Skip to main content

NAuthClient

Package: @nauth-toolkit/client Type: Class

Primary client for interacting with nauth-toolkit backend. Handles authentication, challenges, MFA, social auth, and token management.

import { NAuthClient } from '@nauth-toolkit/client';

Constructor

new NAuthClient(config: NAuthClientConfig)

Parameters

Example

const client = new NAuthClient({
baseUrl: 'https://api.example.com/auth',
tokenDelivery: 'cookies',
onSessionExpired: () => window.location.replace('/login'),
onAuthStateChange: (user) => console.log('Auth state:', user),
});

Methods

Backend Configuration Required

Some methods require additional backend features to be enabled:

  • MFA methods (generateBackupCodes, getMfaDevices, getMfaStatus, removeMfaDeviceById, setPreferredMfaDevice, setupMfaDevice, verifyMfaSetup): require MFA enabled in nauth.config.ts. See Backend MFA Configuration.
  • Social auth methods (exchangeSocialRedirect, getLastOauthState, getLinkedAccounts, linkSocialAccount, loginWithSocial, unlinkSocialAccount, verifyNativeSocial): require social auth providers configured. See Backend Social Login Configuration.
  • Device trust methods (isTrustedDevice, trustDevice): require device trust feature enabled. See Backend Configuration.
  • Audit methods (getAuditHistory): require audit logging enabled. See Backend Configuration.

changePassword()

Change user password (requires current password).

async changePassword(oldPassword: string, newPassword: string): Promise<void>

Parameters

ParameterTypeDescription
oldPasswordstringCurrent password
newPasswordstringNew password (must meet requirements)

See ChangePasswordRequest for request structure.

Errors

CodeWhenDetails
PASSWORD_INCORRECTWrong current passwordundefined
WEAK_PASSWORDPolicy violation{ errors?: string[] }
PASSWORD_REUSEDPassword recently usedundefined
PASSWORD_CHANGE_NOT_ALLOWEDSocial-only accountundefined

Example

await client.changePassword('oldPassword123', 'newSecurePassword456!');

clearStoredChallenge()

Clear persisted challenge session.

async clearStoredChallenge(): Promise<void>

confirmForgotPassword()

Confirm a password reset code and set a new password.

async confirmForgotPassword(identifier: string, code: string, newPassword: string): Promise<ConfirmForgotPasswordResponse>

Parameters

ParameterTypeDescription
identifierstringEmail, username, or phone
codestringOne-time reset code
newPasswordstringNew password

Returns

See ConfirmForgotPasswordRequest for request structure.

Errors

CodeWhenDetails
PASSWORD_RESET_CODE_INVALIDCode invalidundefined
PASSWORD_RESET_CODE_EXPIREDCode expiredundefined
PASSWORD_RESET_MAX_ATTEMPTSToo many attemptsundefined
WEAK_PASSWORDPolicy violation{ errors?: string[] }
PASSWORD_REUSEDPassword recently usedundefined

Example

await client.confirmForgotPassword('user@example.com', '123456', 'NewSecurePass123!');

dispose()

Cleans up resources (event listeners). Call when client is no longer needed.

dispose(): void

exchangeSocialRedirect()

Exchange an exchangeToken (returned in the frontend callback URL) into an AuthResponse.

async exchangeSocialRedirect(exchangeToken: string): Promise<AuthResponse>

Parameters

ParameterTypeDescription
exchangeTokenstringOne-time token issued by backend redirect flow

Returns

  • AuthResponse - Authentication result (tokens or challenge)

Example

const params = new URLSearchParams(window.location.search);
const exchangeToken = params.get('exchangeToken');
if (exchangeToken) {
const response = await client.exchangeSocialRedirect(exchangeToken);
// Redirect based on response.challengeName or success
}

Errors

CodeWhen
CHALLENGE_INVALIDexchangeToken is missing or invalid

See


forgotPassword()

Request a password reset code (account recovery).

async forgotPassword(identifier: string): Promise<ForgotPasswordResponse>

Parameters

ParameterTypeDescription
identifierstringEmail, username, or phone

Returns

See ForgotPasswordRequest for request structure.

Errors

CodeWhenDetails
RATE_LIMIT_PASSWORD_RESETToo many requests{ retryAfter?: number, maxAttempts?: number }

Example

await client.forgotPassword('user@example.com');

generateBackupCodes()

Generate new backup codes for MFA recovery.

async generateBackupCodes(): Promise<string[]>

Returns

  • string[] - Array of backup codes (store securely). See BackupCodesResponse for response structure.

Example

const codes = await client.generateBackupCodes();
console.log('Backup codes:', codes); // ['ABC123', 'DEF456', ...]
// Store these securely - they won't be shown again

getAccessToken()

Get current access token.

async getAccessToken(): Promise<string | null>

getAuditHistory()

Get user's authentication audit history with filtering and pagination.

async getAuditHistory(params?: Record<string, string | number | boolean>): Promise<AuditHistoryResponse>

Parameters

ParameterTypeDescription
pagenumberPage number (default: 1)
limitnumberItems per page (default: 20)
eventTypeAuthAuditEventTypeFilter by event type
eventStatusAuthAuditEventStatusFilter by status

Returns

Example

// Get all login events
const logins = await client.getAuditHistory({
eventType: 'LOGIN_SUCCESS',
page: 1,
limit: 50,
});

// Get suspicious activity
const suspicious = await client.getAuditHistory({
eventStatus: 'SUSPICIOUS',
page: 1,
limit: 100,
});

console.log(`Found ${suspicious.total} suspicious events`);

See AuditHistoryResponse and AuthAuditEvent for details.


getChallengeData()

Get challenge data during MFA_REQUIRED challenge (e.g., passkey options).

async getChallengeData(session: string, method: MFAChallengeMethod): Promise<GetChallengeDataResponse>

Parameters

ParameterTypeDescription
sessionstringChallenge session token
methodMFAChallengeMethodMFA method

Returns

See GetChallengeDataResponse for details.


getCurrentUser()

Get current user from cache.

getCurrentUser(): AuthUser | null

Returns

See AuthUser for user properties.


getLastOauthState()

Get the last OAuth appState from social redirect callback.

Returns the appState that was stored during the most recent social login redirect callback. This is useful for restoring UI state, applying invite codes, or tracking referral information.

The state is automatically stored when the callback guard processes the redirect URL, and is automatically cleared after retrieval to prevent reuse.

async getLastOauthState(): Promise<string | null>

Returns

  • Promise<string | null> - The stored appState, or null if none exists

Example

// After social login redirect completes
const appState = await client.getLastOauthState();
if (appState) {
// Apply invite code or restore UI state
console.log('OAuth state:', appState);
// Example: applyInviteCode(appState);
}

Note

  • The appState is also passed as a query parameter to the success route (e.g., /dashboard?appState=invite-code-123)
  • You can read it from the URL query parameters instead if preferred
  • The state is cleared after retrieval, so call this method only once per OAuth flow

See


getLinkedAccounts()

Get user's linked social accounts.

async getLinkedAccounts(): Promise<LinkedAccountsResponse>

Returns

Example

const accounts = await client.getLinkedAccounts();
console.log('Linked providers:', accounts.providers); // ['google', 'apple']

getMfaDevices()

Get user's registered MFA devices.

async getMfaDevices(): Promise<GetMFADevicesResponse>

Returns

Example

const result = await client.getMfaDevices();
result.devices.forEach((device) => {
console.log('Device:', device.type, device.name);
});

getMfaStatus()

Get user's MFA status.

async getMfaStatus(): Promise<MFAStatus>

Returns

  • MFAStatus - User's MFA configuration and status

See MFAStatus for all properties.


getProfile()

Fetch current user profile from server.

async getProfile(): Promise<AuthUser>

Returns


getSetupData()

Get MFA setup data during MFA_SETUP_REQUIRED challenge.

async getSetupData(session: string, method: MFAMethod): Promise<GetSetupDataResponse>

Parameters

ParameterTypeDescription
sessionstringChallenge session token
methodMFAMethodMFA method to set up

Returns

Setup Data by Method

MethodStructure
totp{ secret, qrCode, manualEntryKey, issuer, accountName }
sms{ maskedPhone } or { deviceId, autoCompleted: true }
email{ maskedEmail } or { deviceId, autoCompleted: true }
passkeyWebAuthn registration options

See GetSetupDataResponse for details.


getStoredChallenge()

Retrieve persisted challenge session from storage.

async getStoredChallenge(): Promise<AuthResponse | null>

Returns

See ChallengeResponse for challenge types.


initialize()

Hydrates client state from storage. Call on app startup to restore authentication state.

async initialize(): Promise<void>

Example

await client.initialize();
const user = client.getCurrentUser();

isAuthenticated()

Check if user is authenticated (async, checks tokens).

async isAuthenticated(): Promise<boolean>

isAuthenticatedSync()

Check if user is authenticated (sync, checks cached state). Use for guards and templates.

isAuthenticatedSync(): boolean

isTrustedDevice()

Check if the current device is trusted.

Performs server-side validation of the device token and checks:

  • Device token exists and is valid
  • Device token matches a trusted device record in the database
  • Trust has not expired

Works in both cookies mode (reads from httpOnly cookie) and JSON mode (reads from X-Device-Token header).

async isTrustedDevice(): Promise<{ trusted: boolean }>

Returns

  • { trusted: boolean } - Whether the current device is trusted

Example

const result = await client.isTrustedDevice();

if (result.trusted) {
console.log('This device is trusted');
} else {
console.log('This device is not trusted');
}

Related:


linkSocialAccount()

Link a social account to existing authenticated user.

async linkSocialAccount(
provider: string,
code: string,
state: string
): Promise<{ message: string }>

Parameters

ParameterTypeDescription
providerSocialProviderSocial provider ('google', 'apple', 'facebook')
codestringOAuth authorization code from callback
statestringOAuth state parameter from callback

Returns

  • { message: string } - Success message

Example

// After OAuth callback
const params = new URLSearchParams(window.location.search);
await client.linkSocialAccount('google', params.get('code')!, params.get('state')!);

login()

Authenticate with identifier (email) and password.

async login(identifier: string, password: string, recaptchaToken?: string): Promise<AuthResponse>

Parameters

ParameterTypeDescription
identifierstringUser email or username
passwordstringUser password
recaptchaTokenstringOptional reCAPTCHA token (v2 manual mode or explicit)

Returns

Errors

CodeWhenDetails
AUTH_INVALID_CREDENTIALSWrong email/passwordundefined
AUTH_ACCOUNT_LOCKEDToo many attempts{ lockoutUntil?: string }
AUTH_ACCOUNT_INACTIVEAccount deactivatedundefined

See NAuthClientError for error handling.

Example

const response = await client.login('user@example.com', 'password123');

if (response.challengeName) {
// Handle challenge (MFA, email verification, etc.)
console.log('Challenge:', response.challengeName, response.session);
} else {
// Login successful
console.log('User:', response.user);
}

loginWithSocial()

Start redirect-first web social login.

async loginWithSocial(provider: 'google' | 'apple' | 'facebook', options?: SocialLoginOptions): Promise<void>

Parameters

ParameterTypeDescription
provider'google' | 'apple' | 'facebook'OAuth provider
optionsSocialLoginOptionsRedirect options (returnTo, appState, action, oauthParams)

Returns

  • Promise<void> - Redirects to OAuth provider

Examples

// Basic usage
await client.loginWithSocial('google', {
returnTo: '/auth/callback',
appState: '12345'
});

// Force Google account chooser
await client.loginWithSocial('google', {
returnTo: '/dashboard',
oauthParams: { prompt: 'select_account' }
});

// Multiple OAuth parameters
await client.loginWithSocial('google', {
returnTo: '/dashboard',
oauthParams: {
prompt: 'select_account consent',
hd: 'company.com',
login_hint: 'user@company.com'
}
});

// Facebook: Rerequest declined permissions
await client.loginWithSocial('facebook', {
returnTo: '/settings',
oauthParams: { auth_type: 'rerequest' }
});

// Apple with nonce for ID token validation
await client.loginWithSocial('apple', {
returnTo: '/dashboard',
oauthParams: { nonce: 'random-nonce-value' }
});

OAuth Parameters

The oauthParams option allows per-request customization of the OAuth flow. These parameters:

  • Override any defaults set in the backend configuration
  • Are appended directly to the provider's authorization URL
  • Enable provider-specific behaviors

Common use cases:

  • Google: Force account chooser, restrict to domain, pre-fill email
  • Facebook: Rerequest declined permissions, customize display mode
  • Apple: Add nonce for ID token validation

See SocialLoginOptions for complete parameter documentation.

See


logout()

End current session. Uses GET request to avoid CSRF token issues.

async logout(forgetDevice?: boolean): Promise<void>

Parameters

ParameterTypeDescription
forgetDevicebooleanIf true, removes device trust. Default: false
Authentication Required

This method requires the user to be authenticated. The endpoint is protected and cannot be called publicly.

Example

// Normal logout (device remains trusted)
await client.logout();

// Logout and forget device (device untrusted, MFA required on next login)
await client.logout(true);

logoutAll()

End all sessions for the current user across all devices.

async logoutAll(forgetDevices?: boolean): Promise<{ revokedCount: number }>

Parameters

ParameterTypeRequiredDescription
forgetDevicesbooleanNoIf true, also revokes all trusted devices. Default: false (devices remain trusted).

Returns

PropertyTypeDescription
revokedCountnumberNumber of sessions revoked
Authentication Required

This method requires the user to be authenticated. The endpoint is protected and cannot be called publicly.

Examples

// Revoke all sessions but keep devices trusted
const result = await client.logoutAll();
console.log(`Revoked ${result.revokedCount} sessions`);

// Revoke all sessions AND all trusted devices
const result2 = await client.logoutAll(true);
console.log(`Revoked ${result2.revokedCount} sessions and all trusted devices`);

off()

Unsubscribe from authentication events.

off(event: AuthEventType | '*', listener: AuthEventListener): void

Parameters

ParameterTypeDescription
eventAuthEventType | '*'Event type
listenerAuthEventListenerCallback function to remove

on()

Subscribe to authentication events.

on(event: AuthEventType | '*', listener: AuthEventListener): () => void

Parameters

ParameterTypeDescription
eventAuthEventType | '*'Event type to listen for, or '*' for all events
listenerAuthEventListenerCallback function

Returns

  • () => void - Unsubscribe function

Event Types

  • 'auth:login' - Login initiated
  • 'auth:signup' - Signup initiated
  • 'auth:success' - User authenticated
  • 'auth:challenge' - Challenge required
  • 'auth:error' - Authentication error
  • 'auth:logout' - User logged out
  • 'auth:refresh' - Token refresh attempted
  • 'auth:session_expired' - Refresh token expired; user must re-authenticate
  • 'oauth:started' - Social login initiated
  • 'oauth:callback' - OAuth callback detected
  • 'oauth:completed' - OAuth flow completed
  • 'oauth:error' - OAuth error

Example

// Listen to specific event
const unsubscribe = client.on('auth:success', (event) => {
console.log('User logged in:', event.data.user);
});

// Listen to all events
client.on('*', (event) => {
console.log('Auth event:', event.type);
});

// Unsubscribe
unsubscribe();

See


refreshTokens()

Manually refresh access and refresh tokens.

async refreshTokens(): Promise<TokenResponse>

Returns

Errors

CodeWhenDetails
AUTH_TOKEN_EXPIREDRefresh token expiredundefined
AUTH_TOKEN_INVALIDRefresh token invalid/revokedundefined

See NAuthClientError for error handling.

Example

try {
const tokens = await client.refreshTokens();
console.log('New access token expires at:', tokens.accessTokenExpiresAt);
} catch (error) {
// Token expired - redirect to login
}

removeMfaDeviceById()

Remove a single MFA device by its unique device ID.

Use this method to give users granular control over which specific device to remove.

async removeMfaDeviceById(deviceId: number): Promise<RemoveMFADeviceResponse>

Parameters

ParameterTypeDescription
deviceIdnumberMFA device ID (from getMfaDevices() or challenge data)

Returns

Example

// Get user's devices
const devices = await client.getMfaDevices();
// [{ id: 48, name: "Google Authenticator", type: "totp", isPreferred: true },
// { id: 52, name: "Microsoft Authenticator", type: "totp", isPreferred: false }]

// Remove specific device by ID
const result = await client.removeMfaDeviceById(52);
console.log(result.removedDeviceId); // 52
console.log(result.removedMethod); // 'totp'
console.log(result.mfaDisabled); // false (still has device 48)

resendCode()

Resend verification code for current challenge.

async resendCode(session: string): Promise<{ destination: string }>

Parameters

ParameterTypeDescription
sessionstringChallenge session token

Returns

PropertyTypeDescription
destinationstringMasked destination (e.g., ***@example.com)

Errors

CodeWhenDetails
RATE_LIMITEDToo many resend attempts{ retryAfter?: number }

resetPasswordWithCode()

Reset password with verification code (generic method for both admin-initiated and user-initiated resets).

async resetPasswordWithCode(
identifier: string,
code: string,
newPassword: string
): Promise<ResetPasswordWithCodeResponse>

Parameters

ParameterTypeDescription
identifierstringUser identifier (email, username, phone)
codestringVerification code (6-10 digits)
newPasswordstringNew password (min 8 characters)

Returns

Example

await client.resetPasswordWithCode('user@example.com', '123456', 'NewPass123!');

respondToChallenge()

Complete any authentication challenge (email verification, MFA, etc.).

async respondToChallenge(response: ChallengeResponse): Promise<AuthResponse>

Parameters

Returns

SDK Validation

The SDK performs client-side validation before sending requests:

  • TOTP Setup: Validates that setupData contains both secret (from getSetupData()) and code (user-entered). Throws NAuthClientError with VALIDATION_FAILED if either is missing.

Errors

CodeWhenDetails
VALIDATION_FAILEDTOTP setup missing secret or code{ field: 'secret' | 'code' }

Example

// Email verification
const result = await client.respondToChallenge({
session: challengeSession,
type: 'VERIFY_EMAIL',
code: '123456',
});

// MFA verification
const result = await client.respondToChallenge({
session: challengeSession,
type: 'MFA_REQUIRED',
method: 'totp',
code: '123456',
});

// MFA setup (TOTP - requires both secret and code)
const setupData = await client.getSetupData(challengeSession, 'totp');
const result = await client.respondToChallenge({
session: challengeSession,
type: 'MFA_SETUP_REQUIRED',
method: 'totp',
setupData: {
secret: setupData.setupData.secret, // Must include secret from getSetupData
code: '123456', // User-entered verification code
},
});

// MFA setup (SMS)
const result = await client.respondToChallenge({
session: challengeSession,
type: 'MFA_SETUP_REQUIRED',
method: 'sms',
setupData: { code: '123456' },
});

setPreferredMfaDevice()

Set a specific MFA device as preferred.

This is important when users can register multiple devices for the same method (notably TOTP and passkeys), so your UI can pick a deterministic default device during MFA challenges.

async setPreferredMfaDevice(deviceId: number): Promise<{ message: string }>

Parameters

ParameterTypeDescription
deviceIdnumberMFA device ID

Returns

  • { message: string } - Success message

Example

// Get user's devices
const devices = await client.getMfaDevices();

// Set preferred device (e.g., user selects "Google Authenticator" from list)
await client.setPreferredMfaDevice(devices[0].id);

setupMfaDevice()

Initiate MFA device setup for authenticated users (outside challenge flow).

async setupMfaDevice(method: string): Promise<GetSetupDataResponse>

Parameters

ParameterTypeDescription
methodMFAMethodMFA method ('totp', 'sms', 'email', 'passkey')

Returns

Example

const setupData = await client.setupMfaDevice('totp');
console.log('QR Code:', setupData.setupData.qrCode);
console.log('Secret:', setupData.setupData.secret);

signup()

Register a new user account.

async signup(payload: SignupRequest): Promise<AuthResponse>

Parameters

Returns

Errors

CodeWhenDetails
SIGNUP_EMAIL_EXISTSEmail already registeredundefined
SIGNUP_WEAK_PASSWORDPassword doesn't meet requirements{ requirements?: string[] }
VALIDATION_FAILEDInvalid input data{ field?: string }

See NAuthClientError for error handling.

Example

const response = await client.signup({
email: 'newuser@example.com',
password: 'SecurePass123!',
firstName: 'John',
lastName: 'Doe',
phone: '+14155551234',
metadata: {
invitation_code: '83891D228', // for custom use cases
referralCode: 'ABC123',
},
});

if (response.challengeName === 'VERIFY_EMAIL') {
// Redirect to email verification page
}

trustDevice()

Mark current device as trusted (skips MFA for future logins on this device).

async trustDevice(): Promise<{ deviceToken: string }>

Returns

  • { deviceToken: string } - Device trust token (stored automatically)

Example

const { deviceToken } = await client.trustDevice();
console.log('Device trusted:', deviceToken);

unlinkSocialAccount()

Unlink a social account from the authenticated user.

async unlinkSocialAccount(provider: string): Promise<{ message: string }>

Parameters

ParameterTypeDescription
providerSocialProviderSocial provider to unlink ('google', 'apple', 'facebook')

Returns

  • { message: string } - Success message

Example

await client.unlinkSocialAccount('google');

updateProfile()

Update user profile.

async updateProfile(updates: UpdateProfileRequest): Promise<AuthUser>

Parameters

Returns


verifyMfaSetup()

Complete MFA device setup by verifying the setup code/data.

async verifyMfaSetup(
method: string,
setupData: Record<string, unknown>,
deviceName?: string
): Promise<{ deviceId: number }>

Parameters

ParameterTypeDescription
methodMFAMethodMFA method being set up
setupDataRecord<string, unknown>Method-specific verification data (e.g., TOTP code, SMS code)
deviceNamestringOptional device name for identification

Returns

  • { deviceId: number } - ID of the newly created MFA device

Example

// After getting setup data
const setupData = await client.setupMfaDevice('totp');

// User scans QR code and enters the code from their authenticator app
const { deviceId } = await client.verifyMfaSetup(
'totp',
{
secret: setupData.setupData.secret, // Must include secret from setupMfaDevice()
code: '123456', // User-entered code from authenticator app
},
'My Phone',
);

verifyNativeSocial()

Verify native social token from mobile apps (Capacitor, React Native).

async verifyNativeSocial(request: SocialVerifyRequest): Promise<AuthResponse>

Parameters

Returns

Example

// After native OAuth (e.g., Google Sign-In plugin)
const result = await client.verifyNativeSocial({
provider: 'google',
idToken: nativeIdToken,
accessToken: nativeAccessToken,
});

if (result.challengeName) {
// Handle challenge
} else {
// Login successful
}

Errors

CodeWhen
SOCIAL_TOKEN_INVALIDNative token verification failed

See Social Authentication Guide for native flow details.


Admin Operations

admin

Admin operations service for user and system management. Available when admin configuration is provided in NAuthClientConfig.

public readonly admin?: AdminOperations

Access

const client = new NAuthClient({
baseUrl: 'https://api.example.com/auth',
tokenDelivery: 'cookies',
admin: {
pathPrefix: '/admin',
},
});

// Access admin operations
if (client.admin) {
const users = await client.admin.getUsers({ page: 1 });
await client.admin.deleteUser('user-uuid');
}

See AdminOperations for complete API documentation.