Skip to content

AuthClient

AuthClient is the plain-JavaScript engine under the React provider. The provider wraps it; the hook delegates to it; nothing else in the package is interesting if you understand AuthClient.

Most React apps never touch it directly — the provider + hook are the right interface. Reach for AuthClient when:

  • You need IntelliAuth in a non-React part of the same app (a service worker, a Web Worker, a vanilla-JS legacy widget).
  • You are building a non-React framework adapter (Vue, Svelte, Solid) and need the engine without the React-specific bits.
  • You're writing a test that needs to drive sign-in without a React tree.
import { AuthClient } from '@intelliauth/react-sdk'
const auth = new AuthClient({
tenantUrl: 'https://banking-cymmetri.intelliauth.local',
clientId: 'app_01HZX...',
redirectUri: window.location.origin + '/callback',
scope: 'openid profile email offline_access',
})

Same configuration shape as the <IntelliAuthProvider /> props, minus the React-specific callbacks (onLogin, etc.). Use auth.on('event-name', handler) for those instead.

The same surface the useIntelliAuth() hook exposes, but as plain methods on the class.

// State
auth.user // current user or null
auth.loading // boolean
auth.error // IntelliAuthError or null
// Auth flows
await auth.loginWithRedirect()
await auth.logout()
await auth.handleRedirectCallback() // call from your /callback route
// Tokens
await auth.getAccessToken()
await auth.forceRefresh()
await auth.checkSession()
// User
await auth.getProfile()
await auth.updateProfile({ name: 'Anita' })
await auth.changePassword({ current: '...', next: '...' })
// MFA
await auth.startMfaEnrolment('totp')
await auth.listMfaEnrolments()
await auth.removeMfaEnrolment('factor_01HZX...')
// Sessions
await auth.listSessions()
await auth.revokeSession('ses_01HZX...')
await auth.revokeOtherSessions()

The full method list lives in the useIntelliAuth() reference — same names, same shapes.

auth.on('login', (user) => console.log('signed in', user))
auth.on('logout', () => console.log('signed out'))
auth.on('tokenRefresh', (tokens) => console.log('refreshed', tokens.expires_at))
auth.on('error', (err) => console.error(err))

Returns an unsubscribe function:

const off = auth.on('login', handler)
// later
off()

The token storage primitives in AuthClient use localStorage by default, which is not available in a service worker. Pass cacheLocation: 'memory' to keep state in the worker's memory:

const auth = new AuthClient({
tenantUrl: '...',
clientId: '...',
redirectUri: '...',
cacheLocation: 'memory',
})

The main thread (the React app) and the service worker each have their own AuthClient. The two are not magically linked. If the user signs in via the main thread, the service worker won't know about it until you tell it. The pattern: the main thread posts a message to the service worker with the access token; the service worker uses that token for its own API calls.

For tests that run in a JSDOM-style environment with a mocked redirect endpoint, you can drive handleRedirectCallback manually:

// Pretend the browser came back from /callback with code + state
window.history.replaceState({}, '', '/callback?code=abc123&state=xyz789')
await auth.handleRedirectCallback()

In real browser-based tests (Playwright, Cypress), let the SDK do its normal thing — the redirect actually happens, the SDK handles it.

import { AuthClient } from '@intelliauth/react-sdk'
AuthClient.isLoginCallback(window.location)
// true if the current URL is a login callback (has ?code= and ?state=)
AuthClient.isLogoutCallback(window.location)
// true if the current URL is a logout return

Useful for tiny apps that drive everything through a single route component.

If you can use the React hook, do. The hook handles re-renders on auth state change, deduplicates concurrent getAccessToken() calls, and integrates with React's Suspense in newer SDK versions. AuthClient is the escape hatch, not the default.