Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions packages/core/auth-js/src/GoTrueAdminApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ export default class GoTrueAdminApi {
}
protected fetch: Fetch

/**
* Creates an admin API client that can be used to manage users and OAuth clients.
*
* @example
* ```ts
* import { GoTrueAdminApi } from '@supabase/auth-js'
*
* const admin = new GoTrueAdminApi({
* url: 'https://xyzcompany.supabase.co/auth/v1',
* headers: { Authorization: `Bearer ${process.env.SUPABASE_SERVICE_ROLE_KEY}` },
* })
* ```
*/
constructor({
url = '',
headers = {},
Expand Down
11 changes: 11 additions & 0 deletions packages/core/auth-js/src/GoTrueClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,17 @@ export default class GoTrueClient {

/**
* Create a new client for use in the browser.
*
* @example
* ```ts
* import { GoTrueClient } from '@supabase/auth-js'
*
* const auth = new GoTrueClient({
* url: 'https://xyzcompany.supabase.co/auth/v1',
* headers: { apikey: 'public-anon-key' },
* storageKey: 'supabase-auth',
* })
* ```
*/
constructor(options: GoTrueClientOptions) {
const settings = { ...DEFAULT_OPTIONS, ...options }
Expand Down
127 changes: 127 additions & 0 deletions packages/core/auth-js/src/lib/errors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import { WeakPasswordReasons } from './types'
import { ErrorCode } from './error-codes'

/**
* Base error thrown by Supabase Auth helpers.
*
* @example
* ```ts
* import { AuthError } from '@supabase/auth-js'
*
* throw new AuthError('Unexpected auth error', 500, 'unexpected')
* ```
*/
export class AuthError extends Error {
/**
* Error code associated with the error. Most errors coming from
Expand All @@ -27,6 +37,16 @@ export function isAuthError(error: unknown): error is AuthError {
return typeof error === 'object' && error !== null && '__isAuthError' in error
}

/**
* Error returned directly from the GoTrue REST API.
*
* @example
* ```ts
* import { AuthApiError } from '@supabase/auth-js'
*
* throw new AuthApiError('Invalid credentials', 400, 'invalid_credentials')
* ```
*/
export class AuthApiError extends AuthError {
status: number

Expand All @@ -42,6 +62,20 @@ export function isAuthApiError(error: unknown): error is AuthApiError {
return isAuthError(error) && error.name === 'AuthApiError'
}

/**
* Wraps non-standard errors so callers can inspect the root cause.
*
* @example
* ```ts
* import { AuthUnknownError } from '@supabase/auth-js'
*
* try {
* await someAuthCall()
* } catch (err) {
* throw new AuthUnknownError('Auth failed', err)
* }
* ```
*/
export class AuthUnknownError extends AuthError {
originalError: unknown

Expand All @@ -52,6 +86,16 @@ export class AuthUnknownError extends AuthError {
}
}

/**
* Flexible error class used to create named auth errors at runtime.
*
* @example
* ```ts
* import { CustomAuthError } from '@supabase/auth-js'
*
* throw new CustomAuthError('My custom auth error', 'MyAuthError', 400, 'custom_code')
* ```
*/
export class CustomAuthError extends AuthError {
name: string
status: number
Expand All @@ -63,6 +107,16 @@ export class CustomAuthError extends AuthError {
}
}

/**
* Error thrown when an operation requires a session but none is present.
*
* @example
* ```ts
* import { AuthSessionMissingError } from '@supabase/auth-js'
*
* throw new AuthSessionMissingError()
* ```
*/
export class AuthSessionMissingError extends CustomAuthError {
constructor() {
super('Auth session missing!', 'AuthSessionMissingError', 400, undefined)
Expand All @@ -73,18 +127,51 @@ export function isAuthSessionMissingError(error: any): error is AuthSessionMissi
return isAuthError(error) && error.name === 'AuthSessionMissingError'
}

/**
* Error thrown when the token response is malformed.
*
* @example
* ```ts
* import { AuthInvalidTokenResponseError } from '@supabase/auth-js'
*
* throw new AuthInvalidTokenResponseError()
* ```
*/
export class AuthInvalidTokenResponseError extends CustomAuthError {
constructor() {
super('Auth session or user missing', 'AuthInvalidTokenResponseError', 500, undefined)
}
}

/**
* Error thrown when email/password credentials are invalid.
*
* @example
* ```ts
* import { AuthInvalidCredentialsError } from '@supabase/auth-js'
*
* throw new AuthInvalidCredentialsError('Email or password is incorrect')
* ```
*/
export class AuthInvalidCredentialsError extends CustomAuthError {
constructor(message: string) {
super(message, 'AuthInvalidCredentialsError', 400, undefined)
}
}

/**
* Error thrown when implicit grant redirects contain an error.
*
* @example
* ```ts
* import { AuthImplicitGrantRedirectError } from '@supabase/auth-js'
*
* throw new AuthImplicitGrantRedirectError('OAuth redirect failed', {
* error: 'access_denied',
* code: 'oauth_error',
* })
* ```
*/
export class AuthImplicitGrantRedirectError extends CustomAuthError {
details: { error: string; code: string } | null = null
constructor(message: string, details: { error: string; code: string } | null = null) {
Expand All @@ -108,6 +195,16 @@ export function isAuthImplicitGrantRedirectError(
return isAuthError(error) && error.name === 'AuthImplicitGrantRedirectError'
}

/**
* Error thrown during PKCE code exchanges.
*
* @example
* ```ts
* import { AuthPKCEGrantCodeExchangeError } from '@supabase/auth-js'
*
* throw new AuthPKCEGrantCodeExchangeError('PKCE exchange failed')
* ```
*/
export class AuthPKCEGrantCodeExchangeError extends CustomAuthError {
details: { error: string; code: string } | null = null

Expand All @@ -126,6 +223,16 @@ export class AuthPKCEGrantCodeExchangeError extends CustomAuthError {
}
}

/**
* Error thrown when a transient fetch issue occurs.
*
* @example
* ```ts
* import { AuthRetryableFetchError } from '@supabase/auth-js'
*
* throw new AuthRetryableFetchError('Service temporarily unavailable', 503)
* ```
*/
export class AuthRetryableFetchError extends CustomAuthError {
constructor(message: string, status: number) {
super(message, 'AuthRetryableFetchError', status, undefined)
Expand All @@ -141,6 +248,16 @@ export function isAuthRetryableFetchError(error: unknown): error is AuthRetryabl
* weak. Inspect the reasons to identify what password strength rules are
* inadequate.
*/
/**
* Error thrown when a supplied password is considered weak.
*
* @example
* ```ts
* import { AuthWeakPasswordError } from '@supabase/auth-js'
*
* throw new AuthWeakPasswordError('Password too short', 400, ['min_length'])
* ```
*/
export class AuthWeakPasswordError extends CustomAuthError {
/**
* Reasons why the password is deemed weak.
Expand All @@ -158,6 +275,16 @@ export function isAuthWeakPasswordError(error: unknown): error is AuthWeakPasswo
return isAuthError(error) && error.name === 'AuthWeakPasswordError'
}

/**
* Error thrown when a JWT cannot be verified or parsed.
*
* @example
* ```ts
* import { AuthInvalidJwtError } from '@supabase/auth-js'
*
* throw new AuthInvalidJwtError('Token signature is invalid')
* ```
*/
export class AuthInvalidJwtError extends CustomAuthError {
constructor(message: string) {
super(message, 'AuthInvalidJwtError', 400, 'invalid_jwt')
Expand Down
43 changes: 43 additions & 0 deletions packages/core/auth-js/src/lib/locks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ export const internals = {
* An error thrown when a lock cannot be acquired after some amount of time.
*
* Use the {@link #isAcquireTimeout} property instead of checking with `instanceof`.
*
* @example
* ```ts
* import { LockAcquireTimeoutError } from '@supabase/auth-js'
*
* class CustomLockError extends LockAcquireTimeoutError {
* constructor() {
* super('Lock timed out')
* }
* }
* ```
*/
export abstract class LockAcquireTimeoutError extends Error {
public readonly isAcquireTimeout = true
Expand All @@ -28,7 +39,27 @@ export abstract class LockAcquireTimeoutError extends Error {
}
}

/**
* Error thrown when the browser Navigator Lock API fails to acquire a lock.
*
* @example
* ```ts
* import { NavigatorLockAcquireTimeoutError } from '@supabase/auth-js'
*
* throw new NavigatorLockAcquireTimeoutError('Lock timed out')
* ```
*/
export class NavigatorLockAcquireTimeoutError extends LockAcquireTimeoutError {}
/**
* Error thrown when the process-level lock helper cannot acquire a lock.
*
* @example
* ```ts
* import { ProcessLockAcquireTimeoutError } from '@supabase/auth-js'
*
* throw new ProcessLockAcquireTimeoutError('Lock timed out')
* ```
*/
export class ProcessLockAcquireTimeoutError extends LockAcquireTimeoutError {}

/**
Expand All @@ -55,6 +86,12 @@ export class ProcessLockAcquireTimeoutError extends LockAcquireTimeoutError {}
* will time out after so many milliseconds. An error is
* a timeout if it has `isAcquireTimeout` set to true.
* @param fn The operation to run once the lock is acquired.
* @example
* ```ts
* await navigatorLock('sync-user', 1000, async () => {
* await refreshSession()
* })
* ```
*/
export async function navigatorLock<R>(
name: string,
Expand Down Expand Up @@ -167,6 +204,12 @@ const PROCESS_LOCKS: { [name: string]: Promise<any> } = {}
* will time out after so many milliseconds. An error is
* a timeout if it has `isAcquireTimeout` set to true.
* @param fn The operation to run once the lock is acquired.
* @example
* ```ts
* await processLock('migrate', 5000, async () => {
* await runMigration()
* })
* ```
*/
export async function processLock<R>(
name: string,
Expand Down
26 changes: 26 additions & 0 deletions packages/core/functions-js/src/FunctionsClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,28 @@ import {
FunctionsResponse,
} from './types'

/**
* Client for invoking Supabase Edge Functions.
*/
export class FunctionsClient {
protected url: string
protected headers: Record<string, string>
protected region: FunctionRegion
protected fetch: Fetch

/**
* Creates a new Functions client bound to an Edge Functions URL.
*
* @example
* ```ts
* import { FunctionsClient, FunctionRegion } from '@supabase/functions-js'
*
* const functions = new FunctionsClient('https://xyzcompany.supabase.co/functions/v1', {
* headers: { apikey: 'public-anon-key' },
* region: FunctionRegion.UsEast1,
* })
* ```
*/
constructor(
url: string,
{
Expand All @@ -36,6 +52,10 @@ export class FunctionsClient {
/**
* Updates the authorization header
* @param token - the new jwt token sent in the authorisation header
* @example
* ```ts
* functions.setAuth(session.access_token)
* ```
*/
setAuth(token: string) {
this.headers.Authorization = `Bearer ${token}`
Expand All @@ -45,6 +65,12 @@ export class FunctionsClient {
* Invokes a function
* @param functionName - The name of the Function to invoke.
* @param options - Options for invoking the Function.
* @example
* ```ts
* const { data, error } = await functions.invoke('hello-world', {
* body: { name: 'Ada' },
* })
* ```
*/
async invoke<T = any>(
functionName: string,
Expand Down
Loading