@nauth-toolkit/client 0.1.18 → 0.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -137,6 +137,10 @@ interface NAuthStorageAdapter {
137
137
  * Remove a stored value.
138
138
  */
139
139
  removeItem(key: string): Promise<void>;
140
+ /**
141
+ * Clear all stored values.
142
+ */
143
+ clear(): Promise<void>;
140
144
  }
141
145
 
142
146
  /**
@@ -259,12 +263,12 @@ interface NAuthEndpoints {
259
263
  mfaPreferred: string;
260
264
  mfaBackupCodes: string;
261
265
  mfaExemption: string;
262
- socialAuthUrl: string;
263
- socialCallback: string;
264
266
  socialLinked: string;
265
267
  socialLink: string;
266
268
  socialUnlink: string;
267
269
  socialVerify: string;
270
+ socialRedirectStart: string;
271
+ socialExchange: string;
268
272
  trustDevice: string;
269
273
  isTrustedDevice: string;
270
274
  auditHistory: string;
@@ -409,6 +413,17 @@ interface MFAStatus {
409
413
  mfaExemptReason: string | null;
410
414
  mfaExemptGrantedAt: string | Date | null;
411
415
  }
416
+ /**
417
+ * MFA device information.
418
+ */
419
+ interface MFADevice {
420
+ id: number;
421
+ type: MFADeviceMethod;
422
+ name: string;
423
+ isPrimary: boolean;
424
+ isActive: boolean;
425
+ createdAt: string | Date;
426
+ }
412
427
  /**
413
428
  * Response from getSetupData API call.
414
429
  * Contains provider-specific MFA setup information.
@@ -759,19 +774,34 @@ type AuthEventListener = (event: AuthEvent) => void;
759
774
  */
760
775
  type SocialProvider = 'google' | 'apple' | 'facebook';
761
776
  /**
762
- * Request to obtain social auth URL.
763
- */
764
- interface SocialAuthUrlRequest {
765
- provider: SocialProvider;
766
- state?: string;
767
- }
768
- /**
769
- * Social callback parameters.
777
+ * Options for starting a redirect-first social login flow.
778
+ *
779
+ * This is a web-first API:
780
+ * - Browser navigates to backend `/auth/social/:provider/redirect`
781
+ * - Backend completes OAuth, sets cookies (or returns exchange token), and redirects back
770
782
  */
771
- interface SocialCallbackRequest {
772
- provider: SocialProvider;
773
- code: string;
774
- state: string;
783
+ interface SocialLoginOptions {
784
+ /**
785
+ * Frontend route (recommended) or URL to redirect to after the backend callback completes.
786
+ * Default: config.redirects.success || '/'
787
+ */
788
+ returnTo?: string;
789
+ /**
790
+ * Optional application state to round-trip back to the frontend.
791
+ * Must be treated as non-secret.
792
+ */
793
+ appState?: string;
794
+ /**
795
+ * Optional flow action.
796
+ * Default: 'login'
797
+ */
798
+ action?: 'login' | 'link';
799
+ /**
800
+ * Optional delivery preference for redirect-first flows.
801
+ *
802
+ * Useful for hybrid deployments where provider callbacks do not contain a reliable `Origin`.
803
+ */
804
+ delivery?: 'cookies' | 'json';
775
805
  }
776
806
  /**
777
807
  * Linked social accounts response.
@@ -1056,69 +1086,36 @@ declare class NAuthClient {
1056
1086
  */
1057
1087
  off(event: AuthEventType | '*', listener: AuthEventListener): void;
1058
1088
  /**
1059
- * Start social OAuth flow with automatic state management.
1089
+ * Start redirect-first social OAuth flow (web).
1060
1090
  *
1061
- * Generates a secure state token, stores OAuth context, and redirects to the OAuth provider.
1062
- * After OAuth callback, use `handleOAuthCallback()` to complete authentication.
1091
+ * This performs a browser navigation to:
1092
+ * `GET {baseUrl}/social/:provider/redirect?returnTo=...&appState=...`
1093
+ *
1094
+ * The backend:
1095
+ * - generates and stores CSRF state (cluster-safe)
1096
+ * - redirects the user to the provider
1097
+ * - completes OAuth on callback and sets cookies (or issues an exchange token)
1098
+ * - redirects back to `returnTo` with `appState` (and `exchangeToken` for json/hybrid)
1063
1099
  *
1064
1100
  * @param provider - OAuth provider ('google', 'apple', 'facebook')
1065
- * @param options - Optional configuration
1101
+ * @param options - Optional redirect options
1066
1102
  *
1067
1103
  * @example
1068
1104
  * ```typescript
1069
- * // Simple usage
1070
- * await client.loginWithSocial('google');
1071
- *
1072
- * // With custom redirect URI
1073
- * await client.loginWithSocial('apple', {
1074
- * redirectUri: 'https://example.com/auth/callback'
1075
- * });
1105
+ * await client.loginWithSocial('google', { returnTo: '/auth/callback', appState: '12345' });
1076
1106
  * ```
1077
1107
  */
1078
- loginWithSocial(provider: SocialProvider, _options?: {
1079
- redirectUri?: string;
1080
- }): Promise<void>;
1108
+ loginWithSocial(provider: SocialProvider, options?: SocialLoginOptions): Promise<void>;
1081
1109
  /**
1082
- * Auto-detect and handle OAuth callback.
1083
- *
1084
- * Call this on app initialization or in callback route.
1085
- * Returns null if not an OAuth callback (no provider/code params).
1086
- *
1087
- * The SDK validates the state token, completes authentication via backend,
1088
- * and emits appropriate events.
1089
- *
1090
- * @param urlOrParams - Optional URL string or URLSearchParams (auto-detects from window.location if not provided)
1091
- * @returns AuthResponse if OAuth callback detected, null otherwise
1092
- *
1093
- * @example
1094
- * ```typescript
1095
- * // Auto-detect on app init
1096
- * const response = await client.handleOAuthCallback();
1097
- * if (response) {
1098
- * if (response.challengeName) {
1099
- * router.navigate(['/challenge', response.challengeName]);
1100
- * } else {
1101
- * router.navigate(['/']); // Navigate to your app's home route
1102
- * }
1103
- * }
1110
+ * Exchange an `exchangeToken` (from redirect callback URL) into an AuthResponse.
1104
1111
  *
1105
- * // In callback route
1106
- * const response = await client.handleOAuthCallback(window.location.search);
1107
- * ```
1108
- */
1109
- handleOAuthCallback(urlOrParams?: string | URLSearchParams): Promise<AuthResponse | null>;
1110
- /**
1111
- * Get social auth URL (low-level API).
1112
+ * Used for `tokenDelivery: 'json'` or hybrid flows where the backend redirects back
1113
+ * with `exchangeToken` instead of setting cookies.
1112
1114
  *
1113
- * For most cases, use `loginWithSocial()` which handles state management automatically.
1115
+ * @param exchangeToken - One-time exchange token from the callback URL
1116
+ * @returns AuthResponse
1114
1117
  */
1115
- getSocialAuthUrl(request: SocialAuthUrlRequest): Promise<{
1116
- url: string;
1117
- }>;
1118
- /**
1119
- * Handle social callback.
1120
- */
1121
- handleSocialCallback(request: SocialCallbackRequest): Promise<AuthResponse>;
1118
+ exchangeSocialRedirect(exchangeToken: string): Promise<AuthResponse>;
1122
1119
  /**
1123
1120
  * Verify native social token (mobile).
1124
1121
  */
@@ -1297,12 +1294,15 @@ declare class NAuthClient {
1297
1294
  /**
1298
1295
  * Angular wrapper around NAuthClient that exposes Observables for auth state.
1299
1296
  *
1300
- * Design philosophy: Keep lean, use getClient() for full API access.
1301
1297
  * This service provides:
1302
1298
  * - Reactive state (currentUser$, isAuthenticated$, challenge$)
1303
- * - Core auth methods as Observables (login, signup, logout, refresh)
1299
+ * - All core auth methods as Observables (login, signup, logout, refresh)
1300
+ * - Profile management (getProfile, updateProfile, changePassword)
1304
1301
  * - Challenge flow methods (respondToChallenge, resendCode)
1305
- * - Escape hatch via getClient() for all other operations
1302
+ * - MFA management (getMfaStatus, setupMfaDevice, etc.)
1303
+ * - Social authentication and account linking
1304
+ * - Device trust management
1305
+ * - Audit history
1306
1306
  *
1307
1307
  * @example
1308
1308
  * ```typescript
@@ -1315,8 +1315,12 @@ declare class NAuthClient {
1315
1315
  * // Auth operations
1316
1316
  * this.auth.login(email, password).subscribe(response => ...);
1317
1317
  *
1318
- * // Advanced operations via client
1319
- * this.auth.getClient().getMfaStatus().then(status => ...);
1318
+ * // Profile management
1319
+ * this.auth.changePassword(oldPassword, newPassword).subscribe(() => ...);
1320
+ * this.auth.updateProfile({ firstName: 'John' }).subscribe(user => ...);
1321
+ *
1322
+ * // MFA operations
1323
+ * this.auth.getMfaStatus().subscribe(status => ...);
1320
1324
  * ```
1321
1325
  */
1322
1326
  declare class AuthService {
@@ -1409,6 +1413,55 @@ declare class AuthService {
1409
1413
  * Confirm a password reset code and set a new password.
1410
1414
  */
1411
1415
  confirmForgotPassword(identifier: string, code: string, newPassword: string): Observable<ConfirmForgotPasswordResponse>;
1416
+ /**
1417
+ * Change user password (requires current password).
1418
+ *
1419
+ * @param oldPassword - Current password
1420
+ * @param newPassword - New password (must meet requirements)
1421
+ * @returns Observable that completes when password is changed
1422
+ *
1423
+ * @example
1424
+ * ```typescript
1425
+ * this.auth.changePassword('oldPassword123', 'newSecurePassword456!').subscribe({
1426
+ * next: () => console.log('Password changed successfully'),
1427
+ * error: (err) => console.error('Failed to change password:', err)
1428
+ * });
1429
+ * ```
1430
+ */
1431
+ changePassword(oldPassword: string, newPassword: string): Observable<void>;
1432
+ /**
1433
+ * Request password change (must change on next login).
1434
+ *
1435
+ * @returns Observable that completes when request is sent
1436
+ */
1437
+ requestPasswordChange(): Observable<void>;
1438
+ /**
1439
+ * Get current user profile.
1440
+ *
1441
+ * @returns Observable of current user profile
1442
+ *
1443
+ * @example
1444
+ * ```typescript
1445
+ * this.auth.getProfile().subscribe(user => {
1446
+ * console.log('User profile:', user);
1447
+ * });
1448
+ * ```
1449
+ */
1450
+ getProfile(): Observable<AuthUser>;
1451
+ /**
1452
+ * Update user profile.
1453
+ *
1454
+ * @param updates - Profile fields to update
1455
+ * @returns Observable of updated user profile
1456
+ *
1457
+ * @example
1458
+ * ```typescript
1459
+ * this.auth.updateProfile({ firstName: 'John', lastName: 'Doe' }).subscribe(user => {
1460
+ * console.log('Profile updated:', user);
1461
+ * });
1462
+ * ```
1463
+ */
1464
+ updateProfile(updates: UpdateProfileRequest): Observable<AuthUser>;
1412
1465
  /**
1413
1466
  * Respond to a challenge (VERIFY_EMAIL, VERIFY_PHONE, MFA_REQUIRED, etc.).
1414
1467
  */
@@ -1447,38 +1500,160 @@ declare class AuthService {
1447
1500
  clearChallenge(): Observable<void>;
1448
1501
  /**
1449
1502
  * Initiate social OAuth login flow.
1450
- * Redirects to OAuth provider with automatic state management.
1503
+ * Redirects the browser to backend `/auth/social/:provider/redirect`.
1451
1504
  */
1452
- loginWithSocial(provider: SocialProvider, options?: {
1453
- redirectUri?: string;
1454
- }): Promise<void>;
1505
+ loginWithSocial(provider: SocialProvider, options?: SocialLoginOptions): Promise<void>;
1455
1506
  /**
1456
- * Get social auth URL to redirect user for OAuth (low-level API).
1507
+ * Exchange an exchangeToken (from redirect callback URL) into an AuthResponse.
1508
+ *
1509
+ * Used for `tokenDelivery: 'json'` or hybrid flows where the backend redirects back
1510
+ * with `exchangeToken` instead of setting cookies.
1511
+ *
1512
+ * @param exchangeToken - One-time exchange token from the callback URL
1513
+ * @returns Observable of AuthResponse
1514
+ */
1515
+ exchangeSocialRedirect(exchangeToken: string): Observable<AuthResponse>;
1516
+ /**
1517
+ * Verify native social token (mobile).
1518
+ *
1519
+ * @param request - Social verification request with provider and token
1520
+ * @returns Observable of AuthResponse
1521
+ */
1522
+ verifyNativeSocial(request: SocialVerifyRequest): Observable<AuthResponse>;
1523
+ /**
1524
+ * Get linked social accounts.
1525
+ *
1526
+ * @returns Observable of linked accounts response
1457
1527
  */
1458
- getSocialAuthUrl(provider: string, redirectUri?: string): Observable<{
1459
- url: string;
1528
+ getLinkedAccounts(): Observable<LinkedAccountsResponse>;
1529
+ /**
1530
+ * Link social account.
1531
+ *
1532
+ * @param provider - Social provider to link
1533
+ * @param code - OAuth authorization code
1534
+ * @param state - OAuth state parameter
1535
+ * @returns Observable with success message
1536
+ */
1537
+ linkSocialAccount(provider: string, code: string, state: string): Observable<{
1538
+ message: string;
1539
+ }>;
1540
+ /**
1541
+ * Unlink social account.
1542
+ *
1543
+ * @param provider - Social provider to unlink
1544
+ * @returns Observable with success message
1545
+ */
1546
+ unlinkSocialAccount(provider: string): Observable<{
1547
+ message: string;
1548
+ }>;
1549
+ /**
1550
+ * Get MFA status for the current user.
1551
+ *
1552
+ * @returns Observable of MFA status
1553
+ */
1554
+ getMfaStatus(): Observable<MFAStatus>;
1555
+ /**
1556
+ * Get MFA devices for the current user.
1557
+ *
1558
+ * @returns Observable of MFA devices array
1559
+ */
1560
+ getMfaDevices(): Observable<MFADevice[]>;
1561
+ /**
1562
+ * Setup MFA device (authenticated user).
1563
+ *
1564
+ * @param method - MFA method to set up
1565
+ * @returns Observable of setup data
1566
+ */
1567
+ setupMfaDevice(method: string): Observable<unknown>;
1568
+ /**
1569
+ * Verify MFA setup (authenticated user).
1570
+ *
1571
+ * @param method - MFA method
1572
+ * @param setupData - Setup data from setupMfaDevice
1573
+ * @param deviceName - Optional device name
1574
+ * @returns Observable with device ID
1575
+ */
1576
+ verifyMfaSetup(method: string, setupData: Record<string, unknown>, deviceName?: string): Observable<{
1577
+ deviceId: number;
1578
+ }>;
1579
+ /**
1580
+ * Remove MFA device.
1581
+ *
1582
+ * @param method - MFA method to remove
1583
+ * @returns Observable with success message
1584
+ */
1585
+ removeMfaDevice(method: string): Observable<{
1586
+ message: string;
1587
+ }>;
1588
+ /**
1589
+ * Set preferred MFA method.
1590
+ *
1591
+ * @param method - Device method to set as preferred ('totp', 'sms', 'email', or 'passkey')
1592
+ * @returns Observable with success message
1593
+ */
1594
+ setPreferredMfaMethod(method: 'totp' | 'sms' | 'email' | 'passkey'): Observable<{
1595
+ message: string;
1460
1596
  }>;
1461
1597
  /**
1462
- * Handle social auth callback (low-level API).
1598
+ * Generate backup codes.
1599
+ *
1600
+ * @returns Observable of backup codes array
1601
+ */
1602
+ generateBackupCodes(): Observable<string[]>;
1603
+ /**
1604
+ * Set MFA exemption (admin/test scenarios).
1605
+ *
1606
+ * @param exempt - Whether to exempt user from MFA
1607
+ * @param reason - Optional reason for exemption
1608
+ * @returns Observable that completes when exemption is set
1609
+ */
1610
+ setMfaExemption(exempt: boolean, reason?: string): Observable<void>;
1611
+ /**
1612
+ * Trust current device.
1613
+ *
1614
+ * @returns Observable with device token
1463
1615
  */
1464
- handleSocialCallback(provider: string, code: string, state: string): Observable<AuthResponse>;
1616
+ trustDevice(): Observable<{
1617
+ deviceToken: string;
1618
+ }>;
1619
+ /**
1620
+ * Check if the current device is trusted.
1621
+ *
1622
+ * @returns Observable with trusted status
1623
+ */
1624
+ isTrustedDevice(): Observable<{
1625
+ trusted: boolean;
1626
+ }>;
1627
+ /**
1628
+ * Get paginated audit history for the current user.
1629
+ *
1630
+ * @param params - Query parameters for filtering and pagination
1631
+ * @returns Observable of audit history response
1632
+ *
1633
+ * @example
1634
+ * ```typescript
1635
+ * this.auth.getAuditHistory({ page: 1, limit: 20, eventType: 'LOGIN_SUCCESS' }).subscribe(history => {
1636
+ * console.log('Audit history:', history);
1637
+ * });
1638
+ * ```
1639
+ */
1640
+ getAuditHistory(params?: Record<string, string | number | boolean>): Observable<AuditHistoryResponse>;
1465
1641
  /**
1466
1642
  * Expose underlying NAuthClient for advanced scenarios.
1467
1643
  *
1468
- * Use this for operations not directly exposed by this service:
1469
- * - Profile management (getProfile, updateProfile)
1470
- * - MFA management (getMfaStatus, setupMfaDevice, etc.)
1471
- * - Social account linking (linkSocialAccount, unlinkSocialAccount)
1472
- * - Audit history (getAuditHistory)
1473
- * - Device trust (trustDevice)
1644
+ * @deprecated All core functionality is now exposed directly on AuthService as Observables.
1645
+ * Use the direct methods on AuthService instead (e.g., `auth.changePassword()` instead of `auth.getClient().changePassword()`).
1646
+ * This method is kept for backward compatibility only and may be removed in a future version.
1647
+ *
1648
+ * @returns The underlying NAuthClient instance
1474
1649
  *
1475
1650
  * @example
1476
1651
  * ```typescript
1477
- * // Get MFA status
1652
+ * // Deprecated - use direct methods instead
1478
1653
  * const status = await this.auth.getClient().getMfaStatus();
1479
1654
  *
1480
- * // Update profile
1481
- * const user = await this.auth.getClient().updateProfile({ firstName: 'John' });
1655
+ * // Preferred - use Observable-based methods
1656
+ * this.auth.getMfaStatus().subscribe(status => ...);
1482
1657
  * ```
1483
1658
  */
1484
1659
  getClient(): NAuthClient;
@@ -1572,54 +1747,29 @@ declare class AuthGuard {
1572
1747
  }
1573
1748
 
1574
1749
  /**
1575
- * OAuth callback route guard.
1576
- *
1577
- * Drop-in guard that automatically processes OAuth callbacks and redirects appropriately.
1578
- * Place this guard on your `/auth/callback` route to handle social authentication.
1750
+ * Social redirect callback route guard.
1579
1751
  *
1580
- * The guard:
1581
- * - Auto-detects OAuth callback parameters (provider, code, state)
1582
- * - Completes authentication via backend
1583
- * - Redirects using window.location (works in browser, Capacitor, SSR-safe)
1752
+ * This guard supports the redirect-first social flow where the backend redirects
1753
+ * back to the frontend with:
1754
+ * - `appState` (always optional)
1755
+ * - `exchangeToken` (present for json/hybrid flows, and for cookie flows that return a challenge)
1756
+ * - `error` / `error_description` (provider errors)
1584
1757
  *
1585
- * Configure redirect URLs in `NAUTH_CLIENT_CONFIG.redirects`.
1758
+ * Behavior:
1759
+ * - If `exchangeToken` exists: exchanges it via backend and redirects to success or challenge routes.
1760
+ * - If no `exchangeToken`: allow the route to activate so the app can display `appState`.
1761
+ * - If `error` exists: redirects to oauthError route.
1586
1762
  *
1587
1763
  * @example
1588
1764
  * ```typescript
1589
- * // app.routes.ts
1590
- * import { oauthCallbackGuard } from '@nauth-toolkit/client/angular';
1765
+ * import { socialRedirectCallbackGuard } from '@nauth-toolkit/client/angular';
1591
1766
  *
1592
1767
  * export const routes: Routes = [
1593
- * {
1594
- * path: 'auth/callback',
1595
- * canActivate: [oauthCallbackGuard],
1596
- * redirectTo: '/', // Fallback - guard handles redirect
1597
- * },
1768
+ * { path: 'auth/callback', canActivate: [socialRedirectCallbackGuard], component: CallbackComponent },
1598
1769
  * ];
1599
1770
  * ```
1600
- *
1601
- * @example
1602
- * ```typescript
1603
- * // app.config.ts - Configure redirect URLs
1604
- * import { NAUTH_CLIENT_CONFIG } from '@nauth-toolkit/client/angular';
1605
- *
1606
- * providers: [
1607
- * {
1608
- * provide: NAUTH_CLIENT_CONFIG,
1609
- * useValue: {
1610
- * baseUrl: 'https://api.example.com/auth',
1611
- * tokenDelivery: 'cookies',
1612
- * redirects: {
1613
- * success: '/home', // Common redirect for all successful auth
1614
- * oauthError: '/login',
1615
- * challengeBase: '/auth/challenge',
1616
- * },
1617
- * },
1618
- * }
1619
- * ]
1620
- * ```
1621
1771
  */
1622
- declare const oauthCallbackGuard: CanActivateFn;
1772
+ declare const socialRedirectCallbackGuard: CanActivateFn;
1623
1773
 
1624
1774
  /**
1625
1775
  * NgModule wrapper to provide configuration and interceptor.
@@ -1665,4 +1815,4 @@ declare class AngularHttpAdapter implements HttpAdapter {
1665
1815
  request<T>(config: HttpRequest): Promise<HttpResponse<T>>;
1666
1816
  }
1667
1817
 
1668
- export { AngularHttpAdapter, AuthChallenge, type AuthEvent, type AuthEventListener, type AuthEventType, AuthGuard, AuthInterceptor, type AuthResponse, AuthService, type AuthUser, type ChallengeResponse, type HttpAdapter, type MFADeviceMethod, type MFAMethod, type MFAStatus, NAUTH_CLIENT_CONFIG, type NAuthClientConfig, NAuthModule, type SocialProvider, type TokenDeliveryMode, type TokenResponse, authGuard, authInterceptor, oauthCallbackGuard };
1818
+ export { AngularHttpAdapter, AuthChallenge, type AuthEvent, type AuthEventListener, type AuthEventType, AuthGuard, AuthInterceptor, type AuthResponse, AuthService, type AuthUser, type ChallengeResponse, type HttpAdapter, type MFADeviceMethod, type MFAMethod, type MFAStatus, NAUTH_CLIENT_CONFIG, type NAuthClientConfig, NAuthModule, type SocialProvider, type TokenDeliveryMode, type TokenResponse, authGuard, authInterceptor, socialRedirectCallbackGuard };