mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
fix(docs): resolve legacy sdk reference urls (#51064)
I made the crawler renderer resolve legacy JavaScript and Dart reference slugs to their current sections, and updated authored guide and SDK spec links to use them. Exact slugs still win, ambiguous bare slugs still return 404, and `file-buckets-listv2` remains a section slug in canonical links. I kept the www redirect work in a separate draft PR because the apps deploy independently. ## To test - [x] On the Docs preview, request `reference/javascript/order` and `reference/dart/get-user` with a bot user agent. Expect the intended heading and canonical URL. - [x] Request `reference/javascript/file-buckets-listv2` with bot and browser user agents. Expect it to open the list v2 section. - [x] Request `reference/swift/get-user` and the Kotlin reference root with a bot user agent. Expect the intended heading. - [x] Open the Storage quickstart guide and follow its upload reference link. Expect the current JavaScript upload section. ## Linear refs GROWTH-1293 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Reference pages now resolve legacy aliases and ambiguous slugs more accurately, with canonical links that preserve explicit SDK versions. * SDK version paths are recognized only when the full path segment matches the version format, improving reference-page routing. * **Documentation** * Updated API reference links across authentication, storage, security, and SDK guides to point to current pages. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
1 parent
2303de33f5
commit
5a7c0d6d84
24 files changed
+206
-35
No files matched your search
@@ -0,0 +1,125 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
const reference = vi.hoisted(() => ({
|
||||
sections: [] as Array<{ id: string; slug: string; title: string; type: string }>,
|
||||
}))
|
||||
|
||||
vi.mock('~/features/docs/Reference.generated.singleton', () => ({
|
||||
getFlattenedSections: async () => reference.sections,
|
||||
getFunctionsList: async () => [],
|
||||
getTypeSpec: async () => undefined,
|
||||
}))
|
||||
|
||||
vi.mock('~/features/docs/Reference.mdx', () => ({
|
||||
getRefMarkdown: async () => 'Reference content',
|
||||
}))
|
||||
|
||||
vi.mock('next/navigation', () => ({
|
||||
notFound: () => {
|
||||
throw new Error('notFound')
|
||||
},
|
||||
}))
|
||||
|
||||
import { GET } from './route'
|
||||
|
||||
function section(slug: string, title: string, type = 'markdown') {
|
||||
return { id: slug, slug, title, type }
|
||||
}
|
||||
|
||||
async function html(path: string) {
|
||||
const response = await GET(new Request(`https://supabase.com${path}`))
|
||||
expect(response.status).toBe(200)
|
||||
return response.text()
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
reference.sections = []
|
||||
})
|
||||
|
||||
describe('crawler reference aliases', () => {
|
||||
it('resolves unique bare JavaScript modifier and filter slugs', async () => {
|
||||
reference.sections = [
|
||||
section('using-modifiers-order', 'Order'),
|
||||
section('using-filters-or', 'Or'),
|
||||
section('using-modifiers-maybesingle', 'Maybe single'),
|
||||
]
|
||||
|
||||
for (const [requested, canonical] of [
|
||||
['order', 'using-modifiers-order'],
|
||||
['or', 'using-filters-or'],
|
||||
['maybeSingle', 'using-modifiers-maybesingle'],
|
||||
]) {
|
||||
expect(await html(`/reference/javascript/${requested}`)).toContain(
|
||||
`href="https://supabase.com/docs/reference/javascript/${canonical}"`
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it('resolves storage slugs and keeps an exact versioned slug', async () => {
|
||||
reference.sections = [
|
||||
section('file-buckets-createbucket', 'Create bucket'),
|
||||
section('file-buckets-upload', 'Upload'),
|
||||
section('file-buckets-createsignedurl', 'Create signed URL'),
|
||||
section('file-buckets-updatebucket', 'Update bucket'),
|
||||
section('file-buckets-listv2', 'List files v2'),
|
||||
]
|
||||
|
||||
for (const [requested, canonical] of [
|
||||
['storage-createbucket', 'file-buckets-createbucket'],
|
||||
['storage-from-upload', 'file-buckets-upload'],
|
||||
['storage-from-createsignedurl', 'file-buckets-createsignedurl'],
|
||||
['storage-updatebucket', 'file-buckets-updatebucket'],
|
||||
['file-buckets-listv2', 'file-buckets-listv2'],
|
||||
]) {
|
||||
expect(await html(`/reference/javascript/${requested}`)).toContain(
|
||||
`href="https://supabase.com/docs/reference/javascript/${canonical}"`
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it('resolves SDK-specific user and root aliases', async () => {
|
||||
reference.sections = [
|
||||
section('introduction', 'Introduction'),
|
||||
section('auth-admin', 'Admin'),
|
||||
section('auth-getuser', 'Get user'),
|
||||
section('auth-currentuser', 'Current user'),
|
||||
]
|
||||
|
||||
expect(await html('/reference/javascript')).toContain(
|
||||
'href="https://supabase.com/docs/reference/javascript/introduction"'
|
||||
)
|
||||
expect(await html('/reference/javascript/start')).toContain('JavaScript: Introduction')
|
||||
expect(await html('/reference/javascript/admin-api')).toContain('JavaScript: Admin')
|
||||
expect(await html('/reference/swift/get-user')).toContain(
|
||||
'href="https://supabase.com/docs/reference/swift/auth-getuser"'
|
||||
)
|
||||
expect(await html('/reference/dart/get-user')).toContain(
|
||||
'href="https://supabase.com/docs/reference/dart/auth-currentuser"'
|
||||
)
|
||||
expect(await html('/reference/kotlin')).toContain('Kotlin: Introduction')
|
||||
})
|
||||
|
||||
it('keeps exact matches ahead of aliases and rejects ambiguous bare slugs', async () => {
|
||||
reference.sections = [
|
||||
section('delete', 'Delete'),
|
||||
section('auth-passkey-list', 'Passkeys'),
|
||||
section('file-buckets-list', 'Files'),
|
||||
]
|
||||
|
||||
expect(await html('/reference/javascript/delete')).toContain('JavaScript: Delete')
|
||||
expect(await html('/reference/javascript/storage-list')).toContain('JavaScript: Files')
|
||||
await expect(html('/reference/javascript/list')).rejects.toThrow('notFound')
|
||||
})
|
||||
|
||||
it('uses canonical paths for explicit versions', async () => {
|
||||
reference.sections = [section('auth-update', 'Update')]
|
||||
|
||||
expect(await html('/reference/javascript/v1/auth-update')).toContain(
|
||||
'href="https://supabase.com/docs/reference/javascript/v1/auth-update"'
|
||||
)
|
||||
reference.sections = [section('auth-updateuser', 'Update')]
|
||||
expect(await html('/reference/javascript/v2/auth-updateuser')).toContain(
|
||||
'href="https://supabase.com/docs/reference/javascript/auth-updateuser"'
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -43,10 +43,23 @@ export async function GET(request: Request) {
|
||||
url,
|
||||
}
|
||||
})
|
||||
section = flattenedSections.find(
|
||||
(section) =>
|
||||
(section.type === 'markdown' || section.type === 'function') && section.slug === slug
|
||||
const contentSections = flattenedSections.filter(
|
||||
(section) => section.type === 'markdown' || section.type === 'function'
|
||||
)
|
||||
section = contentSections.find((section) => section.slug === slug)
|
||||
if (!section) {
|
||||
const legacySlug = slug?.toLowerCase()
|
||||
const replacement = legacyReferenceSlug(lib, version, legacySlug)
|
||||
|
||||
if (replacement) {
|
||||
section = contentSections.find((section) => section.slug?.toLowerCase() === replacement)
|
||||
} else if (legacySlug && version === 'v2' && (lib === 'javascript' || lib === 'dart')) {
|
||||
const matches = contentSections.filter((section) =>
|
||||
section.slug?.toLowerCase().endsWith(`-${legacySlug}`)
|
||||
)
|
||||
if (matches.length === 1) section = matches[0]
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
|
||||
if (!section) {
|
||||
@@ -56,7 +69,7 @@ export async function GET(request: Request) {
|
||||
const html = htmlShell(
|
||||
lib,
|
||||
isVersion ? version : null,
|
||||
slug,
|
||||
section.slug ?? slug,
|
||||
section,
|
||||
libraryNav(sectionsWithUrl) + (await sectionDetails(lib, isVersion ? version : null, section))
|
||||
)
|
||||
@@ -66,6 +79,17 @@ export async function GET(request: Request) {
|
||||
return response
|
||||
}
|
||||
|
||||
function legacyReferenceSlug(lib: string, version: string, slug?: string) {
|
||||
if (!slug || slug === 'start') return 'introduction'
|
||||
if (lib === 'swift' && version === 'v2' && slug === 'get-user') return 'auth-getuser'
|
||||
if (version !== 'v2' || (lib !== 'javascript' && lib !== 'dart')) return undefined
|
||||
if (slug === 'admin-api') return 'auth-admin'
|
||||
if (slug === 'get-user') return lib === 'dart' ? 'auth-currentuser' : 'auth-getuser'
|
||||
if (slug.startsWith('storage-from-')) return `file-buckets-${slug.slice('storage-from-'.length)}`
|
||||
if (slug.startsWith('storage-')) return `file-buckets-${slug.slice('storage-'.length)}`
|
||||
return undefined
|
||||
}
|
||||
|
||||
function htmlShell(
|
||||
lib: string,
|
||||
version: string | null,
|
||||
@@ -74,6 +98,7 @@ function htmlShell(
|
||||
body: string
|
||||
) {
|
||||
const libraryName = REFERENCES[lib].name
|
||||
const versionPath = version && version !== REFERENCES[lib].versions[0] ? '/' + version : ''
|
||||
let title = libraryName + ': ' + (section.title ?? '')
|
||||
|
||||
return (
|
||||
@@ -84,6 +109,7 @@ function htmlShell(
|
||||
`<meta name="og:image" content="https://supabase.com/docs/img/supabase-og-image.png">` +
|
||||
`<meta name="twitter:image" content="https://supabase.com/docs/img/supabase-og-image.png">` +
|
||||
`<link rel="canonical" href="https://supabase.com/docs/reference/${lib}` +
|
||||
versionPath +
|
||||
(slug ? '/' + slug : '') +
|
||||
`">` +
|
||||
'</head>' +
|
||||
|
||||
@@ -38,7 +38,7 @@ In the **sign-in flow**, the user signs in (upgrading the session to AAL1) and t
|
||||
|
||||
<Admonition type="note">
|
||||
|
||||
[TOTP MFA API](/docs/reference/javascript/auth-mfa-api) is free to use and is enabled on all Supabase projects by default.
|
||||
[TOTP MFA API](/docs/reference/javascript/auth-mfa) is free to use and is enabled on all Supabase projects by default.
|
||||
|
||||
</Admonition>
|
||||
|
||||
|
||||
@@ -637,7 +637,7 @@ Response:
|
||||
|
||||
<Admonition type="note">
|
||||
|
||||
For complete API documentation, see the [OAuth Admin API reference](/docs/reference/javascript/auth-admin-oauth-admin).
|
||||
For complete API documentation, see the [OAuth Admin API reference](/docs/reference/javascript/oauth-admin).
|
||||
|
||||
</Admonition>
|
||||
|
||||
|
||||
@@ -849,7 +849,7 @@ It's a good practice to provide a settings page where users can view all authori
|
||||
|
||||
</Admonition>
|
||||
|
||||
For complete API reference, see the [OAuth methods in supabase-js](/docs/reference/javascript/auth-admin-oauth-server).
|
||||
For complete API reference, see the [OAuth methods in supabase-js](/docs/reference/javascript/oauth-server).
|
||||
|
||||
## Next steps
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ Leaked password protection is available on the Pro Plan and above.
|
||||
|
||||
Users will need to be recently logged in to change their password without requiring reauthentication. (A user is considered recently logged in if the session was created within the last 24 hours.) If disabled, a user can change their password at any time.
|
||||
|
||||
When enabled, a `nonce` will be sent to the user and this nonce must be validated before the a password change can occur. This can be triggered with the [reauthenticate()](/docs/reference/javascript/auth-reauthentication) API call.
|
||||
When enabled, a `nonce` will be sent to the user and this nonce must be validated before the a password change can occur. This can be triggered with the [reauthenticate()](/docs/reference/javascript/auth-reauthenticate) API call.
|
||||
|
||||
```
|
||||
const { error } = await supabase.auth.reauthenticate()
|
||||
|
||||
@@ -14,7 +14,7 @@ When a JWT is issued by Supabase Auth, the key used to create its [signature](ht
|
||||
|
||||
| System | Type | Description |
|
||||
| ----------------- | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Legacy | JWT secret | Initially Supabase was designed to use a single shared secret key to sign all JWTs. This includes <span className="whitespace-nowrap!">the `anon` and `service_role`</span> keys, all user access tokens including some [Storage pre-signed URLs](/docs/reference/javascript/storage-from-createsignedurl). **No longer recommended.** Available for backward compatibility. |
|
||||
| Legacy | JWT secret | Initially Supabase was designed to use a single shared secret key to sign all JWTs. This includes <span className="whitespace-nowrap!">the `anon` and `service_role`</span> keys, all user access tokens including some [Storage pre-signed URLs](/docs/reference/javascript/file-buckets-createsignedurl). **No longer recommended.** Available for backward compatibility. |
|
||||
| Signing keys | Asymmetric key (RSA, Elliptic Curves) | A JWT signing key based on [public-key cryptography](https://en.wikipedia.org/wiki/Public-key_cryptography) (RSA, Elliptic Curves) that follows industry best practices and significantly improves the security, reliability and performance of your applications. |
|
||||
| Signing keys | Shared secret key | A JWT signing key based on a [shared secret](https://en.wikipedia.org/wiki/HMAC). |
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ Various products at Supabase have their own hardening and configuration guides,
|
||||
|
||||
- [Object ownership](/docs/guides/storage/security/ownership)
|
||||
- [Access control](/docs/guides/storage/security/access-control)
|
||||
- The Storage API docs contain hints about required [RLS policy permissions](/docs/reference/javascript/storage-createbucket)
|
||||
- The Storage API docs contain hints about required [RLS policy permissions](/docs/reference/javascript/file-buckets-createbucket)
|
||||
- [Custom roles with the storage schema](/docs/guides/storage/schema/custom-roles)
|
||||
|
||||
## Realtime
|
||||
|
||||
@@ -69,7 +69,7 @@ Use the Auth admin API to create providers. You need your project's secret key f
|
||||
|
||||
<Admonition type="danger">
|
||||
|
||||
The JavaScript examples use a [supabase-js](/docs/reference/javascript/start) client created with the secret key (`SUPABASE_SECRET_KEY`), which must only run in trusted server-side environments.
|
||||
The JavaScript examples use a [supabase-js](/docs/reference/javascript/introduction) client created with the secret key (`SUPABASE_SECRET_KEY`), which must only run in trusted server-side environments.
|
||||
|
||||
</Admonition>
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ const { data, error } = await supabase.storage.createBucket('avatars', {
|
||||
})
|
||||
```
|
||||
|
||||
[Reference.](/docs/reference/javascript/storage-createbucket)
|
||||
[Reference.](/docs/reference/javascript/file-buckets-createbucket)
|
||||
|
||||
</TabPanel>
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ When a bucket is set to **Private** all operations are subject to access control
|
||||
|
||||
The only ways to download assets within a private bucket is to:
|
||||
|
||||
- Use the [download method](/docs/reference/javascript/storage-from-download) by providing an authorization header containing your user's JWT. The RLS policy you create on the `storage.objects` table will use this user to determine if they have access.
|
||||
- Create a signed URL with the [`createSignedUrl` method](/docs/reference/javascript/storage-from-createsignedurl) that can be accessed for a limited time.
|
||||
- Use the [download method](/docs/reference/javascript/file-buckets-download) by providing an authorization header containing your user's JWT. The RLS policy you create on the `storage.objects` table will use this user to determine if they have access.
|
||||
- Create a signed URL with the [`createSignedUrl` method](/docs/reference/javascript/file-buckets-createsignedurl) that can be accessed for a limited time.
|
||||
|
||||
#### Example use cases:
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ Smart CDN caching is automatically enabled for [Pro Plan and above](/pricing).
|
||||
|
||||
## Cache duration
|
||||
|
||||
When Smart CDN is enabled, the asset is cached on the CDN for as long as possible. You can still control how long assets are stored in the browser using the [`cacheControl`](/docs/reference/javascript/storage-from-upload) option when uploading a file. Smart CDN caching works with all types of storage operations including signed URLs.
|
||||
When Smart CDN is enabled, the asset is cached on the CDN for as long as possible. You can still control how long assets are stored in the browser using the [`cacheControl`](/docs/reference/javascript/file-buckets-upload) option when uploading a file. Smart CDN caching works with all types of storage operations including signed URLs.
|
||||
|
||||
When a file is updated or deleted, the CDN cache is automatically invalidated to reflect the change (including transformed images). It can take **up to 60 seconds** for the CDN cache to be invalidated as the asset metadata has to propagate across all the data-centers around the globe.
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ values
|
||||
const { data, error } = await supabase.storage.createBucket('avatars')
|
||||
```
|
||||
|
||||
[Reference.](/docs/reference/javascript/storage-createbucket)
|
||||
[Reference.](/docs/reference/javascript/file-buckets-createbucket)
|
||||
|
||||
</TabPanel>
|
||||
<$Show if="sdk:dart">
|
||||
@@ -152,7 +152,7 @@ const { data, error } = await supabase.storage
|
||||
.upload('public/avatar1.png', avatarFile)
|
||||
```
|
||||
|
||||
[Reference.](/docs/reference/javascript/storage-from-upload)
|
||||
[Reference.](/docs/reference/javascript/file-buckets-upload)
|
||||
|
||||
</TabPanel>
|
||||
<$Show if="sdk:dart">
|
||||
@@ -220,7 +220,7 @@ You can download a file from the Dashboard, or within a browser using our JS lib
|
||||
const { data, error } = await supabase.storage.from('avatars').download('public/avatar1.png')
|
||||
```
|
||||
|
||||
[Reference.](/docs/reference/javascript/storage-from-download)
|
||||
[Reference.](/docs/reference/javascript/file-buckets-download)
|
||||
|
||||
</TabPanel>
|
||||
<$Show if="sdk:dart">
|
||||
@@ -237,7 +237,7 @@ void main() async {
|
||||
}
|
||||
```
|
||||
|
||||
[Reference.](/docs/reference/dart/storage-from-download)
|
||||
[Reference.](/docs/reference/dart/file-buckets-download)
|
||||
|
||||
</TabPanel>
|
||||
</$Show>
|
||||
|
||||
@@ -20,11 +20,11 @@ If you need different `SELECT` policies for different Storage actions, such as l
|
||||
|
||||
<Admonition type="note">
|
||||
|
||||
The RLS policies required for different operations are documented [here](/docs/reference/javascript/storage-createbucket)
|
||||
The RLS policies required for different operations are documented [here](/docs/reference/javascript/file-buckets-createbucket)
|
||||
|
||||
</Admonition>
|
||||
|
||||
For example, the only RLS policy required for [uploading](/docs/reference/javascript/storage-from-upload) objects is to grant the `INSERT` permission to the `storage.objects` table.
|
||||
For example, the only RLS policy required for [uploading](/docs/reference/javascript/file-buckets-upload) objects is to grant the `INSERT` permission to the `storage.objects` table.
|
||||
|
||||
To allow overwriting files using the `upsert` functionality you will need to additionally grant `SELECT` and `UPDATE` permissions.
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ final response = await supabase.storage
|
||||
);
|
||||
```
|
||||
|
||||
[Reference.](/docs/reference/dart/storage-from-download)
|
||||
[Reference.](/docs/reference/dart/file-buckets-download)
|
||||
|
||||
</TabPanel>
|
||||
</$Show>
|
||||
|
||||
@@ -69,7 +69,7 @@ const supabase = createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, {
|
||||
</RefSubLayout.Examples>
|
||||
</RefSubLayout.EducationRow>
|
||||
|
||||
Read more about the [constructor options](/docs/reference/javascript/release-notes#explicit-constructor-options).
|
||||
Read more about the [constructor options](/docs/reference/javascript/initializing).
|
||||
|
||||
### Auth methods
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ export function parseReferencePath(slug: Array<string>) {
|
||||
let maybeCrawlers: string | null
|
||||
let path: string[]
|
||||
;[sdkId, maybeVersion, maybeCrawlers, ...path] = slug
|
||||
if (!/v\d+/.test(maybeVersion)) {
|
||||
if (!/^v\d+$/.test(maybeVersion)) {
|
||||
maybeVersion = null
|
||||
path = [maybeCrawlers, ...path]
|
||||
maybeCrawlers = maybeVersion
|
||||
|
||||
@@ -163,3 +163,23 @@ describe('docs middleware — /guides/* content negotiation', () => {
|
||||
expect(rewrite).not.toContain('/api/guides-md/')
|
||||
})
|
||||
})
|
||||
|
||||
describe('docs middleware — reference paths', () => {
|
||||
it('does not mistake listv2 for a version segment', () => {
|
||||
const path = '/docs/reference/javascript/file-buckets-listv2'
|
||||
expect(
|
||||
middleware(makeRequest(path, { userAgent: 'Googlebot' })).headers.get(REWRITE_HEADER)
|
||||
).toBe('https://supabase.com/docs/api/crawlers')
|
||||
expect(middleware(makeRequest(path)).headers.get(REWRITE_HEADER)).toBe(
|
||||
'https://supabase.com/docs/reference/javascript'
|
||||
)
|
||||
})
|
||||
|
||||
it('sends the Kotlin root to the crawler renderer for bots', () => {
|
||||
expect(
|
||||
middleware(makeRequest('/docs/reference/kotlin', { userAgent: 'Googlebot' })).headers.get(
|
||||
REWRITE_HEADER
|
||||
)
|
||||
).toBe('https://supabase.com/docs/api/crawlers')
|
||||
})
|
||||
})
|
||||
@@ -43,7 +43,7 @@ export function middleware(request: NextRequest) {
|
||||
let [, lib, maybeVersion, ...slug] = pathname.replace(REFERENCE_PATH, '').split('/')
|
||||
|
||||
if (clientSdkIds.includes(lib)) {
|
||||
const version = /v\d+/.test(maybeVersion) ? maybeVersion : undefined
|
||||
const version = /^v\d+$/.test(maybeVersion) ? maybeVersion : undefined
|
||||
if (!version) {
|
||||
slug = [maybeVersion, ...slug]
|
||||
}
|
||||
@@ -77,7 +77,7 @@ export function middleware(request: NextRequest) {
|
||||
}
|
||||
|
||||
if (clientSdkIds.includes(lib)) {
|
||||
const version = /v\d+/.test(maybeVersion) ? maybeVersion : null
|
||||
const version = /^v\d+$/.test(maybeVersion) ? maybeVersion : null
|
||||
const rewritePath = [REFERENCE_PATH, lib, version].filter(Boolean).join('/')
|
||||
return NextResponse.rewrite(new URL(rewritePath, request.url))
|
||||
}
|
||||
|
||||
@@ -1553,7 +1553,7 @@ functions:
|
||||
Retrieve URLs for assets in public buckets
|
||||
title: 'from.getPublicUrl()'
|
||||
notes: |
|
||||
- The bucket needs to be set to public, either via [updateBucket()](/docs/reference/dart/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public"
|
||||
- The bucket needs to be set to public, either via [updateBucket()](/docs/reference/dart/v1/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public"
|
||||
- Policy permissions required:
|
||||
- `buckets` permissions: none
|
||||
- `objects` permissions: none
|
||||
|
||||
@@ -948,7 +948,7 @@ functions:
|
||||
- Drives the full WebAuthn ceremony end to end: starts the challenge with the Supabase server, calls the `authenticator` you supply to prompt the user for biometrics or a security key, and verifies the credential with the server.
|
||||
- Does not require an existing session. On success the session is persisted and an `AuthChangeEvent.signedIn` event is fired.
|
||||
- `supabase_flutter` does not depend on a passkey plugin directly. Pass an implementation of `PasskeyAuthenticatorInterface`, such as the [`passkeys`](https://pub.dev/packages/passkeys) plugin's `PasskeyAuthenticator` (since `passkeys` `2.21.0`).
|
||||
- For native flows or custom UI, use the lower-level [`auth.passkey`](/docs/reference/dart/auth-passkey-api) namespace instead.
|
||||
- For native flows or custom UI, use the lower-level [`auth.passkey`](/docs/reference/dart/auth-passkey) namespace instead.
|
||||
- Passkeys are a BETA feature and must be enabled for your project in the Supabase Dashboard under Authentication > Configuration > Passkeys.
|
||||
- Platform setup the library cannot perform (Associated Domains on iOS/macOS, Digital Asset Links on Android, the `passkeys` web SDK on web) is documented in the `supabase_flutter` package README.
|
||||
params:
|
||||
@@ -982,7 +982,7 @@ functions:
|
||||
- Drives the full WebAuthn ceremony end to end: starts the registration with the Supabase server, calls the `authenticator` you supply to create a credential on the device, and verifies it with the server.
|
||||
- Requires a signed in (non-anonymous) user. If the user has verified MFA factors, the session has to be at `aal2` to manage passkeys.
|
||||
- `supabase_flutter` does not depend on a passkey plugin directly. Pass an implementation of `PasskeyAuthenticatorInterface`, such as the [`passkeys`](https://pub.dev/packages/passkeys) plugin's `PasskeyAuthenticator` (since `passkeys` `2.21.0`).
|
||||
- For native flows or custom UI, use the lower-level [`auth.passkey`](/docs/reference/dart/auth-passkey-api) namespace instead.
|
||||
- For native flows or custom UI, use the lower-level [`auth.passkey`](/docs/reference/dart/auth-passkey) namespace instead.
|
||||
- Passkeys are a BETA feature and must be enabled for your project in the Supabase Dashboard under Authentication > Configuration > Passkeys.
|
||||
params:
|
||||
- name: authenticator
|
||||
@@ -2379,7 +2379,7 @@ functions:
|
||||
- id: passkey-verify-registration
|
||||
title: 'passkey.verifyRegistration()'
|
||||
notes: |
|
||||
Completes the registration of a new passkey and returns the stored [`Passkey`](/docs/reference/dart/auth-passkey-api).
|
||||
Completes the registration of a new passkey and returns the stored [`Passkey`](/docs/reference/dart/auth-passkey).
|
||||
params:
|
||||
- name: challengeId
|
||||
isOptional: false
|
||||
@@ -5329,7 +5329,7 @@ functions:
|
||||
Retrieve URLs for assets in public buckets
|
||||
title: 'from.getPublicUrl()'
|
||||
notes: |
|
||||
- The bucket needs to be set to public, either via [updateBucket()](/docs/reference/dart/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public"
|
||||
- The bucket needs to be set to public, either via [updateBucket()](/docs/reference/dart/file-buckets-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public"
|
||||
- Policy permissions required:
|
||||
- `buckets` permissions: none
|
||||
- `objects` permissions: none
|
||||
@@ -5537,7 +5537,7 @@ functions:
|
||||
title: 'from.downloadStream()'
|
||||
notes: |
|
||||
- The request is sent when the stream is listened to. A non-success response surfaces as a `StorageException` on the stream before any bytes are emitted.
|
||||
- Prefer this over [`download()`](/docs/reference/dart/storage-from-download) for large files to keep memory usage low.
|
||||
- Prefer this over [`download()`](/docs/reference/dart/file-buckets-download) for large files to keep memory usage low.
|
||||
- Policy permissions required:
|
||||
- `buckets` permissions: none
|
||||
- `objects` permissions: `select`
|
||||
|
||||
@@ -1532,7 +1532,7 @@ functions:
|
||||
title: 'from.getPublicUrl()'
|
||||
$ref: '@supabase/storage-js."lib/StorageFileApi".StorageFileApi.getPublicUrl'
|
||||
notes: |
|
||||
- The bucket needs to be set to public, either via [updateBucket()](/docs/reference/javascript/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public"
|
||||
- The bucket needs to be set to public, either via [updateBucket()](/docs/reference/javascript/v1/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public"
|
||||
- Policy permissions required:
|
||||
- `buckets` permissions: none
|
||||
- `objects` permissions: none
|
||||
|
||||
@@ -3333,7 +3333,7 @@ functions:
|
||||
- id: from-get-public-url
|
||||
title: from.getPublicUrl()
|
||||
notes: |
|
||||
- The bucket needs to be set to public, either via [updateBucket()](/docs/reference/javascript/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public"
|
||||
- The bucket needs to be set to public, either via [updateBucket()](/docs/reference/swift/v1/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public"
|
||||
- RLS policy permissions required:
|
||||
- `buckets` table permissions: none
|
||||
- `objects` table permissions: none
|
||||
|
||||
@@ -5691,7 +5691,7 @@ functions:
|
||||
- id: from-get-public-url
|
||||
title: from.getPublicUrl()
|
||||
notes: |
|
||||
- The bucket needs to be set to public, either via [updateBucket()](/docs/reference/javascript/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public"
|
||||
- The bucket needs to be set to public, either via [updateBucket()](/docs/reference/swift/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public"
|
||||
- RLS policy permissions required:
|
||||
- `buckets` table permissions: none
|
||||
- `objects` table permissions: none
|
||||
|
||||
Reference in new issue
Block a user