@faable/auth-js - v2.1.0
    Preparing search index...

    Class FaableAuthClient

    The main entry point of the SDK: an isomorphic client bound to a Faable Auth tenant that drives every authentication flow.

    Prefer creating it through the createClient factory in app code. Once instantiated it begins loading its session in the background, so you can subscribe to auth-state and trigger sign-ins right away. The most common starting points are the sign-in methods and getSession.

    Hierarchy

    • Base
      • FaableAuthClient
    Index

    Constructors - Getting started

    Properties

    audience?: string
    domainUrl: string
    redirectUri: string
    scope?: string
    sessionCheckExpiryDays: number
    tokenIssuer: string

    Accessors - Sessions

    • get session(): Session | null

      Cached session value last persisted by the client.

      This is a synchronous accessor that returns whatever the client has already loaded into memory. It can lag behind storage (for example, across tabs before the broadcast event arrives) and never triggers a refresh. Prefer FaableAuthClient.getSession when you need an authoritative value, especially on the server.

      Returns Session | null

      The cached Session or null if no user is signed in.

    Accessors - Lifecycle

    • get lastInitializeResult(): InitializeResult | null

      The result of the most recent FaableAuthClient.initialize run, or null while the first one is still in flight.

      The constructor starts initialize() in the background and discards the promise; this accessor lets code that cannot await it (for example a React provider effect) read whether the last OAuth/redirect attempt errored, instead of being stuck with a session that silently stays null.

      Returns InitializeResult | null

    Methods - Sign in

    • Starts an OAuth / social login by redirecting the browser to the tenant's /authorize endpoint for the chosen connection.

      In browsers the SDK redirects the current window unless skipBrowserRedirect is true. On that redirect success path the returned promise never resolves — the pending navigation owns the page, so a loading state you tie to the await stays on until unload instead of flashing back. Pass skipBrowserRedirect: true to get { data: { url } } back and drive the navigation yourself. PKCE is used by default in browsers, falling back to the implicit flow elsewhere. Prefer connection_id when known — the backend resolves it without an extra lookup; connection (by name) is kept for legacy tenants.

      Parameters

      Returns Promise<OAuthResponse>

      // Redirects the current window; the promise does not resolve on success.
      await auth.signInWithOauthConnection({
      connection: 'google',
      redirectTo: 'https://app.example.com/callback'
      })

      // Or take over the navigation yourself:
      const { data } = await auth.signInWithOauthConnection({
      connection: 'google',
      skipBrowserRedirect: true
      })
      window.location.assign(data.url)
    • Completes a passwordless login by exchanging an OTP code for a session.

      Pair this with FaableAuthClient.signInWithPasswordless called with type: 'code'. On success the new session is persisted to storage and a SIGNED_IN event is broadcast.

      Parameters

      • data: { audience?: string; otp: string; username: string }

        The user identifier and the OTP code they received.

      Returns Promise<AuthResponse>

      const { data, error } = await auth.signInWithOtp({
      username: 'user@example.com',
      otp: '123456'
      })
    • Starts a passwordless login flow by emailing the user either an OTP code or a magic link.

      Parameters

      • data: { audience?: string; email: string; type: "code" | "link" }

        The user's email and the delivery mechanism.

      Returns Promise<AuthResult<any>>

      await auth.signInWithPasswordless({
      email: 'user@example.com',
      type: 'code'
      })
    • Signs the user in with a username + password against a database connection on the tenant.

      The server responds with an HTML form that posts the user back to the tenant's /login/callback to complete the OAuth flow; the SDK auto-submits it from the current document. That is why the success path resolves to { data: null, error: null } — the actual session lands on the redirect target, not on this return value. Subscribe with FaableAuthClient.onAuthStateChange to observe the resulting SIGNED_IN event.

      Parameters

      • data: {
            audience?: string;
            password: string;
            redirectTo?: string;
            state?: string;
            username: string;
        }

      Returns Promise<AuthResult<null>>

      await auth.signInWithUsernamePassword({
      username: 'user@example.com',
      password: '••••••••',
      redirectTo: 'https://app.example.com/callback'
      })
    • Registers a new user against the tenant's database connection with an email + password, then signs them in — so an email/password signup form can live entirely in the browser with no backend of your own.

      This calls the public POST /dbconnections/signup endpoint (the Faable analogue of Auth0's /dbconnections/signup) which creates the user and its credential in one step, then chains FaableAuthClient.signInWithUsernamePassword to establish the session.

      Auto-login navigates the browser. Like every interactive username/password login in this SDK, the sign-in step submits a form that round-trips through the auth server, so on success the page redirects to your redirectTo and the live session is delivered there by FaableAuthClient.initialize (and a SIGNED_IN event). This method only returns synchronously when signup itself fails, or in non-navigating runtimes (e.g. tests).

      The user is created with email_verified: false; any verification / welcome email is driven by the tenant's account settings.

      Parameters

      • data: {
            audience?: string;
            connection?: string;
            email: string;
            family_name?: string;
            given_name?: string;
            name?: string;
            password: string;
            redirectTo?: string;
            state?: string;
            user_metadata?: Record<string, unknown>;
        }

        The new user's email, password and optional profile fields.

      Returns Promise<AuthResult<null>>

      const { error } = await auth.signUp({
      email: 'user@example.com',
      password: '••••••••',
      name: 'Ada Lovelace',
      redirectTo: 'https://app.example.com/callback'
      })
      if (error) showError(error.message) // e.g. 'email_taken', 'signup_disabled'
      // otherwise the browser is already navigating to complete the login

    Methods - Authorize URLs

    • Redirects the current window to the tenant's /authorize endpoint.

      Fire-and-forget: there is no return value because the browser navigates away. The session lands back on your redirectUri, where FaableAuthClient.initialize consumes it on the next page load.

      Parameters

      • options: {
            audience?: string;
            redirectTo?: string;
            response_type: string;
            scope?: string;
        }

      Returns void

      auth.authorize({
      response_type: 'code',
      redirectTo: 'https://app.example.com/callback'
      })
    • Builds the tenant's /authorize URL without redirecting the browser.

      Useful when you need to render a login link, open the page in a popup, or hand the URL to a different runtime (e.g. a webview). For the everyday "click → redirect" flow use FaableAuthClient.authorize or FaableAuthClient.signInWithOauthConnection.

      The redirect target is resolved with this precedence: options.redirectToconfig.redirectUriwindow.location.origin.

      Parameters

      • options: {
            audience?: string;
            connection?: string;
            queryParams?: { [key: string]: string };
            redirectTo?: string;
            response_type?: string;
            scope?: string;
        } = {}
        • Optionalaudience?: string
        • Optionalconnection?: string
        • OptionalqueryParams?: { [key: string]: string }

          Extra /authorize params merged in as-is — e.g. { prompt: 'select_account' } or { prompt: 'login' } to force account selection / re-authentication even when an SSO session exists.

        • OptionalredirectTo?: string
        • Optionalresponse_type?: string
        • Optionalscope?: string

      Returns string

      The fully-qualified authorize URL.

      const url = auth.buildAuthorizeUrl({
      connection: 'google',
      redirectTo: 'https://app.example.com/callback'
      })
      window.open(url, 'login', 'popup')
    • Builds the tenant's RP-initiated logout URL ({domain}/logout?client_id=…).

      Navigate the browser to it (top-level, not fetch) to end the session and clear the auth server's SSO cookie — the only reliable way to do that from another origin. FaableAuthClient.signOut does this for you by default; use this helper when you want to drive the navigation yourself.

      Parameters

      • options: { returnTo?: string } = {}
        • OptionalreturnTo?: string

          Where to send the browser after logout, mapped to the OIDC post_logout_redirect_uri. Must be registered as a logout URL on the client or the server responds 400.

      Returns string

      window.location.assign(auth.getLogoutUrl({ returnTo: 'https://app.example.com' }))
      

      Logout

    Methods - Sessions

    • Returns the session, refreshing it if necessary.

      The session returned can be null if no user is signed in or the last one has logged out.

      IMPORTANT: This method loads values directly from the storage attached to the client. If that storage is based on request cookies (for example, on the server) the values in it may not be authentic and therefore it's strongly advised against using this method and its results in such circumstances — a warning will be emitted when the storage exposes isServer: true. Re-fetch the user with a verified call (or verify the access token yourself) before trusting it.

      Returns Promise<
          | { data: { session: Session }; error: null }
          | { data: { session: null }; error: AuthError }
          | { data: { session: null }; error: null },
      >

      const { data, error } = await auth.getSession()
      if (data.session) console.log(data.session.user)
    • Subscribes to auth-state changes for this client.

      The callback fires for INITIAL_SESSION once shortly after subscribing (so consumers don't have to special-case "no event yet"), and then for every SIGNED_IN, SIGNED_OUT, TOKEN_REFRESHED, PASSWORD_RECOVERY, and USER_UPDATED event. Events are broadcast across tabs through BroadcastChannel, so a sign-in or sign-out in one tab reaches every other tab using the same storageKey.

      Parameters

      • callback: (event: AuthChangeEvent, session: Session | null) => void | Promise<void>

        Invoked with the event name and the new session (or null on SIGNED_OUT). Can return a promise — the SDK awaits it.

      Returns { data: { subscription: Subscription } }

      { data: { subscription } } — call subscription.unsubscribe() to stop listening.

      const { data: { subscription } } = auth.onAuthStateChange((event, session) => {
      if (event === 'SIGNED_IN') console.log('Welcome', session?.user.email)
      })
      // later
      subscription.unsubscribe()
    • Forces a new session by exchanging a refresh token regardless of expiry.

      Normally the SDK handles refresh transparently via the auto-refresh ticker; call this only when you need to force an immediate refresh — e.g. right after a server-side action that changed the user's claims. Omit currentSession to reuse whatever FaableAuthClient.getSession returns.

      Parameters

      • OptionalcurrentSession: { refresh_token: string }

        Optional session shape carrying the refresh token to exchange. When passed it must include refresh_token.

      Returns Promise<AuthResponse>

      const { data, error } = await auth.refreshSession()
      
    • Adopts an externally-provided session into the client.

      Decodes the access token to find its expiry; refreshes immediately when already expired, otherwise fetches the user info to round-trip the session. Persists the result and broadcasts SIGNED_IN. An invalid refresh or access token surfaces as error on the returned object.

      Parameters

      • currentSession: { access_token: string; refresh_token: string }

        Minimal session shape — an access token and a refresh token. Other fields are recomputed.

      Returns Promise<AuthResponse>

      // After receiving tokens from a custom server-side handoff
      await auth.setSession({ access_token, refresh_token })
    • Starts an auto-refresh process in the background. The session is checked every few seconds. Close to the time of expiration a process is started to refresh the session. If refreshing fails it will be retried for as long as necessary.

      If autoRefreshToken is enabled in the client config you don't need to call this function, it will be called for you.

      On browsers the refresh process works only when the tab/window is in the foreground to conserve resources as well as prevent race conditions and flooding auth with requests. If you call this method any managed visibility change callback will be removed and you must manage visibility changes on your own.

      On non-browser platforms the refresh process works continuously in the background, which may not be desirable. You should hook into your platform's foreground indication mechanism and call these methods appropriately to conserve resources.

      Returns Promise<void>

      // React Native / Node: drive the refresh loop on focus events yourself
      appState.addEventListener('change', state => {
      if (state === 'active') auth.startAutoRefresh()
      })

    Methods - Account

    • Starts a verified email change for the currently signed-in user.

      The user must be authenticated — the call is made with the session's access token, and the auth server only lets a user change their own email. It creates a verification ticket and emails the user; the change is applied only after they click the link, which the server handles and then redirects to redirect_uri. The current session is unaffected until then.

      Parameters

      • params: {
            new_email: string;
            redirect_uri?: string;
            verification_mode?: "new_only" | "old_and_new";
        }

        The new email plus optional verification policy.

        • verification_mode: 'new_only' verifies just the new address; 'old_and_new' also requires confirming from the old one. When omitted the account's default policy applies.
        • redirect_uri: where the server sends the user after they verify.

      Returns Promise<AuthResult<unknown>>

      const { data, error } = await auth.changeEmail({
      new_email: 'new@example.com',
      redirect_uri: 'https://app.example.com/account'
      })
      // data: { status: 'verification_sent', ticket_id, verification_mode }
    • Triggers a "change your password" email for a database-connection user.

      The current session is unaffected — the user clicks the link in the email and completes the reset on the tenant's hosted pages. The promise resolves once the email has been queued.

      Parameters

      • params: { email: string }

        The user's email address.

      Returns Promise<AuthResult<unknown>>

      await auth.changePassword({ email: 'user@example.com' })
      

    Methods - Sign out

    • Signs the user out and clears the session from storage.

      In a browser context this removes the persisted session and broadcasts a SIGNED_OUT event to every tab listening on the same storageKey. The access token JWT itself remains valid until its exp — keep that expiry short.

      By default (global scope, in a browser) this navigates the page to the auth server's /logout to also clear the SSO cookie, then returns to returnTo if given. Without that navigation the SSO session survives on the auth domain and the next /authorize silently re-logs the previous user — a cross-origin fetch cannot clear that cookie. On this path the returned promise does not resolve (the browser is unloading). Pass { redirect: false } to keep the legacy fetch-only behaviour, or use FaableAuthClient.getLogoutUrl to drive the navigation yourself.

      Scopes:

      • 'global' (default) — invalidate all refresh tokens for the user and, in a browser, redirect to /logout to clear the SSO cookie
      • 'local' — only clear this client's storage (no redirect)
      • 'others' — invalidate every refresh token except this device's; no SIGNED_OUT event is fired locally (no redirect)

      Parameters

      Returns Promise<{ error: AuthError | null }>

      await auth.signOut() // global — clears local + auth SSO cookie via redirect
      await auth.signOut({ returnTo: 'https://app.example.com/bye' }) // + landing
      await auth.signOut({ redirect: false }) // legacy: local + best-effort fetch
      await auth.signOut({ scope: 'local' }) // only this device, no redirect

      Logout

    Methods - Lifecycle

    • Completes an OAuth / magic-link / password-recovery redirect on your callback route and reports the outcome.

      The SDK already consumes the URL during the initialize() it kicks off from the constructor; this is a thin, discoverable wrapper that awaits that same in-flight run (idempotent) so you can:

      • redirect only once the token exchange has finished, and
      • surface error instead of hanging on a "Signing you in…" screen when the exchange fails (e.g. an expired PKCE verifier).

      It also returns returnTo — the app-side destination you optionally passed to signInWith*({ returnTo }) — so you don't need a side channel (like sessionStorage) to remember where to send the user.

      Returns Promise<InitializeResult>

      // app/callback/page.tsx
      const { error, returnTo } = await auth.handleRedirectCallback()
      if (error) showError(error.message)
      else router.replace(returnTo ?? '/')
    • Initializes the client session either from the URL or from storage.

      Automatically called once from the constructor and idempotent — extra calls return the same in-flight promise. Call it explicitly when you need to await an OAuth, magic link, or password-recovery redirect to finish processing so you can surface any returned error.

      Returns Promise<InitializeResult>

      A promise that resolves to { error } — non-null when the URL carried a failure or storage was corrupt; never throws.

      const { error } = await auth.initialize()
      if (error) console.error('Auth redirect failed', error)