Member Junction
    Preparing search index...

    MSAL (Microsoft Authentication Library) provider implementation - v3.0.0

    Implements the abstract methods from MJAuthBase to hide MSAL-specific details. The key abstraction is that MSAL stores the JWT in AuthenticationResult.idToken, but consumers never need to know this detail.

    Hierarchy (View Summary)

    Implements

    • OnDestroy
    Index

    Constructors

    Properties

    Auth: MsalService
    isAuthenticated$: BehaviorSubject<boolean> = ...
    type: "msal" = MJMSALProvider.PROVIDER_TYPE

    Provider type identifier Must be implemented by concrete providers

    userEmail$: BehaviorSubject<string> = ...
    userInfo$: BehaviorSubject<StandardUserInfo | null> = ...
    PROVIDER_TYPE: "msal" = 'msal'

    Accessors

    • get preservedLocalStorageKeys(): Set<string>

      localStorage keys that survive a logout (e.g. UI theme preference).

      Override this getter in a subclass to preserve additional keys specific to your provider or application.

      Returns Set<string>

    • get angularProviderFactory(): (
          environment: Record<string, unknown>,
      ) => (
          | typeof MsalService
          | typeof MsalGuard
          | typeof MsalBroadcastService
          | {
              provide: InjectionToken<IPublicClientApplication>;
              useValue: PublicClientApplication;
          }
          | {
              provide: InjectionToken<MsalGuardConfiguration>;
              useValue: {
                  authRequest: { scopes: string[] };
                  interactionType: InteractionType;
                  protectedResourceMap?: undefined;
              };
          }
          | {
              provide: InjectionToken<MsalInterceptorConfiguration>;
              useValue: {
                  authRequest?: undefined;
                  interactionType: InteractionType;
                  protectedResourceMap: Map<string, string[]>;
              };
          }
      )[]

      Returns (
          environment: Record<string, unknown>,
      ) => (
          | typeof MsalService
          | typeof MsalGuard
          | typeof MsalBroadcastService
          | {
              provide: InjectionToken<IPublicClientApplication>;
              useValue: PublicClientApplication;
          }
          | {
              provide: InjectionToken<MsalGuardConfiguration>;
              useValue: {
                  authRequest: { scopes: string[] };
                  interactionType: InteractionType;
                  protectedResourceMap?: undefined;
              };
          }
          | {
              provide: InjectionToken<MsalInterceptorConfiguration>;
              useValue: {
                  authRequest?: undefined;
                  interactionType: InteractionType;
                  protectedResourceMap: Map<string, string[]>;
              };
          }
      )[]

        • (
              environment: Record<string, unknown>,
          ): (
              | typeof MsalService
              | typeof MsalGuard
              | typeof MsalBroadcastService
              | {
                  provide: InjectionToken<IPublicClientApplication>;
                  useValue: PublicClientApplication;
              }
              | {
                  provide: InjectionToken<MsalGuardConfiguration>;
                  useValue: {
                      authRequest: { scopes: string[] };
                      interactionType: InteractionType;
                      protectedResourceMap?: undefined;
                  };
              }
              | {
                  provide: InjectionToken<MsalInterceptorConfiguration>;
                  useValue: {
                      authRequest?: undefined;
                      interactionType: InteractionType;
                      protectedResourceMap: Map<string, string[]>;
                  };
              }
          )[]
        • Factory function to provide Angular dependencies required by MSAL Stored as a static property for the factory to access without instantiation

          Parameters

          • environment: Record<string, unknown>

          Returns (
              | typeof MsalService
              | typeof MsalGuard
              | typeof MsalBroadcastService
              | {
                  provide: InjectionToken<IPublicClientApplication>;
                  useValue: PublicClientApplication;
              }
              | {
                  provide: InjectionToken<MsalGuardConfiguration>;
                  useValue: {
                      authRequest: { scopes: string[] };
                      interactionType: InteractionType;
                      protectedResourceMap?: undefined;
                  };
              }
              | {
                  provide: InjectionToken<MsalInterceptorConfiguration>;
                  useValue: {
                      authRequest?: undefined;
                      interactionType: InteractionType;
                      protectedResourceMap: Map<string, string[]>;
                  };
              }
          )[]

      Use AngularProviderFactory.

    • set angularProviderFactory(
          value: (
              environment: Record<string, unknown>,
          ) => (
              | typeof MsalService
              | typeof MsalGuard
              | typeof MsalBroadcastService
              | {
                  provide: InjectionToken<IPublicClientApplication>;
                  useValue: PublicClientApplication;
              }
              | {
                  provide: InjectionToken<MsalGuardConfiguration>;
                  useValue: {
                      authRequest: { scopes: string[] };
                      interactionType: InteractionType;
                      protectedResourceMap?: undefined;
                  };
              }
              | {
                  provide: InjectionToken<MsalInterceptorConfiguration>;
                  useValue: {
                      authRequest?: undefined;
                      interactionType: InteractionType;
                      protectedResourceMap: Map<string, string[]>;
                  };
              }
          )[],
      ): void

      Parameters

      • value: (
            environment: Record<string, unknown>,
        ) => (
            | typeof MsalService
            | typeof MsalGuard
            | typeof MsalBroadcastService
            | {
                provide: InjectionToken<IPublicClientApplication>;
                useValue: PublicClientApplication;
            }
            | {
                provide: InjectionToken<MsalGuardConfiguration>;
                useValue: {
                    authRequest: { scopes: string[] };
                    interactionType: InteractionType;
                    protectedResourceMap?: undefined;
                };
            }
            | {
                provide: InjectionToken<MsalInterceptorConfiguration>;
                useValue: {
                    authRequest?: undefined;
                    interactionType: InteractionType;
                    protectedResourceMap: Map<string, string[]>;
                };
            }
        )[]
          • (
                environment: Record<string, unknown>,
            ): (
                | typeof MsalService
                | typeof MsalGuard
                | typeof MsalBroadcastService
                | {
                    provide: InjectionToken<IPublicClientApplication>;
                    useValue: PublicClientApplication;
                }
                | {
                    provide: InjectionToken<MsalGuardConfiguration>;
                    useValue: {
                        authRequest: { scopes: string[] };
                        interactionType: InteractionType;
                        protectedResourceMap?: undefined;
                    };
                }
                | {
                    provide: InjectionToken<MsalInterceptorConfiguration>;
                    useValue: {
                        authRequest?: undefined;
                        interactionType: InteractionType;
                        protectedResourceMap: Map<string, string[]>;
                    };
                }
            )[]
          • Factory function to provide Angular dependencies required by MSAL Stored as a static property for the factory to access without instantiation

            Parameters

            • environment: Record<string, unknown>

            Returns (
                | typeof MsalService
                | typeof MsalGuard
                | typeof MsalBroadcastService
                | {
                    provide: InjectionToken<IPublicClientApplication>;
                    useValue: PublicClientApplication;
                }
                | {
                    provide: InjectionToken<MsalGuardConfiguration>;
                    useValue: {
                        authRequest: { scopes: string[] };
                        interactionType: InteractionType;
                        protectedResourceMap?: undefined;
                    };
                }
                | {
                    provide: InjectionToken<MsalInterceptorConfiguration>;
                    useValue: {
                        authRequest?: undefined;
                        interactionType: InteractionType;
                        protectedResourceMap: Map<string, string[]>;
                    };
                }
            )[]

      Returns void

      Use AngularProviderFactory.

    Methods

    • Clears MJ client-side caches before logout.

      Removes all localStorage entries except those returned by preservedLocalStorageKeys, and deletes the MJ_Metadata IndexedDB database so a subsequent user session starts with a clean slate.

      First, while the session is still authenticated, it sends this user's unsent realtime-call recording shards (a few seconds at most) and deletes whatever is left, so their call audio is neither left on a shared browser nor re-sent from the next user's session.

      Returns Promise<void>

    • Get profile picture URL from auth provider

      Returns the user's profile picture URL if available from the auth provider. This abstracts away provider-specific logic:

      • Microsoft/MSAL: Fetches from Graph API
      • Auth0/Okta: Returns from user claims

      Returns Promise<string | null>

      Promise resolving to image URL or null if not available

      const pictureUrl = await this.authBase.getProfilePictureUrl();
      if (pictureUrl) {
      this.userAvatar = pictureUrl;
      }
    • Logout — clears all MJ client-side caches then delegates to the provider.

      Cache clearing happens universally regardless of auth provider so that a subsequent login as a different user never sees the previous user's data. Providers that need to clear additional caches should override logoutInternal() and call super.logoutInternal() if applicable.

      Returns Promise<void>

    • Refresh authentication token

      Attempts to obtain a fresh authentication token using the provider's refresh mechanism. If silent refresh fails due to session expiry, the provider will handle re-authentication automatically (which may involve redirecting to the auth provider's login page).

      Returns StandardAuthToken on success, or throws on complete failure.

      IMPORTANT: If the provider requires interactive re-authentication (redirect or popup), this method may never return. The app will reload after authentication completes and re-initialize with a fresh token.

      Returns Promise<StandardAuthToken>

      Promise resolving to StandardAuthToken or throws on failure

      const token = await this.authBase.refreshToken();
      return token.idToken; // Always succeeds or throws
    • Refresh token using MSAL's silent token acquisition

      MSAL 5.x Best Practices:

      • Pass account parameter for reliable silent acquisition
      • Use forceRefresh: true to bypass cache and get fresh tokens from Azure AD
      • Handle MSAL 5.x specific error codes (timed_out, no_tokens_found, etc.)

      IMPORTANT: This method is called when the server has already rejected the current token as expired (JWT_EXPIRED). Using CacheLookupPolicy.Default here can return a cached ID token that is still expired (e.g. when the access token has a longer lifetime than the ID token). forceRefresh: true ensures a network round-trip to Azure AD so both the access token and ID token are genuinely refreshed.

      Returns Promise<TokenRefreshResult>

    • Factory function to provide Angular dependencies required by MSAL Stored as a static property for the factory to access without instantiation

      Parameters

      • environment: Record<string, unknown>

      Returns (
          | typeof MsalService
          | typeof MsalGuard
          | typeof MsalBroadcastService
          | {
              provide: InjectionToken<IPublicClientApplication>;
              useValue: PublicClientApplication;
          }
          | {
              provide: InjectionToken<MsalGuardConfiguration>;
              useValue: {
                  authRequest: { scopes: string[] };
                  interactionType: InteractionType;
                  protectedResourceMap?: undefined;
              };
          }
          | {
              provide: InjectionToken<MsalInterceptorConfiguration>;
              useValue: {
                  authRequest?: undefined;
                  interactionType: InteractionType;
                  protectedResourceMap: Map<string, string[]>;
              };
          }
      )[]

    • Maps a catalog row onto the unprefixed keys angularProviderFactory reads (CLIENT_ID / CLIENT_AUTHORITY), which predate the <DRIVER>_* convention the generic overlay emits — without this mapping a metadata-configured row would be silently ignored in favour of the compiled environment.

      The authority comes from ClientConfiguration.authority when the row supplies one; otherwise it is derived from the Issuer by stripping the trailing /v2.0 — an Entra issuer is https://login.microsoftonline.com/<tenantId>/v2.0, and MSAL's authority is that same URL without the version suffix. That derivation only holds for standard Entra tenants: rows for Azure AD B2C or v1 sts.windows.net issuers must set ClientConfiguration.authority explicitly, because their issuer is not a usable authority (and B2C additionally needs knownAuthorities, which this driver does not yet plumb).

      Parameters

      Returns Record<string, unknown>

    • Picks the cached account a session may resume as.

      MSAL keeps every account that signed in on this browser profile until it is logged out, so on a shared machine the cache can hold another person's account next to the current one. The active account is the one the last sign-in set, so it wins; a single cached account is unambiguous. With several accounts and none active there is no way to tell whose session this is, so the method returns null and the user signs in again rather than resuming as the first account listed.

      Parameters

      • accounts: AccountInfo[]
      • active: AccountInfo | null

      Returns AccountInfo | null