@opensourcekd/ng-common-libs 2.0.9 → 2.0.11

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.
package/dist/index.d.ts CHANGED
@@ -198,6 +198,10 @@ declare function setStorageItem(key: string, value: string, storageType?: 'local
198
198
  */
199
199
  declare function removeStorageItem(key: string, storageType?: 'localStorage' | 'sessionStorage'): void;
200
200
 
201
+ /**
202
+ * Type definitions for AuthService
203
+ * Framework-agnostic interfaces for authentication state management
204
+ */
201
205
  /**
202
206
  * User information from ID token
203
207
  * Standard OIDC claims compatible with Auth0
@@ -305,19 +309,88 @@ interface StorageKeys {
305
309
  USER_INFO: string;
306
310
  DECODED_TOKEN: string;
307
311
  }
312
+
313
+ /**
314
+ * Decode a JWT access token and store its payload in storage
315
+ *
316
+ * Note: This only decodes the JWT structure without verifying the signature.
317
+ * The token signature is already validated by the Auth0 SDK when obtained.
318
+ * The stored payload is for informational use only (e.g. checking expiration,
319
+ * reading scopes). Do NOT use it for authorization decisions — always validate
320
+ * on the backend.
321
+ *
322
+ * @param token - Raw JWT access token string
323
+ * @param storageKeys - Storage key names configuration
324
+ * @param storageConfig - Storage type (localStorage / sessionStorage) configuration
325
+ */
326
+ declare function decodeAndStoreToken(token: string, storageKeys: StorageKeys, storageConfig: StorageConfig): void;
327
+ /**
328
+ * Retrieve and parse the decoded token payload from storage
329
+ *
330
+ * Note: This data is for informational purposes only (e.g. checking expiration,
331
+ * viewing scopes). Do NOT use it for authorization decisions — always validate
332
+ * permissions on the backend.
333
+ *
334
+ * @param storageKeys - Storage key names configuration
335
+ * @param storageConfig - Storage type (localStorage / sessionStorage) configuration
336
+ * @returns Decoded {@link TokenPayload} or `null` if not present or unparseable
337
+ */
338
+ declare function getDecodedToken(storageKeys: StorageKeys, storageConfig: StorageConfig): TokenPayload | null;
339
+
340
+ /**
341
+ * User data extraction utilities
342
+ * Pure functions for parsing user claims and constructing user data objects
343
+ */
344
+
345
+ /**
346
+ * Standard OIDC and JWT claims excluded from custom/namespaced claim detection
347
+ */
348
+ declare const STANDARD_JWT_CLAIMS: readonly string[];
349
+ /**
350
+ * Determine whether a claim key is a namespaced Auth0 custom claim
351
+ * @param key - Claim key to inspect
352
+ * @returns `true` if the key starts with `http://` or `https://`
353
+ */
354
+ declare function isNamespacedClaim(key: string): boolean;
355
+ /**
356
+ * Extract namespaced (Auth0 custom) claim keys from a user info object
357
+ * @param user - {@link UserInfo} object to inspect
358
+ * @returns Array of claim keys that are URL-namespaced
359
+ */
360
+ declare function getCustomClaims(user: UserInfo): string[];
361
+ /**
362
+ * Resolve the first matching primitive claim value from a {@link UserInfo} object
363
+ *
364
+ * Checks direct claims first, then falls back to namespaced (Auth0 custom) claims
365
+ * whose keys contain the requested name as a substring.
366
+ *
367
+ * @param userInfo - The user info object to search
368
+ * @param claimNames - Single claim name or ordered array of names to check
369
+ * @param defaultValue - Value to return when no matching claim is found
370
+ * @returns Resolved string value or `defaultValue`
371
+ * @example
372
+ * const role = extractClaimValue(userInfo, ['role', 'user_role'], 'user');
373
+ */
374
+ declare function extractClaimValue(userInfo: UserInfo, claimNames: string | string[], defaultValue: string): string;
375
+ /**
376
+ * Build a simplified {@link UserData} object from a full {@link UserInfo} object
377
+ * @param userInfo - Full user info from the ID token
378
+ * @returns Simplified user data with id, name, email, role, and org
379
+ */
380
+ declare function buildUserData(userInfo: UserInfo): UserData;
381
+
308
382
  /**
309
383
  * Pure TypeScript Authentication Service for Auth0 integration
310
- * Framework-agnostic - works with any JavaScript framework (Angular, React, Vue, etc.)
384
+ * Framework-agnostic works with any JavaScript framework (Angular, React, Vue, etc.)
311
385
  *
312
- * Handles login, logout, token management, and user session
313
- * Uses configurable storage (sessionStorage/localStorage) for sensitive data
314
- * Emits authentication events via EventBus for cross-application communication
386
+ * Handles login, logout, token management, and user session.
387
+ * Uses configurable storage (sessionStorage/localStorage) for sensitive data.
388
+ * Emits authentication events via EventBus for cross-application communication.
315
389
  *
316
390
  * @example
317
391
  * ```typescript
318
392
  * import { AuthService, EventBus } from '@opensourcekd/ng-common-libs';
319
393
  *
320
- * // Create instances
321
394
  * const eventBus = new EventBus();
322
395
  * const authConfig = {
323
396
  * domain: 'your-domain.auth0.com',
@@ -328,25 +401,23 @@ interface StorageKeys {
328
401
  * };
329
402
  * const authService = new AuthService(authConfig, eventBus);
330
403
  *
331
- * // Or create with an identifier
404
+ * // With an identifier for MFE scenarios
332
405
  * const authService = new AuthService(authConfig, eventBus, undefined, undefined, { id: 'MFE' });
333
406
  *
334
- * // Use the service
335
407
  * await authService.login();
336
408
  * const user = authService.getUser();
337
409
  * const token = await authService.getToken();
338
- *
339
- * // Get the identifier
340
410
  * const id = authService.getId(); // 'MFE' or undefined
341
411
  * ```
342
412
  */
343
413
  declare class AuthService {
344
- private readonly STANDARD_JWT_CLAIMS;
345
414
  private auth0Client;
346
415
  private initializationPromise;
416
+ /** Remains false if callback processing fails, allowing the callback to be retried. */
347
417
  private callbackHandled;
348
418
  private callbackPromise;
349
419
  private userSubject;
420
+ /** Observable stream of the currently authenticated user */
350
421
  user$: Observable<UserInfo | null>;
351
422
  private config;
352
423
  private storageConfig;
@@ -355,145 +426,169 @@ declare class AuthService {
355
426
  private id?;
356
427
  /**
357
428
  * Create a new AuthService instance
358
- * @param config - Auth0 configuration
429
+ * @param config - Auth0 configuration (domain, clientId, redirectUri, etc.)
359
430
  * @param eventBus - EventBus instance for emitting auth events
360
- * @param storageConfig - Storage configuration (optional, defaults to sessionStorage)
361
- * @param storageKeys - Storage keys (optional, defaults to standard keys)
362
- * @param options - Optional configuration with an id to identify the instance
431
+ * @param storageConfig - Storage configuration (defaults to sessionStorage for both token and user)
432
+ * @param storageKeys - Storage key names (defaults to standard auth0_* keys)
433
+ * @param options - Optional settings; supply `id` to label this instance in MFE scenarios
363
434
  */
364
435
  constructor(config: Auth0Config, eventBus: EventBus, storageConfig?: StorageConfig, storageKeys?: StorageKeys, options?: AuthServiceOptions);
365
436
  /**
366
437
  * Get the identifier of this AuthService instance
367
- * @returns The id if provided during initialization, undefined otherwise
438
+ * @returns The id supplied via options during construction, or `undefined`
368
439
  */
369
440
  getId(): string | undefined;
370
441
  /**
371
- * Get effective audience value (with fallback to defaultAudience)
372
- * @private
442
+ * Resolve the effective audience value, falling back to defaultAudience when audience is unset
443
+ * @returns The audience string, or `undefined` if neither field is set
373
444
  */
374
445
  private getEffectiveAudience;
375
446
  /**
376
- * Initialize Auth0 client
447
+ * Initialize the Auth0 SPA client
448
+ * @throws {Error} When required config fields (domain, clientId) are missing
377
449
  */
378
450
  private initializeAuth0;
379
451
  /**
380
- * Ensure Auth0 client is initialized before use
452
+ * Ensure the Auth0 client instance is created, without triggering callback detection.
453
+ * Used internally by {@link handleCallback} to avoid a circular async dependency:
454
+ * `ensureInitialized` → `checkAndHandleCallback` → `handleCallback` → `ensureInitialized`.
455
+ * @throws {Error} When the Auth0 client fails to initialize
456
+ */
457
+ private ensureAuth0Client;
458
+ /**
459
+ * Ensure the Auth0 client is initialized before use
460
+ * Lazy-initializes on the first call and auto-handles OAuth callbacks when detected
461
+ * @throws {Error} When the Auth0 client fails to initialize
381
462
  */
382
463
  private ensureInitialized;
383
464
  /**
384
- * Check for OAuth callback parameters in URL and auto-handle if present
385
- * Note: The Auth0 SDK's handleRedirectCallback() validates the state parameter
386
- * to prevent CSRF attacks. This method only checks for the presence of callback
387
- * parameters before delegating to the Auth0 SDK for secure processing.
465
+ * Check for OAuth callback parameters in the URL and auto-handle them
466
+ *
467
+ * The Auth0 SDK's `handleRedirectCallback` validates the `state` parameter
468
+ * to prevent CSRF attacks. This method only detects presence of callback
469
+ * params before delegating securely to the SDK.
470
+ *
471
+ * Uses an async IIFE to store the in-flight promise for concurrency deduplication
472
+ * (concurrent callers await the same promise) while still using async/await
473
+ * internally instead of `.then()/.catch()` chains.
388
474
  */
389
475
  private checkAndHandleCallback;
390
476
  /**
391
- * Login with Auth0
477
+ * Redirect the user to Auth0 Universal Login
478
+ * @param user - Optional username hint (for logging/debugging only)
479
+ * @param options - Optional invitation or organization parameters
480
+ * @throws {Error} When the Auth0 redirect fails
392
481
  */
393
482
  login(user?: string, options?: {
394
483
  invitation?: string;
395
484
  organization?: string;
396
485
  }): Promise<void>;
397
486
  /**
398
- * Handle OAuth2 callback after successful authorization
487
+ * Handle the OAuth2 redirect callback after successful authorization
488
+ * Stores the user info and access token, then cleans up the callback URL
489
+ *
490
+ * Uses {@link ensureAuth0Client} (not {@link ensureInitialized}) to avoid a circular
491
+ * async dependency: `ensureInitialized` → `checkAndHandleCallback` → `handleCallback`
492
+ * → `ensureInitialized`. Only the Auth0 client instance is needed here.
493
+ * @returns {@link CallbackResult} with `success` flag and optional `appState`
399
494
  */
400
495
  handleCallback(): Promise<CallbackResult>;
401
496
  /**
402
- * Log all user claims for debugging
403
- */
404
- private logUserClaims;
405
- private logStandardClaims;
406
- private logClaims;
407
- private getCustomClaims;
408
- private getAdditionalClaims;
409
- private isNamespacedClaim;
410
- /**
411
- * Logout user and clear authentication state
497
+ * Log the user out, clear all stored auth data, and redirect to the logout URI
498
+ *
499
+ * Uses {@link ensureAuth0Client} (not {@link ensureInitialized}) to avoid triggering
500
+ * callback detection during logout. Calling `ensureInitialized` here would invoke
501
+ * `checkAndHandleCallback`, which re-authenticates the user if callback URL params
502
+ * are present, causing them to be sent back to Auth0 instead of the logout URI.
412
503
  */
413
504
  logout(): Promise<void>;
414
505
  /**
415
- * Get current access token
506
+ * Get the current access token asynchronously
507
+ * Returns from storage first; falls back to a silent Auth0 token refresh
508
+ * @returns The access token string, or `null` on failure
416
509
  */
417
510
  getToken(): Promise<string | null>;
418
511
  /**
419
- * Get current access token synchronously from storage only
512
+ * Get the current access token synchronously from storage only
513
+ * @returns The stored token string, or `null` if not present
420
514
  */
421
515
  getTokenSync(): string | null;
422
516
  /**
423
- * Set access token in storage and emit event
424
- */
425
- private setToken;
426
- /**
427
- * Decode JWT token and store its payload
428
- * Note: This only decodes the JWT structure without verifying the signature.
429
- * The token signature is already validated by Auth0 SDK when obtained.
430
- * This decoded data is for informational purposes (e.g., checking expiration, viewing scopes).
431
- * Do NOT use decoded token data for authorization decisions - always validate on the backend.
432
- */
433
- private decodeAndStoreToken;
434
- /**
435
- * Get decoded token payload from storage
436
- * Note: This data is for informational purposes only (checking expiration, viewing scopes, etc.).
437
- * Do NOT use this for authorization decisions - always validate permissions on the backend.
438
- * The token signature is validated by Auth0 SDK when the token is obtained.
517
+ * Get the decoded access token payload from storage
518
+ *
519
+ * Note: For informational use only (checking expiration, viewing scopes, etc.).
520
+ * Do NOT use for authorization decisions — always validate on the backend.
521
+ *
522
+ * @returns Decoded {@link TokenPayload} or `null` if not present
439
523
  */
440
524
  getDecodedToken(): TokenPayload | null;
441
525
  /**
442
- * Check if user is authenticated
526
+ * Check whether the user is authenticated via the Auth0 SDK
527
+ * @returns `true` if the Auth0 session is valid; falls back to storage check on error
443
528
  */
444
529
  isAuthenticated(): Promise<boolean>;
445
530
  /**
446
- * Check if user is authenticated synchronously
531
+ * Check whether the user is authenticated synchronously based on stored token presence
532
+ * @returns `true` when an access token exists in storage
447
533
  */
448
534
  isAuthenticatedSync(): boolean;
449
535
  /**
450
- * Get current user information
536
+ * Get the current authenticated user's info
537
+ * @returns {@link UserInfo} object or `null` if not authenticated
451
538
  */
452
539
  getUser(): UserInfo | null;
453
540
  /**
454
- * Get simplified user data from token
541
+ * Get a simplified view of the current user's data
542
+ * @returns {@link UserData} with id, name, email, role, and org — or `null` if not authenticated
455
543
  */
456
544
  getUserData(): UserData | null;
457
- private extractClaimValue;
458
545
  /**
459
- * Get user information from storage
546
+ * Read and parse user info from storage on initialization
547
+ * @returns Stored {@link UserInfo} or `null` if absent
460
548
  */
461
549
  private getUserInfoFromStorage;
462
550
  /**
463
- * Set user information in storage and update observable
551
+ * Persist user info to storage and update the user observable
552
+ * @param userInfo - The {@link UserInfo} object to store
464
553
  */
465
554
  private setUserInfo;
466
555
  /**
467
- * Emit authentication event for cross-application communication
556
+ * Persist the access token to storage, decode and cache its payload
557
+ * @param token - Raw JWT access token string
558
+ */
559
+ private setToken;
560
+ /**
561
+ * Emit an authentication event via the shared EventBus
562
+ * @param eventType - Short event type suffix (e.g. `'login_success'`, `'logout'`)
563
+ * @param payload - Arbitrary metadata payload, or `null`
468
564
  */
469
565
  private emitAuthEvent;
470
566
  /**
471
- * Clean up OAuth callback parameters from URL after successful authentication
472
- * Removes 'code' and 'state' parameters while preserving other query parameters
567
+ * Remove OAuth callback parameters (`code`, `state`) from the browser URL
568
+ * while preserving all other query parameters and the hash fragment.
569
+ * Uses `history.replaceState` to avoid adding an entry to browser history.
473
570
  */
474
571
  private cleanupCallbackUrl;
475
572
  }
476
573
  /**
477
- * Create AuthService instance using AUTH0_CONFIG
478
- * Helper function for creating AuthService with default configuration from AUTH0_CONFIG
574
+ * Create an {@link AuthService} instance pre-configured from the shared {@link AUTH0_CONFIG}
479
575
  *
480
- * Note: Make sure to call configureAuth0() before using this helper
576
+ * Note: Call {@link configureAuth0} before using this helper so that `AUTH0_CONFIG`
577
+ * is populated with the correct values for your environment.
481
578
  *
482
579
  * @param eventBus - EventBus instance for auth events
483
- * @returns Configured AuthService instance
580
+ * @returns Fully configured {@link AuthService} instance
484
581
  *
485
582
  * @example
486
583
  * ```typescript
487
584
  * import { createAuthService, EventBus, configureAuth0, APP_CONFIG } from '@opensourcekd/ng-common-libs';
488
585
  *
489
- * // Configure Auth0 first
490
586
  * configureAuth0({
491
587
  * domain: APP_CONFIG.auth0Domain,
492
588
  * clientId: APP_CONFIG.auth0ClientId,
493
589
  * audience: APP_CONFIG.apiUrl,
494
590
  * });
495
591
  *
496
- * // Create instances
497
592
  * const eventBus = new EventBus();
498
593
  * const authService = createAuthService(eventBus);
499
594
  * ```
@@ -699,5 +794,5 @@ declare class Logger {
699
794
  }): void;
700
795
  }
701
796
 
702
- export { APP_CONFIG, AUTH0_CONFIG, AuthService, EventBus, LogSeverity, Logger, STORAGE_CONFIG, STORAGE_KEYS, configureAuth0, createAuthService, getStorageItem, removeStorageItem, resetAuth0Config, setStorageItem };
797
+ export { APP_CONFIG, AUTH0_CONFIG, AuthService, EventBus, LogSeverity, Logger, STANDARD_JWT_CLAIMS, STORAGE_CONFIG, STORAGE_KEYS, buildUserData, configureAuth0, createAuthService, decodeAndStoreToken, extractClaimValue, getCustomClaims, getDecodedToken, getStorageItem, isNamespacedClaim, removeStorageItem, resetAuth0Config, setStorageItem };
703
798
  export type { AppState, Auth0Config, Auth0ConfigOptions, AuthServiceOptions, AuthorizationParams, CallbackResult, EventBusOptions, EventPayload, LogAttributes, LogRecord, LoggerOptions, StorageConfig, StorageKeys, TokenPayload, UserData, UserInfo };