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>