import { Router } from '@angular/router'; import { Observable } from 'rxjs'; import { AngularHttpAdapter } from './http-adapter'; import { RecaptchaService } from '../lib/recaptcha.service'; import { NAuthClient, NAuthClientConfig, ChallengeResponse, AuthResponse, TokenResponse, AuthUser, ConfirmForgotPasswordResponse, ForgotPasswordResponse, ResetPasswordWithCodeResponse, UpdateProfileRequest, GetChallengeDataResponse, GetSetupDataResponse, GetMFADevicesResponse, MFAStatus, RemoveMFADeviceResponse, AuthEvent, SocialProvider, SocialLoginOptions, LinkedAccountsResponse, SocialVerifyRequest, AuditHistoryResponse, AdminOperations } from '@nauth-toolkit/client'; import * as i0 from "@angular/core"; /** * Angular wrapper around NAuthClient that provides promise-based auth methods and reactive state. * * This service provides: * - Reactive state (currentUser$, isAuthenticated$, challenge$) * - All core auth methods as Promises (login, signup, logout, refresh) * - Profile management (getProfile, updateProfile, changePassword) * - Challenge flow methods (respondToChallenge, resendCode) * - MFA management (getMfaStatus, setupMfaDevice, etc.) * - Social authentication and account linking * - Device trust management * - Audit history * * @example * ```typescript * constructor(private auth: AuthService) {} * * // Reactive state * this.auth.currentUser$.subscribe(user => ...); * this.auth.isAuthenticated$.subscribe(isAuth => ...); * * // Auth operations with async/await * const response = await this.auth.login(email, password); * * // Profile management * await this.auth.changePassword(oldPassword, newPassword); * const user = await this.auth.updateProfile({ firstName: 'John' }); * * // MFA operations * const status = await this.auth.getMfaStatus(); * ``` */ export declare class AuthService { private router?; private recaptchaService?; private readonly client; private readonly config; private readonly currentUserSubject; private readonly isAuthenticatedSubject; private readonly challengeSubject; private readonly authEventsSubject; private initialized; /** * @param config - Injected client configuration (required) * @param httpAdapter - Angular HTTP adapter for making requests (required) * @param router - Angular Router (optional, automatically used for navigation if available) * @param recaptchaService - RecaptchaService (optional, for automatic token generation) */ constructor(config: NAuthClientConfig, httpAdapter: AngularHttpAdapter, router?: Router, recaptchaService?: RecaptchaService); /** * Current user observable. */ get currentUser$(): Observable; /** * Authenticated state observable. */ get isAuthenticated$(): Observable; /** * Current challenge observable (for reactive challenge navigation). */ get challenge$(): Observable; /** * Authentication events stream. * Emits all auth lifecycle events for custom logic, analytics, or UI updates. */ get authEvents$(): Observable; /** * Successful authentication events stream. * Emits when user successfully authenticates (login, signup, social auth). */ get authSuccess$(): Observable; /** * Authentication error events stream. * Emits when authentication fails (login error, OAuth error, etc.). */ get authError$(): Observable; /** * Check if authenticated (sync, uses cached state). */ isAuthenticated(): boolean; /** * Get current user (sync, uses cached state). */ getCurrentUser(): AuthUser | null; /** * Get current challenge (sync). */ getCurrentChallenge(): AuthResponse | null; /** * Get challenge router for manual navigation control. * Useful for guards that need to handle errors or build custom URLs. * * @returns ChallengeRouter instance * * @example * ```typescript * const router = this.auth.getChallengeRouter(); * await router.navigateToError('oauth'); * ``` */ getChallengeRouter(): import("@nauth-toolkit/client").ChallengeRouter; /** * Login with identifier and password. * * Automatically generates reCAPTCHA token if configured (v3 only). * For v2 manual mode, pass the token explicitly. * * @param identifier - User email or username * @param password - User password * @param recaptchaToken - Optional reCAPTCHA token (for v2 manual mode or when auto-generation is disabled) * @returns Promise with auth response or challenge * * @example Basic Login * ```typescript * const response = await this.auth.login('user@example.com', 'password'); * ``` * * @example With Manual reCAPTCHA (v2) * ```typescript * const response = await this.auth.login('user@example.com', 'password', recaptchaToken); * ``` */ login(identifier: string, password: string, recaptchaToken?: string): Promise; /** * Signup with credentials. * * Automatically generates reCAPTCHA token if configured (v3 only). * For v2 manual mode, include token in payload. * * @param payload - Signup request payload * @returns Promise with auth response or challenge * * @example Basic Signup * ```typescript * const response = await this.auth.signup({ * email: 'new@example.com', * password: 'SecurePass123!', * firstName: 'John', * }); * ``` * * @example With Manual reCAPTCHA (v2) * ```typescript * const response = await this.auth.signup({ * email: 'new@example.com', * password: 'SecurePass123!', * recaptchaToken: token, * }); * ``` */ signup(payload: Parameters[0]): Promise; /** * Logout current session. * * @param forgetDevice - If true, removes device trust * * @example * ```typescript * await this.auth.logout(); * ``` */ logout(forgetDevice?: boolean): Promise; /** * Logout all sessions. * * Revokes all active sessions for the current user across all devices. * Optionally revokes all trusted devices if forgetDevices is true. * * @param forgetDevices - If true, also revokes all trusted devices (default: false) * @returns Promise with number of sessions revoked * * @example * ```typescript * const result = await this.auth.logoutAll(); * console.log(`Revoked ${result.revokedCount} sessions`); * ``` */ logoutAll(forgetDevices?: boolean): Promise<{ revokedCount: number; }>; /** * Refresh tokens. * * @returns Promise with new tokens * * @example * ```typescript * const tokens = await this.auth.refresh(); * ``` */ refresh(): Promise; /** * Request a password reset code (forgot password). * * @param identifier - User email, username, or phone * @returns Promise with password reset response * * @example * ```typescript * await this.auth.forgotPassword('user@example.com'); * ``` */ forgotPassword(identifier: string): Promise; /** * Confirm a password reset code and set a new password. * * @param identifier - User email, username, or phone * @param code - One-time reset code * @param newPassword - New password * @returns Promise with confirmation response * * @example * ```typescript * await this.auth.confirmForgotPassword('user@example.com', '123456', 'NewPass123!'); * ``` */ confirmForgotPassword(identifier: string, code: string, newPassword: string): Promise; /** * Reset password with code or token (generic method for both admin and user-initiated resets). * * Accepts either: * - code: Short numeric code from email/SMS (6-10 digits) * - token: Long hex token from reset link (64 chars) * * @param identifier - User identifier (email, username, phone) * @param codeOrToken - Verification code OR token from link * @param newPassword - New password * @returns Promise with success response * * @example * ```typescript * // With code from email * await this.auth.resetPasswordWithCode('user@example.com', '123456', 'NewPass123!'); * * // With token from link * await this.auth.resetPasswordWithCode('user@example.com', '64-char-token', 'NewPass123!'); * ``` */ resetPasswordWithCode(identifier: string, codeOrToken: string, newPassword: string): Promise; /** * Change user password (requires current password). * * @param oldPassword - Current password * @param newPassword - New password (must meet requirements) * @returns Promise that resolves when password is changed * * @example * ```typescript * await this.auth.changePassword('oldPassword123', 'newSecurePassword456!'); * ``` */ changePassword(oldPassword: string, newPassword: string): Promise; /** * Get current user profile. * * @returns Promise of current user profile * * @example * ```typescript * const user = await this.auth.getProfile(); * console.log('User profile:', user); * ``` */ getProfile(): Promise; /** * Update user profile. * * @param updates - Profile fields to update * @returns Promise of updated user profile * * @example * ```typescript * const user = await this.auth.updateProfile({ firstName: 'John', lastName: 'Doe' }); * console.log('Profile updated:', user); * ``` */ updateProfile(updates: UpdateProfileRequest): Promise; /** * Respond to a challenge (VERIFY_EMAIL, VERIFY_PHONE, MFA_REQUIRED, etc.). * * @param response - Challenge response data * @returns Promise with auth response or next challenge * * @example * ```typescript * const result = await this.auth.respondToChallenge({ * session: challengeSession, * type: 'VERIFY_EMAIL', * code: '123456', * }); * ``` */ respondToChallenge(response: ChallengeResponse): Promise; /** * Resend challenge code. * * @param session - Challenge session token * @returns Promise with destination information * * @example * ```typescript * const result = await this.auth.resendCode(session); * console.log('Code sent to:', result.destination); * ``` */ resendCode(session: string): Promise<{ destination: string; }>; /** * Get MFA setup data (for MFA_SETUP_REQUIRED challenge). * * Returns method-specific setup information: * - TOTP: { secret, qrCode, manualEntryKey } * - SMS: { maskedPhone } * - Email: { maskedEmail } * - Passkey: WebAuthn registration options * * @param session - Challenge session token * @param method - MFA method to set up * @returns Promise of setup data response * * @example * ```typescript * const setupData = await this.auth.getSetupData(session, 'totp'); * console.log('QR Code:', setupData.setupData.qrCode); * ``` */ getSetupData(session: string, method: string): Promise; /** * Get MFA challenge data (for MFA_REQUIRED challenge - e.g., passkey options). * * @param session - Challenge session token * @param method - Challenge method * @returns Promise of challenge data response * * @example * ```typescript * const challengeData = await this.auth.getChallengeData(session, 'passkey'); * ``` */ getChallengeData(session: string, method: string): Promise; /** * Clear stored challenge (when navigating away from challenge flow). * * @returns Promise that resolves when challenge is cleared * * @example * ```typescript * await this.auth.clearChallenge(); * ``` */ clearChallenge(): Promise; /** * Get current access token (JSON mode only). * * This is primarily useful for consumers using Angular `HttpClient` directly * (outside of the SDK methods) and relying on an interceptor to attach Bearer tokens. * * @returns Access token, or null if not available * * @example * ```typescript * const token = await this.auth.getAccessToken(); * ``` */ getAccessToken(): Promise; /** * Initiate social OAuth login flow. * Redirects the browser to backend `/auth/social/:provider/redirect`. * * @param provider - Social provider ('google', 'apple', 'facebook') * @param options - Optional redirect options * @returns Promise that resolves when redirect starts * * @example * ```typescript * await this.auth.loginWithSocial('google', { returnTo: '/auth/callback' }); * ``` */ loginWithSocial(provider: SocialProvider, options?: SocialLoginOptions): Promise; /** * Exchange an exchangeToken (from redirect callback URL) into an AuthResponse. * * Used for `tokenDelivery: 'json'` or hybrid flows where the backend redirects back * with `exchangeToken` instead of setting cookies. * * @param exchangeToken - One-time exchange token from the callback URL * @returns Promise of AuthResponse * * @example * ```typescript * const response = await this.auth.exchangeSocialRedirect(exchangeToken); * ``` */ exchangeSocialRedirect(exchangeToken: string): Promise; /** * Verify native social token (mobile). * * @param request - Social verification request with provider and token * @returns Promise of AuthResponse * * @example * ```typescript * const result = await this.auth.verifyNativeSocial({ * provider: 'google', * idToken: nativeIdToken, * }); * ``` */ verifyNativeSocial(request: SocialVerifyRequest): Promise; /** * Get linked social accounts. * * @returns Promise of linked accounts response * * @example * ```typescript * const accounts = await this.auth.getLinkedAccounts(); * console.log('Linked providers:', accounts.providers); * ``` */ getLinkedAccounts(): Promise; /** * Link social account. * * @param provider - Social provider to link * @param code - OAuth authorization code * @param state - OAuth state parameter * @returns Promise with success message * * @example * ```typescript * await this.auth.linkSocialAccount('google', code, state); * ``` */ linkSocialAccount(provider: string, code: string, state: string): Promise<{ message: string; }>; /** * Unlink social account. * * @param provider - Social provider to unlink * @returns Promise with success message * * @example * ```typescript * await this.auth.unlinkSocialAccount('google'); * ``` */ unlinkSocialAccount(provider: string): Promise<{ message: string; }>; /** * 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 cleared after retrieval to prevent reuse. * * @returns The stored appState, or null if none exists * * @example * ```typescript * const appState = await this.auth.getLastOauthState(); * if (appState) { * // Apply invite code or restore UI state * console.log('OAuth state:', appState); * } * ``` */ getLastOauthState(): Promise; /** * Get MFA status for the current user. * * @returns Promise of MFA status * * @example * ```typescript * const status = await this.auth.getMfaStatus(); * console.log('MFA enabled:', status.enabled); * ``` */ getMfaStatus(): Promise; /** * Get MFA devices for the current user. * * @returns Promise of MFA devices response * * @example * ```typescript * const result = await this.auth.getMfaDevices(); * console.log('Devices:', result.devices); * ``` */ getMfaDevices(): Promise; /** * Setup MFA device (authenticated user). * * Returns method-specific setup information: * - TOTP: { secret, qrCode, manualEntryKey } * - SMS: { maskedPhone } or { deviceId, autoCompleted: true } * - Email: { maskedEmail } or { deviceId, autoCompleted: true } * - Passkey: WebAuthn registration options * * @param method - MFA method to set up * @returns Promise of setup data response * * @example * ```typescript * const result = await this.auth.setupMfaDevice('totp'); * console.log('QR Code:', result.setupData.qrCode); * ``` */ setupMfaDevice(method: string): Promise; /** * Verify MFA setup (authenticated user). * * Completes MFA device setup by verifying the setup data. The structure of `setupData` varies by method: * * **TOTP:** * - Requires both `secret` (from `getSetupData()` response) and `code` (from authenticator app) * - Example: `{ secret: 'JBSWY3DPEHPK3PXP', code: '123456' }` * * **SMS:** * - Requires `phoneNumber` and `code` (verification code sent to phone) * - Example: `{ phoneNumber: '+1234567890', code: '123456' }` * * **Email:** * - Requires `code` (verification code sent to email) * - Example: `{ code: '123456' }` * * **Passkey:** * - Requires `credential` (WebAuthn credential from registration) and `expectedChallenge` * - Example: `{ credential: {...}, expectedChallenge: '...' }` * * @param method - MFA method ('totp', 'sms', 'email', 'passkey') * @param setupData - Method-specific setup verification data * @param deviceName - Optional device name (can also be included in setupData for some methods) * @returns Promise with device ID of the created MFA device * * @example TOTP Setup * ```typescript * // Step 1: Get setup data * const setupData = await this.auth.setupMfaDevice('totp'); * // Returns: { setupData: { secret: 'JBSWY3DPEHPK3PXP', qrCode: '...', ... } } * * // Step 2: User scans QR code and enters code from authenticator app * const code = '123456'; // From authenticator app * * // Step 3: Verify setup (requires both secret and code) * const result = await this.auth.verifyMfaSetup('totp', { * secret: setupData.setupData.secret, * code: code, * }, 'Google Authenticator'); * // Returns: { deviceId: 123 } * ``` * * @example SMS Setup * ```typescript * const result = await this.auth.verifyMfaSetup('sms', { * phoneNumber: '+1234567890', // Phone number receiving the code * code: '123456', // Code sent to phone * }, 'My iPhone'); * ``` * * @example Passkey Setup * ```typescript * const credential = await navigator.credentials.create({ * publicKey: setupData.setupData.options * }); * const result = await this.auth.verifyMfaSetup('passkey', { * credential: credential, * expectedChallenge: setupData.setupData.challenge, * }, 'MacBook Pro'); * ``` */ verifyMfaSetup(method: string, setupData: Record, deviceName?: string): Promise<{ deviceId: number; }>; /** * Remove a single MFA device by device ID. * * **Recommended:** Use this for granular device management. * * @param deviceId - MFA device ID * @returns Removal response * * @example * ```typescript * const devices = await this.auth.getMfaDevices(); * await this.auth.removeMfaDeviceById(devices[0].id); * ``` */ removeMfaDeviceById(deviceId: number): Promise; /** /** * Select an MFA device for verification (during challenge flow) * * Call this when user selects a specific device from the MFA selector UI. * SDK stores the deviceId internally and auto-injects it when respondToChallenge() is called. * * @param deviceId - ID of the device user selected * * @example * ```typescript * // User clicks "Microsoft Authenticator" button * this.auth.selectMFADevice(48); * * // Navigate to OTP verification (no deviceId in query params needed!) * this.router.navigate(['/auth/challenge/mfa-required']); * * // Later, when submitting OTP code: * await this.auth.respondToChallenge({ * type: 'MFA_REQUIRED', * session: 'abc123', * method: 'totp', * code: '123456', * // SDK auto-injects deviceId=48 here! * }); * ``` */ selectMFADevice(deviceId: number): void; /** * Get available MFA devices from challenge response * * Returns array of devices for methods that support multiple devices (TOTP, Passkey). * Use this to render device selection UI only. * * @param challenge - Challenge response from login/signup * @returns Array of MFA devices with id, name, and type * * @example * ```typescript * // In MFA selector component * const devices = this.auth.getMFADevicesFromChallenge(this.challenge()); * // Returns: [ * // { id: 48, name: "Microsoft Authenticator", type: "totp" }, * // { id: 3, name: "Google Authenticator", type: "totp" } * // ] * * // Render device buttons * for (const device of devices) { * // * } * ``` */ getMFADevicesFromChallenge(challenge: AuthResponse): Array<{ id: number; name: string; type: string; }>; /** * Clear any selected MFA device * * Useful if user navigates back to device selector or cancels MFA flow. */ clearSelectedMFADevice(): void; /** * Set preferred MFA method. * * @param method - Device method to set as preferred ('totp', 'sms', 'email', or 'passkey') * @returns Promise with success message * * @example * ```typescript * await this.auth.setPreferredMfaMethod('totp'); * ``` */ /** * Set a specific MFA device as preferred. * * @param deviceId - MFA device ID * @returns Promise with success message */ setPreferredMfaDevice(deviceId: number): Promise<{ message: string; }>; /** * Generate backup codes. * * @returns Promise of backup codes array * * @example * ```typescript * const codes = await this.auth.generateBackupCodes(); * console.log('Backup codes:', codes); * ``` */ generateBackupCodes(): Promise; /** * Trust current device. * * @returns Promise with device token * * @example * ```typescript * const result = await this.auth.trustDevice(); * console.log('Device trusted:', result.deviceToken); * ``` */ trustDevice(): Promise<{ deviceToken: string; }>; /** * Check if the current device is trusted. * * @returns Promise with trusted status * * @example * ```typescript * const result = await this.auth.isTrustedDevice(); * if (result.trusted) { * console.log('This device is trusted'); * } * ``` */ isTrustedDevice(): Promise<{ trusted: boolean; }>; /** * Get paginated audit history for the current user. * * @param params - Query parameters for filtering and pagination * @returns Promise of audit history response * * @example * ```typescript * const history = await this.auth.getAuditHistory({ * page: 1, * limit: 20, * eventTypes: ['LOGIN_SUCCESS'], * eventStatus: ['FAILURE'], * }); * console.log('Audit history:', history); * ``` */ getAuditHistory(params?: Record>): Promise; /** * Expose underlying NAuthClient for advanced scenarios. * * @returns The underlying NAuthClient instance * * @example * ```typescript * // Deprecated - use direct methods instead * const status = await this.auth.getClient().getMfaStatus(); * * // Preferred - use direct methods * const status = await this.auth.getMfaStatus(); * ``` */ getClient(): NAuthClient; /** * Admin operations (if enabled in config). * * Provides admin-level user management methods: * - User CRUD operations * - Password management * - Session management * - MFA management * - Audit history * * Returns undefined if admin was not configured. * * @returns AdminOperations instance or undefined * * @example * ```typescript * // Check if admin is available * if (this.auth.admin) { * const users = await this.auth.admin.getUsers({ page: 1 }); * } * * // With optional chaining * await this.auth.admin?.deleteUser(sub); * * // Create user * const result = await this.auth.admin?.createUser({ * email: 'user@example.com', * password: 'SecurePass123!', * isEmailVerified: true, * }); * ``` */ get admin(): AdminOperations | undefined; /** * Initialize by hydrating state from storage. * Called automatically on construction. */ private initialize; /** * Update challenge state after auth response. */ private updateChallengeState; /** * Get reCAPTCHA token - auto-generate for v3 or use provided token. * * Handles platform detection: * - Web browser: Generate token if enabled and v3 * - Capacitor native: Skip (use device attestation instead) * - SSR: Skip * - Manual mode (v2 or manualChallenge=true): Requires explicit token * * @param providedToken - Explicitly provided token (v2 manual mode) * @param action - Action name for v3 analytics * @returns reCAPTCHA token or undefined * * @private */ private getRecaptchaToken; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; }