@memberjunction/ng-auth-services 5.11.0 → 5.13.0
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mjexplorer-msal-provider.service.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/mjexplorer-msal-provider.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,SAAS,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAA6D,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE9I,OAAO,
|
|
1
|
+
{"version":3,"file":"mjexplorer-msal-provider.service.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/mjexplorer-msal-provider.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,SAAS,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAA6D,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE9I,OAAO,EAAuF,uBAAuB,EAAE,eAAe,EAAoB,MAAM,qBAAqB,CAAC;AAGtL,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EAEjB,kBAAkB,EACnB,MAAM,eAAe,CAAC;;AACvB;;;;;;GAMG;AACH,qBAIa,cAAe,SAAQ,UAAW,YAAW,SAAS;IA+C9C,IAAI,EAAE,WAAW;IAAE,OAAO,CAAC,oBAAoB;IA9ClE,MAAM,CAAC,QAAQ,CAAC,aAAa,UAAU;IACvC,QAAQ,CAAC,IAAI,UAAgC;IAE7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuB;IACpD,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAuC;IACjF,OAAO,CAAC,YAAY,CAA8B;IAElD;;;OAGG;IACH,MAAM,CAAC,sBAAsB,GAAI,aAAa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;;;;;;;;SAiCnE;gBAEiB,IAAI,EAAE,WAAW,EAAU,oBAAoB,EAAE,oBAAoB;IAYlF,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YASnB,sBAAsB;cAkEpB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBzE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAOvB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAUrC;;;;;OAKG;cACa,sBAAsB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAkDhE;;;;OAIG;cACa,wBAAwB,IAAI,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IA4C7E;;;;OAIG;cACa,uBAAuB,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAgB3E;;;;;;;OAOG;cACa,oBAAoB,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAsFnE;;;;;OAKG;IACH,SAAS,CAAC,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB;YAiHpD,iBAAiB;IAQ/B;;;;;;;;OAQG;IACH,OAAO,CAAC,YAAY;IAepB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAYhC;;;;;;OAMG;cACa,4BAA4B,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAqCtE;;;;;;OAMG;cACa,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBnD,iBAAiB,IAAI,MAAM,EAAE;IAI7B,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;IASlE,WAAW,IAAI,IAAI;yCAnoBR,cAAc;6CAAd,cAAc;CAyoB1B"}
|
|
@@ -10,7 +10,7 @@ import { RegisterClass } from '@memberjunction/global';
|
|
|
10
10
|
import { MJAuthBase } from '../mjexplorer-auth-base.service';
|
|
11
11
|
import { BehaviorSubject, Subject, filter, takeUntil } from 'rxjs';
|
|
12
12
|
import { MsalBroadcastService, MsalService, MSAL_INSTANCE, MSAL_GUARD_CONFIG, MSAL_INTERCEPTOR_CONFIG, MsalGuard } from '@azure/msal-angular';
|
|
13
|
-
import { CacheLookupPolicy, InteractionRequiredAuthError, InteractionStatus, PublicClientApplication, InteractionType, BrowserAuthError } from '@azure/msal-browser';
|
|
13
|
+
import { CacheLookupPolicy, ClientAuthError, InteractionRequiredAuthError, InteractionStatus, PublicClientApplication, InteractionType, BrowserAuthError } from '@azure/msal-browser';
|
|
14
14
|
import { LogError } from '@memberjunction/core';
|
|
15
15
|
import { AuthErrorType } from '../auth-types';
|
|
16
16
|
import * as i0 from "@angular/core";
|
|
@@ -353,7 +353,8 @@ let MJMSALProvider = class MJMSALProvider extends MJAuthBase {
|
|
|
353
353
|
'no_tokens_found',
|
|
354
354
|
'no_account_error',
|
|
355
355
|
'login_required',
|
|
356
|
-
'consent_required'
|
|
356
|
+
'consent_required',
|
|
357
|
+
'token_refresh_required' // ClientAuthError when cached token needs refresh
|
|
357
358
|
];
|
|
358
359
|
if (interactionRequiredCodes.includes(errorCode || '') || error instanceof InteractionRequiredAuthError) {
|
|
359
360
|
// Return INTERACTION_REQUIRED error - base class will call handleSessionExpiryInternal
|
|
@@ -392,6 +393,24 @@ let MJMSALProvider = class MJMSALProvider extends MJAuthBase {
|
|
|
392
393
|
userMessage: 'Additional authentication is required. Please log in again.'
|
|
393
394
|
};
|
|
394
395
|
}
|
|
396
|
+
// ClientAuthError — covers codes like token_refresh_required that are not
|
|
397
|
+
// surfaced through BrowserAuthError or InteractionRequiredAuthError.
|
|
398
|
+
if (error instanceof ClientAuthError) {
|
|
399
|
+
if (errorCode === 'token_refresh_required') {
|
|
400
|
+
return {
|
|
401
|
+
type: AuthErrorType.INTERACTION_REQUIRED,
|
|
402
|
+
message,
|
|
403
|
+
originalError: error,
|
|
404
|
+
userMessage: 'Your session has expired. Please log in again.'
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
return {
|
|
408
|
+
type: AuthErrorType.TOKEN_EXPIRED,
|
|
409
|
+
message,
|
|
410
|
+
originalError: error,
|
|
411
|
+
userMessage: 'Your session has expired. Please log in again.'
|
|
412
|
+
};
|
|
413
|
+
}
|
|
395
414
|
if (error instanceof BrowserAuthError) {
|
|
396
415
|
// Check specific error codes - MSAL 5.x codes
|
|
397
416
|
if (errorCode === 'user_cancelled' || message.includes('user cancelled')) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mjexplorer-msal-provider.service.js","sourceRoot":"","sources":["../../../src/lib/providers/mjexplorer-msal-provider.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, OnDestroy } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { MJAuthBase } from '../mjexplorer-auth-base.service';\nimport { BehaviorSubject, Observable, Subject, catchError, filter, from, map, of, throwError, takeUntil, take } from 'rxjs';\nimport { MsalBroadcastService, MsalService, MSAL_INSTANCE, MSAL_GUARD_CONFIG, MSAL_INTERCEPTOR_CONFIG, MsalGuard } from '@azure/msal-angular';\nimport { AccountInfo, AuthenticationResult } from '@azure/msal-common';\nimport { CacheLookupPolicy, InteractionRequiredAuthError, InteractionStatus, PublicClientApplication, InteractionType, BrowserAuthError } from '@azure/msal-browser';\nimport { LogError } from '@memberjunction/core';\nimport { AngularAuthProviderConfig } from '../IAuthProvider';\nimport {\n StandardUserInfo,\n StandardAuthToken,\n StandardAuthError,\n AuthErrorType,\n TokenRefreshResult\n} from '../auth-types';\n/**\n * MSAL (Microsoft Authentication Library) provider implementation - v3.0.0\n *\n * Implements the abstract methods from MJAuthBase to hide MSAL-specific details.\n * The key abstraction is that MSAL stores the JWT in AuthenticationResult.idToken,\n * but consumers never need to know this detail.\n */\n@Injectable({\n providedIn: 'root'\n})\n@RegisterClass(MJAuthBase, 'msal')\nexport class MJMSALProvider extends MJAuthBase implements OnDestroy {\n static readonly PROVIDER_TYPE = 'msal';\n readonly type = MJMSALProvider.PROVIDER_TYPE;\n\n private readonly _destroying$ = new Subject<void>();\n private readonly _initializationCompleted$ = new BehaviorSubject<boolean>(false);\n private _initPromise: Promise<void> | null = null;\n\n /**\n * Factory function to provide Angular dependencies required by MSAL\n * Stored as a static property for the factory to access without instantiation\n */\n static angularProviderFactory = (environment: Record<string, unknown>) => [\n {\n provide: MSAL_INSTANCE,\n useValue: new PublicClientApplication({\n auth: {\n clientId: environment['CLIENT_ID'] as string,\n authority: environment['CLIENT_AUTHORITY'] as string,\n redirectUri: window.location.origin,\n },\n cache: {\n cacheLocation: 'localStorage',\n },\n }),\n },\n {\n provide: MSAL_GUARD_CONFIG,\n useValue: {\n interactionType: InteractionType.Redirect,\n authRequest: {\n scopes: ['User.Read'],\n },\n },\n },\n {\n provide: MSAL_INTERCEPTOR_CONFIG,\n useValue: {\n interactionType: InteractionType.Redirect,\n protectedResourceMap: new Map([['https://graph.microsoft.com/v1.0/me', ['user.read']]]),\n },\n },\n MsalService,\n MsalGuard,\n MsalBroadcastService\n ];\n\n constructor(public auth: MsalService, private msalBroadcastService: MsalBroadcastService) {\n const config: AngularAuthProviderConfig = {\n name: MJMSALProvider.PROVIDER_TYPE,\n type: MJMSALProvider.PROVIDER_TYPE\n };\n super(config);\n }\n\n // ============================================================================\n // LIFECYCLE METHODS\n // ============================================================================\n\n async initialize(): Promise<void> {\n if (this._initPromise) {\n return this._initPromise;\n }\n\n this._initPromise = this._performInitialization();\n return this._initPromise;\n }\n\n private async _performInitialization(): Promise<void> {\n console.debug('[MSAL] Starting initialization...');\n await this.auth.instance.initialize();\n console.debug('[MSAL] MSAL instance initialized');\n\n // Handle redirect immediately after initialization\n const redirectResponse = await this.auth.instance.handleRedirectPromise();\n console.debug('[MSAL] Redirect response:', redirectResponse ? 'Found' : 'None');\n\n if (redirectResponse && redirectResponse.account) {\n // User just logged in via redirect\n console.debug('[MSAL] Processing redirect login');\n this.auth.instance.setActiveAccount(redirectResponse.account);\n this.updateAuthState(true);\n\n // Update user info from account\n const userInfo = this.mapMSALAccountToStandard(redirectResponse.account);\n this.updateUserInfo(userInfo);\n\n this._initializationCompleted$.next(true);\n console.debug('[MSAL] Initialization completed (redirect login)');\n } else {\n // Set active account if we have one from cache\n const accounts = this.auth.instance.getAllAccounts();\n console.debug('[MSAL] Cached accounts found:', accounts.length);\n\n if (accounts.length > 0) {\n console.debug('[MSAL] Restoring session from cached account:', accounts[0].username);\n this.auth.instance.setActiveAccount(accounts[0]);\n this.updateAuthState(true);\n\n // Update user info from cached account\n const userInfo = this.mapMSALAccountToStandard(accounts[0]);\n this.updateUserInfo(userInfo);\n\n this._initializationCompleted$.next(true);\n console.debug('[MSAL] Initialization completed (cached session restored)');\n } else {\n console.debug('[MSAL] No cached accounts, user needs to log in');\n }\n }\n\n // Subscribe to broadcast service for ongoing auth state changes\n this.msalBroadcastService.inProgress$\n .pipe(\n filter((status: InteractionStatus) => status === InteractionStatus.None),\n takeUntil(this._destroying$)\n )\n .subscribe(() => {\n const accounts = this.auth.instance.getAllAccounts();\n const isAuth = accounts.length > 0;\n\n this.updateAuthState(isAuth);\n\n if (isAuth) {\n this.auth.instance.setActiveAccount(accounts[0]);\n const userInfo = this.mapMSALAccountToStandard(accounts[0]);\n this.updateUserInfo(userInfo);\n } else {\n this.updateUserInfo(null);\n }\n\n this._initializationCompleted$.next(true);\n });\n }\n\n protected async loginInternal(options?: Record<string, unknown>): Promise<void> {\n await this.ensureInitialized();\n\n const silentRequest = {\n scopes: ['User.Read', 'email', 'profile'],\n ...options\n };\n\n return new Promise((resolve, reject) => {\n this.auth.loginRedirect(silentRequest).subscribe({\n next: () => {\n resolve();\n },\n error: (error) => {\n LogError(error);\n reject(error);\n }\n });\n });\n }\n\n async logout(): Promise<void> {\n await this.ensureInitialized();\n this.auth.logoutRedirect().subscribe(() => {\n // Logout will trigger a redirect\n });\n }\n\n async handleCallback(): Promise<void> {\n // MSAL Angular handles callbacks internally through its broadcast service\n // The handleRedirectPromise is called in initialize()\n await this.ensureInitialized();\n }\n\n // ============================================================================\n // ABSTRACT METHOD IMPLEMENTATIONS (v3.0.0)\n // ============================================================================\n\n /**\n * Extract ID token from MSAL's storage\n *\n * MSAL stores the JWT in AuthenticationResult.idToken\n * This is the key abstraction - consumers never need to know about MSAL's structure!\n */\n protected async extractIdTokenInternal(): Promise<string | null> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return null;\n }\n\n // First try to get cached token from account\n // This avoids unnecessary iframe calls that can timeout\n if (account.idToken) {\n // Check if token is expired or about to expire (within 5-minute buffer)\n // This prevents the race condition where proactive refresh hasn't completed\n // but the cached token is already expired\n if (this.isTokenValid(account.idToken, 300)) {\n return account.idToken;\n }\n\n // Token expired or near-expiry — force a silent refresh\n console.debug('[MSAL] Cached token expired or near-expiry, forcing silent refresh');\n try {\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read', 'email', 'profile'],\n account: account,\n forceRefresh: true\n });\n return response.idToken || null;\n } catch (refreshError) {\n console.warn('[MSAL] Silent refresh failed, returning expired cached token:', refreshError);\n // Fall through to existing cache-only acquisition below\n }\n }\n\n // If not in account, try silent token acquisition from cache only\n // Use CacheLookupPolicy.AccessToken to avoid iframe calls\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read', 'email', 'profile'],\n account: account,\n cacheLookupPolicy: CacheLookupPolicy.AccessToken\n });\n\n // MSAL-specific detail: JWT is in idToken property\n return response.idToken || null;\n } catch (error) {\n console.error('[MSAL] Error extracting ID token:', error);\n return null;\n }\n }\n\n /**\n * Extract complete token info from MSAL\n *\n * Maps MSAL's AuthenticationResult to StandardAuthToken\n */\n protected async extractTokenInfoInternal(): Promise<StandardAuthToken | null> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return null;\n }\n\n // Use cache-only lookup to avoid iframe timeouts during normal token extraction\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read', 'email', 'profile'],\n account: account,\n cacheLookupPolicy: CacheLookupPolicy.AccessToken\n });\n\n if (!response.idToken) {\n return null;\n }\n\n return {\n idToken: response.idToken,\n accessToken: response.accessToken,\n expiresAt: response.expiresOn ? response.expiresOn.getTime() : 0,\n scopes: response.scopes\n };\n } catch (error) {\n // If acquireTokenSilent fails (e.g., iframe timeout), try to use cached account data\n console.error('[MSAL] Error extracting token info:', error);\n\n const account = this.auth.instance.getActiveAccount();\n if (account?.idToken) {\n // Return basic token info from account if available\n return {\n idToken: account.idToken,\n expiresAt: 0, // Unknown from account alone\n scopes: []\n };\n }\n\n return null;\n }\n }\n\n /**\n * Extract user info from MSAL account\n *\n * Maps MSAL's AccountInfo structure to StandardUserInfo\n */\n protected async extractUserInfoInternal(): Promise<StandardUserInfo | null> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return null;\n }\n\n return this.mapMSALAccountToStandard(account);\n } catch (error) {\n console.error('[MSAL] Error extracting user info:', error);\n return null;\n }\n }\n\n /**\n * Refresh token using MSAL's silent token acquisition\n *\n * MSAL 5.x Best Practices:\n * - Pass account parameter for reliable silent acquisition\n * - Use CacheLookupPolicy.Default for efficient cache → refresh token → iframe chain\n * - Handle MSAL 5.x specific error codes (timed_out, no_tokens_found, etc.)\n */\n protected async refreshTokenInternal(): Promise<TokenRefreshResult> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return {\n success: false,\n error: {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message: 'No active account found',\n userMessage: 'You need to log in to continue.'\n }\n };\n }\n\n // MSAL 5.x: Pass account for reliable silent acquisition\n // Use Default policy for efficient cache → refresh token → iframe chain\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read', 'email', 'profile'],\n account: account,\n cacheLookupPolicy: CacheLookupPolicy.Default\n });\n\n if (!response.idToken) {\n return {\n success: false,\n error: {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message: 'Token refresh succeeded but no ID token returned',\n userMessage: 'Session refresh failed. Please log in again.'\n }\n };\n }\n\n const token: StandardAuthToken = {\n idToken: response.idToken,\n accessToken: response.accessToken,\n expiresAt: response.expiresOn ? response.expiresOn.getTime() : 0,\n scopes: response.scopes\n };\n\n return {\n success: true,\n token\n };\n } catch (error) {\n console.error('[MSAL] Token refresh failed:', error);\n\n // Handle MSAL 5.x error codes that require user interaction\n // - timed_out: MSAL 5.x iframe timeout (replaces monitor_window_timeout from 3.x)\n // - monitor_window_timeout: Legacy MSAL 3.x iframe timeout\n // - no_tokens_found: No cached tokens available\n // - no_account_error: Account not found in cache\n // - InteractionRequiredAuthError: Server requires user interaction\n const errorCode = (error as Record<string, unknown>)?.errorCode as string | undefined;\n const interactionRequiredCodes = [\n 'monitor_window_timeout',\n 'timed_out',\n 'no_tokens_found',\n 'no_account_error',\n 'login_required',\n 'consent_required'\n ];\n\n if (interactionRequiredCodes.includes(errorCode || '') || error instanceof InteractionRequiredAuthError) {\n // Return INTERACTION_REQUIRED error - base class will call handleSessionExpiryInternal\n return {\n success: false,\n error: {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message: `Silent token refresh failed - interaction required (${errorCode || 'unknown'})`,\n userMessage: 'Your session has expired. Redirecting to login...',\n originalError: error\n }\n };\n }\n\n return {\n success: false,\n error: this.classifyErrorInternal(error)\n };\n }\n }\n\n /**\n * Classify MSAL-specific errors into semantic types\n *\n * Maps MSAL error classes to AuthErrorType enum.\n * Updated for MSAL 5.x error codes.\n */\n protected classifyErrorInternal(error: unknown): StandardAuthError {\n const errorObj = error as Record<string, unknown>;\n const message = errorObj?.['message'] as string || 'Unknown error';\n const errorCode = errorObj?.['errorCode'] as string || '';\n\n // Check for specific MSAL error types\n if (error instanceof InteractionRequiredAuthError) {\n return {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message,\n originalError: error,\n userMessage: 'Additional authentication is required. Please log in again.'\n };\n }\n\n if (error instanceof BrowserAuthError) {\n // Check specific error codes - MSAL 5.x codes\n if (errorCode === 'user_cancelled' || message.includes('user cancelled')) {\n return {\n type: AuthErrorType.USER_CANCELLED,\n message,\n originalError: error,\n userMessage: 'Login was cancelled.'\n };\n }\n\n // MSAL 5.x timeout and session errors that require interaction\n const interactionRequiredCodes = [\n 'timed_out',\n 'monitor_window_timeout',\n 'no_tokens_found',\n 'no_account_error',\n 'login_required',\n 'consent_required'\n ];\n if (interactionRequiredCodes.includes(errorCode)) {\n return {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n return {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message,\n originalError: error,\n userMessage: 'Authentication error. Please log in again.'\n };\n }\n\n // Check message patterns\n if (message.includes('token') && message.includes('expired')) {\n return {\n type: AuthErrorType.TOKEN_EXPIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n if (message.includes('network') || message.includes('fetch')) {\n return {\n type: AuthErrorType.NETWORK_ERROR,\n message,\n originalError: error,\n userMessage: 'Network error. Please check your connection and try again.'\n };\n }\n\n if (message.includes('you need to be authorized')) {\n return {\n type: AuthErrorType.TOKEN_EXPIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n // Default to unknown error\n return {\n type: AuthErrorType.UNKNOWN_ERROR,\n message,\n originalError: error,\n userMessage: 'An unexpected error occurred. Please try again.'\n };\n }\n\n // ============================================================================\n // HELPER METHODS\n // ============================================================================\n\n private async ensureInitialized(): Promise<void> {\n if (!this._initPromise) {\n await this.initialize();\n } else if (!this._initializationCompleted$.value) {\n await this._initPromise;\n }\n }\n\n /**\n * Check if a JWT token is still valid with an optional buffer period.\n * Decodes the payload to read the `exp` claim without cryptographic verification\n * (expiry is a timing check, not an authenticity check).\n *\n * @param token - The JWT string to check\n * @param bufferSeconds - Number of seconds before actual expiry to consider the token invalid (default: 0)\n * @returns true if the token's exp claim is beyond (now + buffer), false otherwise\n */\n private isTokenValid(token: string, bufferSeconds: number = 0): boolean {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) {\n return false;\n }\n const payload = JSON.parse(atob(parts[1])) as { exp?: number };\n const expiresAtMs = (payload.exp ?? 0) * 1000;\n return expiresAtMs > Date.now() + (bufferSeconds * 1000);\n } catch {\n // If we can't decode the token, treat it as invalid\n return false;\n }\n }\n\n /**\n * Map MSAL AccountInfo to StandardUserInfo\n */\n private mapMSALAccountToStandard(account: AccountInfo): StandardUserInfo {\n return {\n id: account.localAccountId || account.homeAccountId,\n email: account.username || '',\n name: account.name || account.username || '',\n givenName: account.idTokenClaims?.['given_name'] as string,\n familyName: account.idTokenClaims?.['family_name'] as string,\n preferredUsername: account.username,\n emailVerified: true // MSAL doesn't provide this, assume true\n };\n }\n\n /**\n * Get profile picture URL from Microsoft Graph API\n *\n * MSAL requires fetching the photo from Microsoft Graph.\n * This is the key advantage of encapsulation - consumers don't need\n * to know about Graph API, they just call getProfilePictureUrl()!\n */\n protected async getProfilePictureUrlInternal(): Promise<string | null> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return null;\n }\n\n // Get access token for Microsoft Graph\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read'],\n account: account,\n forceRefresh: false\n });\n\n if (!response.accessToken) {\n return null;\n }\n\n // Fetch photo from Microsoft Graph\n const graphResponse = await fetch('https://graph.microsoft.com/v1.0/me/photo/$value', {\n headers: { 'Authorization': `Bearer ${response.accessToken}` }\n });\n\n if (graphResponse.ok) {\n const blob = await graphResponse.blob();\n return URL.createObjectURL(blob);\n }\n\n return null;\n } catch (error) {\n console.error('[MSAL] Error getting profile picture:', error);\n return null;\n }\n }\n\n /**\n * Handle session expiry by redirecting to Microsoft login\n *\n * This method is called by the base class when silent token refresh fails\n * with INTERACTION_REQUIRED error. It redirects to Microsoft login and never returns.\n * After authentication, the app will reload and re-initialize with a fresh token.\n */\n protected async handleSessionExpiryInternal(): Promise<void> {\n console.debug('[MSAL] Redirecting to Microsoft login for re-authentication...');\n\n // Initiate redirect authentication - page will navigate away\n this.auth.loginRedirect({\n scopes: ['User.Read', 'email', 'profile'],\n prompt: 'select_account'\n }).subscribe({\n error: (redirectError) => {\n console.error('[MSAL] Redirect initiation failed:', redirectError);\n }\n });\n\n // Return a promise that never resolves - page will navigate before this matters\n return new Promise<void>(() => {});\n }\n\n // ============================================================================\n // CONFIGURATION\n // ============================================================================\n\n override getRequiredConfig(): string[] {\n return ['clientId', 'tenantId'];\n }\n\n override validateConfig(_config: Record<string, unknown>): boolean {\n // MSAL configuration is handled by Angular module providers\n return true;\n }\n\n // ============================================================================\n // CLEANUP\n // ============================================================================\n\n ngOnDestroy(): void {\n this._destroying$.next();\n this._destroying$.complete();\n this._initPromise = null;\n this._initializationCompleted$.complete();\n }\n}"]}
|
|
1
|
+
{"version":3,"file":"mjexplorer-msal-provider.service.js","sourceRoot":"","sources":["../../../src/lib/providers/mjexplorer-msal-provider.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, OnDestroy } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { MJAuthBase } from '../mjexplorer-auth-base.service';\nimport { BehaviorSubject, Observable, Subject, catchError, filter, from, map, of, throwError, takeUntil, take } from 'rxjs';\nimport { MsalBroadcastService, MsalService, MSAL_INSTANCE, MSAL_GUARD_CONFIG, MSAL_INTERCEPTOR_CONFIG, MsalGuard } from '@azure/msal-angular';\nimport { AccountInfo, AuthenticationResult } from '@azure/msal-common';\nimport { CacheLookupPolicy, ClientAuthError, InteractionRequiredAuthError, InteractionStatus, PublicClientApplication, InteractionType, BrowserAuthError } from '@azure/msal-browser';\nimport { LogError } from '@memberjunction/core';\nimport { AngularAuthProviderConfig } from '../IAuthProvider';\nimport {\n StandardUserInfo,\n StandardAuthToken,\n StandardAuthError,\n AuthErrorType,\n TokenRefreshResult\n} from '../auth-types';\n/**\n * MSAL (Microsoft Authentication Library) provider implementation - v3.0.0\n *\n * Implements the abstract methods from MJAuthBase to hide MSAL-specific details.\n * The key abstraction is that MSAL stores the JWT in AuthenticationResult.idToken,\n * but consumers never need to know this detail.\n */\n@Injectable({\n providedIn: 'root'\n})\n@RegisterClass(MJAuthBase, 'msal')\nexport class MJMSALProvider extends MJAuthBase implements OnDestroy {\n static readonly PROVIDER_TYPE = 'msal';\n readonly type = MJMSALProvider.PROVIDER_TYPE;\n\n private readonly _destroying$ = new Subject<void>();\n private readonly _initializationCompleted$ = new BehaviorSubject<boolean>(false);\n private _initPromise: Promise<void> | null = null;\n\n /**\n * Factory function to provide Angular dependencies required by MSAL\n * Stored as a static property for the factory to access without instantiation\n */\n static angularProviderFactory = (environment: Record<string, unknown>) => [\n {\n provide: MSAL_INSTANCE,\n useValue: new PublicClientApplication({\n auth: {\n clientId: environment['CLIENT_ID'] as string,\n authority: environment['CLIENT_AUTHORITY'] as string,\n redirectUri: window.location.origin,\n },\n cache: {\n cacheLocation: 'localStorage',\n },\n }),\n },\n {\n provide: MSAL_GUARD_CONFIG,\n useValue: {\n interactionType: InteractionType.Redirect,\n authRequest: {\n scopes: ['User.Read'],\n },\n },\n },\n {\n provide: MSAL_INTERCEPTOR_CONFIG,\n useValue: {\n interactionType: InteractionType.Redirect,\n protectedResourceMap: new Map([['https://graph.microsoft.com/v1.0/me', ['user.read']]]),\n },\n },\n MsalService,\n MsalGuard,\n MsalBroadcastService\n ];\n\n constructor(public auth: MsalService, private msalBroadcastService: MsalBroadcastService) {\n const config: AngularAuthProviderConfig = {\n name: MJMSALProvider.PROVIDER_TYPE,\n type: MJMSALProvider.PROVIDER_TYPE\n };\n super(config);\n }\n\n // ============================================================================\n // LIFECYCLE METHODS\n // ============================================================================\n\n async initialize(): Promise<void> {\n if (this._initPromise) {\n return this._initPromise;\n }\n\n this._initPromise = this._performInitialization();\n return this._initPromise;\n }\n\n private async _performInitialization(): Promise<void> {\n console.debug('[MSAL] Starting initialization...');\n await this.auth.instance.initialize();\n console.debug('[MSAL] MSAL instance initialized');\n\n // Handle redirect immediately after initialization\n const redirectResponse = await this.auth.instance.handleRedirectPromise();\n console.debug('[MSAL] Redirect response:', redirectResponse ? 'Found' : 'None');\n\n if (redirectResponse && redirectResponse.account) {\n // User just logged in via redirect\n console.debug('[MSAL] Processing redirect login');\n this.auth.instance.setActiveAccount(redirectResponse.account);\n this.updateAuthState(true);\n\n // Update user info from account\n const userInfo = this.mapMSALAccountToStandard(redirectResponse.account);\n this.updateUserInfo(userInfo);\n\n this._initializationCompleted$.next(true);\n console.debug('[MSAL] Initialization completed (redirect login)');\n } else {\n // Set active account if we have one from cache\n const accounts = this.auth.instance.getAllAccounts();\n console.debug('[MSAL] Cached accounts found:', accounts.length);\n\n if (accounts.length > 0) {\n console.debug('[MSAL] Restoring session from cached account:', accounts[0].username);\n this.auth.instance.setActiveAccount(accounts[0]);\n this.updateAuthState(true);\n\n // Update user info from cached account\n const userInfo = this.mapMSALAccountToStandard(accounts[0]);\n this.updateUserInfo(userInfo);\n\n this._initializationCompleted$.next(true);\n console.debug('[MSAL] Initialization completed (cached session restored)');\n } else {\n console.debug('[MSAL] No cached accounts, user needs to log in');\n }\n }\n\n // Subscribe to broadcast service for ongoing auth state changes\n this.msalBroadcastService.inProgress$\n .pipe(\n filter((status: InteractionStatus) => status === InteractionStatus.None),\n takeUntil(this._destroying$)\n )\n .subscribe(() => {\n const accounts = this.auth.instance.getAllAccounts();\n const isAuth = accounts.length > 0;\n\n this.updateAuthState(isAuth);\n\n if (isAuth) {\n this.auth.instance.setActiveAccount(accounts[0]);\n const userInfo = this.mapMSALAccountToStandard(accounts[0]);\n this.updateUserInfo(userInfo);\n } else {\n this.updateUserInfo(null);\n }\n\n this._initializationCompleted$.next(true);\n });\n }\n\n protected async loginInternal(options?: Record<string, unknown>): Promise<void> {\n await this.ensureInitialized();\n\n const silentRequest = {\n scopes: ['User.Read', 'email', 'profile'],\n ...options\n };\n\n return new Promise((resolve, reject) => {\n this.auth.loginRedirect(silentRequest).subscribe({\n next: () => {\n resolve();\n },\n error: (error) => {\n LogError(error);\n reject(error);\n }\n });\n });\n }\n\n async logout(): Promise<void> {\n await this.ensureInitialized();\n this.auth.logoutRedirect().subscribe(() => {\n // Logout will trigger a redirect\n });\n }\n\n async handleCallback(): Promise<void> {\n // MSAL Angular handles callbacks internally through its broadcast service\n // The handleRedirectPromise is called in initialize()\n await this.ensureInitialized();\n }\n\n // ============================================================================\n // ABSTRACT METHOD IMPLEMENTATIONS (v3.0.0)\n // ============================================================================\n\n /**\n * Extract ID token from MSAL's storage\n *\n * MSAL stores the JWT in AuthenticationResult.idToken\n * This is the key abstraction - consumers never need to know about MSAL's structure!\n */\n protected async extractIdTokenInternal(): Promise<string | null> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return null;\n }\n\n // First try to get cached token from account\n // This avoids unnecessary iframe calls that can timeout\n if (account.idToken) {\n // Check if token is expired or about to expire (within 5-minute buffer)\n // This prevents the race condition where proactive refresh hasn't completed\n // but the cached token is already expired\n if (this.isTokenValid(account.idToken, 300)) {\n return account.idToken;\n }\n\n // Token expired or near-expiry — force a silent refresh\n console.debug('[MSAL] Cached token expired or near-expiry, forcing silent refresh');\n try {\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read', 'email', 'profile'],\n account: account,\n forceRefresh: true\n });\n return response.idToken || null;\n } catch (refreshError) {\n console.warn('[MSAL] Silent refresh failed, returning expired cached token:', refreshError);\n // Fall through to existing cache-only acquisition below\n }\n }\n\n // If not in account, try silent token acquisition from cache only\n // Use CacheLookupPolicy.AccessToken to avoid iframe calls\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read', 'email', 'profile'],\n account: account,\n cacheLookupPolicy: CacheLookupPolicy.AccessToken\n });\n\n // MSAL-specific detail: JWT is in idToken property\n return response.idToken || null;\n } catch (error) {\n console.error('[MSAL] Error extracting ID token:', error);\n return null;\n }\n }\n\n /**\n * Extract complete token info from MSAL\n *\n * Maps MSAL's AuthenticationResult to StandardAuthToken\n */\n protected async extractTokenInfoInternal(): Promise<StandardAuthToken | null> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return null;\n }\n\n // Use cache-only lookup to avoid iframe timeouts during normal token extraction\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read', 'email', 'profile'],\n account: account,\n cacheLookupPolicy: CacheLookupPolicy.AccessToken\n });\n\n if (!response.idToken) {\n return null;\n }\n\n return {\n idToken: response.idToken,\n accessToken: response.accessToken,\n expiresAt: response.expiresOn ? response.expiresOn.getTime() : 0,\n scopes: response.scopes\n };\n } catch (error) {\n // If acquireTokenSilent fails (e.g., iframe timeout), try to use cached account data\n console.error('[MSAL] Error extracting token info:', error);\n\n const account = this.auth.instance.getActiveAccount();\n if (account?.idToken) {\n // Return basic token info from account if available\n return {\n idToken: account.idToken,\n expiresAt: 0, // Unknown from account alone\n scopes: []\n };\n }\n\n return null;\n }\n }\n\n /**\n * Extract user info from MSAL account\n *\n * Maps MSAL's AccountInfo structure to StandardUserInfo\n */\n protected async extractUserInfoInternal(): Promise<StandardUserInfo | null> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return null;\n }\n\n return this.mapMSALAccountToStandard(account);\n } catch (error) {\n console.error('[MSAL] Error extracting user info:', error);\n return null;\n }\n }\n\n /**\n * Refresh token using MSAL's silent token acquisition\n *\n * MSAL 5.x Best Practices:\n * - Pass account parameter for reliable silent acquisition\n * - Use CacheLookupPolicy.Default for efficient cache → refresh token → iframe chain\n * - Handle MSAL 5.x specific error codes (timed_out, no_tokens_found, etc.)\n */\n protected async refreshTokenInternal(): Promise<TokenRefreshResult> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return {\n success: false,\n error: {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message: 'No active account found',\n userMessage: 'You need to log in to continue.'\n }\n };\n }\n\n // MSAL 5.x: Pass account for reliable silent acquisition\n // Use Default policy for efficient cache → refresh token → iframe chain\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read', 'email', 'profile'],\n account: account,\n cacheLookupPolicy: CacheLookupPolicy.Default\n });\n\n if (!response.idToken) {\n return {\n success: false,\n error: {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message: 'Token refresh succeeded but no ID token returned',\n userMessage: 'Session refresh failed. Please log in again.'\n }\n };\n }\n\n const token: StandardAuthToken = {\n idToken: response.idToken,\n accessToken: response.accessToken,\n expiresAt: response.expiresOn ? response.expiresOn.getTime() : 0,\n scopes: response.scopes\n };\n\n return {\n success: true,\n token\n };\n } catch (error) {\n console.error('[MSAL] Token refresh failed:', error);\n\n // Handle MSAL 5.x error codes that require user interaction\n // - timed_out: MSAL 5.x iframe timeout (replaces monitor_window_timeout from 3.x)\n // - monitor_window_timeout: Legacy MSAL 3.x iframe timeout\n // - no_tokens_found: No cached tokens available\n // - no_account_error: Account not found in cache\n // - InteractionRequiredAuthError: Server requires user interaction\n const errorCode = (error as Record<string, unknown>)?.errorCode as string | undefined;\n const interactionRequiredCodes = [\n 'monitor_window_timeout',\n 'timed_out',\n 'no_tokens_found',\n 'no_account_error',\n 'login_required',\n 'consent_required',\n 'token_refresh_required' // ClientAuthError when cached token needs refresh\n ];\n\n if (interactionRequiredCodes.includes(errorCode || '') || error instanceof InteractionRequiredAuthError) {\n // Return INTERACTION_REQUIRED error - base class will call handleSessionExpiryInternal\n return {\n success: false,\n error: {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message: `Silent token refresh failed - interaction required (${errorCode || 'unknown'})`,\n userMessage: 'Your session has expired. Redirecting to login...',\n originalError: error\n }\n };\n }\n\n return {\n success: false,\n error: this.classifyErrorInternal(error)\n };\n }\n }\n\n /**\n * Classify MSAL-specific errors into semantic types\n *\n * Maps MSAL error classes to AuthErrorType enum.\n * Updated for MSAL 5.x error codes.\n */\n protected classifyErrorInternal(error: unknown): StandardAuthError {\n const errorObj = error as Record<string, unknown>;\n const message = errorObj?.['message'] as string || 'Unknown error';\n const errorCode = errorObj?.['errorCode'] as string || '';\n\n // Check for specific MSAL error types\n if (error instanceof InteractionRequiredAuthError) {\n return {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message,\n originalError: error,\n userMessage: 'Additional authentication is required. Please log in again.'\n };\n }\n\n // ClientAuthError — covers codes like token_refresh_required that are not\n // surfaced through BrowserAuthError or InteractionRequiredAuthError.\n if (error instanceof ClientAuthError) {\n if (errorCode === 'token_refresh_required') {\n return {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n return {\n type: AuthErrorType.TOKEN_EXPIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n if (error instanceof BrowserAuthError) {\n // Check specific error codes - MSAL 5.x codes\n if (errorCode === 'user_cancelled' || message.includes('user cancelled')) {\n return {\n type: AuthErrorType.USER_CANCELLED,\n message,\n originalError: error,\n userMessage: 'Login was cancelled.'\n };\n }\n\n // MSAL 5.x timeout and session errors that require interaction\n const interactionRequiredCodes = [\n 'timed_out',\n 'monitor_window_timeout',\n 'no_tokens_found',\n 'no_account_error',\n 'login_required',\n 'consent_required'\n ];\n if (interactionRequiredCodes.includes(errorCode)) {\n return {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n return {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message,\n originalError: error,\n userMessage: 'Authentication error. Please log in again.'\n };\n }\n\n // Check message patterns\n if (message.includes('token') && message.includes('expired')) {\n return {\n type: AuthErrorType.TOKEN_EXPIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n if (message.includes('network') || message.includes('fetch')) {\n return {\n type: AuthErrorType.NETWORK_ERROR,\n message,\n originalError: error,\n userMessage: 'Network error. Please check your connection and try again.'\n };\n }\n\n if (message.includes('you need to be authorized')) {\n return {\n type: AuthErrorType.TOKEN_EXPIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n // Default to unknown error\n return {\n type: AuthErrorType.UNKNOWN_ERROR,\n message,\n originalError: error,\n userMessage: 'An unexpected error occurred. Please try again.'\n };\n }\n\n // ============================================================================\n // HELPER METHODS\n // ============================================================================\n\n private async ensureInitialized(): Promise<void> {\n if (!this._initPromise) {\n await this.initialize();\n } else if (!this._initializationCompleted$.value) {\n await this._initPromise;\n }\n }\n\n /**\n * Check if a JWT token is still valid with an optional buffer period.\n * Decodes the payload to read the `exp` claim without cryptographic verification\n * (expiry is a timing check, not an authenticity check).\n *\n * @param token - The JWT string to check\n * @param bufferSeconds - Number of seconds before actual expiry to consider the token invalid (default: 0)\n * @returns true if the token's exp claim is beyond (now + buffer), false otherwise\n */\n private isTokenValid(token: string, bufferSeconds: number = 0): boolean {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) {\n return false;\n }\n const payload = JSON.parse(atob(parts[1])) as { exp?: number };\n const expiresAtMs = (payload.exp ?? 0) * 1000;\n return expiresAtMs > Date.now() + (bufferSeconds * 1000);\n } catch {\n // If we can't decode the token, treat it as invalid\n return false;\n }\n }\n\n /**\n * Map MSAL AccountInfo to StandardUserInfo\n */\n private mapMSALAccountToStandard(account: AccountInfo): StandardUserInfo {\n return {\n id: account.localAccountId || account.homeAccountId,\n email: account.username || '',\n name: account.name || account.username || '',\n givenName: account.idTokenClaims?.['given_name'] as string,\n familyName: account.idTokenClaims?.['family_name'] as string,\n preferredUsername: account.username,\n emailVerified: true // MSAL doesn't provide this, assume true\n };\n }\n\n /**\n * Get profile picture URL from Microsoft Graph API\n *\n * MSAL requires fetching the photo from Microsoft Graph.\n * This is the key advantage of encapsulation - consumers don't need\n * to know about Graph API, they just call getProfilePictureUrl()!\n */\n protected async getProfilePictureUrlInternal(): Promise<string | null> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return null;\n }\n\n // Get access token for Microsoft Graph\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read'],\n account: account,\n forceRefresh: false\n });\n\n if (!response.accessToken) {\n return null;\n }\n\n // Fetch photo from Microsoft Graph\n const graphResponse = await fetch('https://graph.microsoft.com/v1.0/me/photo/$value', {\n headers: { 'Authorization': `Bearer ${response.accessToken}` }\n });\n\n if (graphResponse.ok) {\n const blob = await graphResponse.blob();\n return URL.createObjectURL(blob);\n }\n\n return null;\n } catch (error) {\n console.error('[MSAL] Error getting profile picture:', error);\n return null;\n }\n }\n\n /**\n * Handle session expiry by redirecting to Microsoft login\n *\n * This method is called by the base class when silent token refresh fails\n * with INTERACTION_REQUIRED error. It redirects to Microsoft login and never returns.\n * After authentication, the app will reload and re-initialize with a fresh token.\n */\n protected async handleSessionExpiryInternal(): Promise<void> {\n console.debug('[MSAL] Redirecting to Microsoft login for re-authentication...');\n\n // Initiate redirect authentication - page will navigate away\n this.auth.loginRedirect({\n scopes: ['User.Read', 'email', 'profile'],\n prompt: 'select_account'\n }).subscribe({\n error: (redirectError) => {\n console.error('[MSAL] Redirect initiation failed:', redirectError);\n }\n });\n\n // Return a promise that never resolves - page will navigate before this matters\n return new Promise<void>(() => {});\n }\n\n // ============================================================================\n // CONFIGURATION\n // ============================================================================\n\n override getRequiredConfig(): string[] {\n return ['clientId', 'tenantId'];\n }\n\n override validateConfig(_config: Record<string, unknown>): boolean {\n // MSAL configuration is handled by Angular module providers\n return true;\n }\n\n // ============================================================================\n // CLEANUP\n // ============================================================================\n\n ngOnDestroy(): void {\n this._destroying$.next();\n this._destroying$.complete();\n this._initPromise = null;\n this._initializationCompleted$.complete();\n }\n}"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-auth-services",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.13.0",
|
|
4
4
|
"description": "MemberJunction Explorer: Authentication Services",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"@okta/okta-auth-js": "^7.14.1"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@memberjunction/core": "5.
|
|
34
|
-
"@memberjunction/global": "5.
|
|
33
|
+
"@memberjunction/core": "5.13.0",
|
|
34
|
+
"@memberjunction/global": "5.13.0",
|
|
35
35
|
"rxjs": "^7.8.2",
|
|
36
36
|
"tslib": "^2.8.1"
|
|
37
37
|
},
|