/* * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ import { CommonAuthorizationUrlRequest, CommonSilentFlowRequest, PerformanceCallbackFunction, AccountInfo, Logger, ICrypto, IPerformanceClient, DEFAULT_CRYPTO_IMPLEMENTATION, AccountFilter, } from "@azure/msal-common"; import { ITokenCache } from "../cache/ITokenCache"; import { BrowserConfiguration } from "../config/Configuration"; import { BrowserCacheManager, DEFAULT_BROWSER_CACHE_MANAGER, } from "../cache/BrowserCacheManager"; import { INavigationClient } from "../navigation/INavigationClient"; import { AuthorizationCodeRequest } from "../request/AuthorizationCodeRequest"; import { EndSessionPopupRequest } from "../request/EndSessionPopupRequest"; import { EndSessionRequest } from "../request/EndSessionRequest"; import { PopupRequest } from "../request/PopupRequest"; import { RedirectRequest } from "../request/RedirectRequest"; import { SilentRequest } from "../request/SilentRequest"; import { SsoSilentRequest } from "../request/SsoSilentRequest"; import { AuthenticationResult } from "../response/AuthenticationResult"; import { ApiId, WrapperSKU } from "../utils/BrowserConstants"; import { IController } from "./IController"; import { UnknownOperatingContext } from "../operatingcontext/UnknownOperatingContext"; import { CryptoOps } from "../crypto/CryptoOps"; import { blockAPICallsBeforeInitialize, blockNonBrowserEnvironment, } from "../utils/BrowserUtils"; import { EventHandler } from "../event/EventHandler"; import { EventCallbackFunction } from "../event/EventMessage"; import { ClearCacheRequest } from "../request/ClearCacheRequest"; /** * UnknownOperatingContextController class * * - Until initialize method is called, this controller is the default * - AFter initialize method is called, this controller will be swapped out for the appropriate controller * if the operating context can be determined; otherwise this controller will continued be used * * - Why do we have this? We don't want to dynamically import (download) all of the code in StandardController if we don't need to. * * - Only includes implementation for getAccounts and handleRedirectPromise * - All other methods are will throw initialization error (because either initialize method or the factory method were not used) * - This controller is necessary for React Native wrapper, server side rendering and any other scenario where we don't have a DOM * */ export class UnknownOperatingContextController implements IController { // OperatingContext protected readonly operatingContext: UnknownOperatingContext; // Logger protected logger: Logger; // Storage interface implementation protected readonly browserStorage: BrowserCacheManager; // Input configuration by developer/user protected readonly config: BrowserConfiguration; // Performance telemetry client protected readonly performanceClient: IPerformanceClient; // Crypto interface implementation protected readonly browserCrypto: ICrypto; // Flag to indicate if in browser environment protected isBrowserEnvironment: boolean; // Flag representing whether or not the initialize API has been called and completed protected initialized: boolean = false; protected readonly eventHandler: EventHandler; constructor(operatingContext: UnknownOperatingContext) { this.operatingContext = operatingContext; this.isBrowserEnvironment = this.operatingContext.isBrowserEnvironment(); this.config = operatingContext.getConfig(); this.logger = operatingContext.getLogger(); // Initialize performance client this.performanceClient = this.config.telemetry.client; // Initialize the crypto class. this.browserCrypto = this.isBrowserEnvironment ? new CryptoOps(this.logger, this.performanceClient) : DEFAULT_CRYPTO_IMPLEMENTATION; // Initialize the browser storage class. this.browserStorage = this.isBrowserEnvironment ? new BrowserCacheManager( this.config.auth.clientId, this.config.cache, this.browserCrypto, this.logger, undefined, this.performanceClient ) : DEFAULT_BROWSER_CACHE_MANAGER( this.config.auth.clientId, this.logger ); this.eventHandler = new EventHandler(this.logger, this.browserCrypto); } getBrowserStorage(): BrowserCacheManager { return this.browserStorage; } getEventHandler(): EventHandler { return this.eventHandler; } // eslint-disable-next-line @typescript-eslint/no-unused-vars getAccount(accountFilter: AccountFilter): AccountInfo | null { return null; } // eslint-disable-next-line @typescript-eslint/no-unused-vars getAccountByHomeId(homeAccountId: string): AccountInfo | null { return null; } // eslint-disable-next-line @typescript-eslint/no-unused-vars getAccountByLocalId(localAccountId: string): AccountInfo | null { return null; } // eslint-disable-next-line @typescript-eslint/no-unused-vars getAccountByUsername(username: string): AccountInfo | null { return null; } getAllAccounts(): AccountInfo[] { return []; } initialize(): Promise { this.initialized = true; return Promise.resolve(); } // eslint-disable-next-line @typescript-eslint/no-unused-vars acquireTokenPopup(request: PopupRequest): Promise { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return {} as Promise; } // eslint-disable-next-line @typescript-eslint/no-unused-vars acquireTokenRedirect(request: RedirectRequest): Promise { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return Promise.resolve(); } acquireTokenSilent( // eslint-disable-next-line @typescript-eslint/no-unused-vars silentRequest: SilentRequest ): Promise { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return {} as Promise; } acquireTokenByCode( // eslint-disable-next-line @typescript-eslint/no-unused-vars request: AuthorizationCodeRequest ): Promise { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return {} as Promise; } acquireTokenNative( // eslint-disable-next-line @typescript-eslint/no-unused-vars request: | PopupRequest | SilentRequest | Partial< Omit< CommonAuthorizationUrlRequest, | "responseMode" | "codeChallenge" | "codeChallengeMethod" | "requestedClaimsHash" | "nativeBroker" > >, // eslint-disable-next-line @typescript-eslint/no-unused-vars apiId: ApiId, // eslint-disable-next-line @typescript-eslint/no-unused-vars accountId?: string | undefined ): Promise { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return {} as Promise; } acquireTokenByRefreshToken( // eslint-disable-next-line @typescript-eslint/no-unused-vars commonRequest: CommonSilentFlowRequest, // eslint-disable-next-line @typescript-eslint/no-unused-vars silentRequest: SilentRequest ): Promise { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return {} as Promise; } addEventCallback(callback: EventCallbackFunction): string | null { return this.eventHandler.addEventCallback(callback); } removeEventCallback(callbackId: string): void { this.eventHandler.removeEventCallback(callbackId); } // eslint-disable-next-line @typescript-eslint/no-unused-vars addPerformanceCallback(callback: PerformanceCallbackFunction): string { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return ""; } // eslint-disable-next-line @typescript-eslint/no-unused-vars removePerformanceCallback(callbackId: string): boolean { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return true; } enableAccountStorageEvents(): void { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); } disableAccountStorageEvents(): void { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); } handleRedirectPromise( // eslint-disable-next-line @typescript-eslint/no-unused-vars hash?: string | undefined ): Promise { blockAPICallsBeforeInitialize(this.initialized); return Promise.resolve(null); } loginPopup( // eslint-disable-next-line @typescript-eslint/no-unused-vars request?: PopupRequest | undefined ): Promise { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return {} as Promise; } // eslint-disable-next-line @typescript-eslint/no-unused-vars loginRedirect(request?: RedirectRequest | undefined): Promise { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return {} as Promise; } // eslint-disable-next-line @typescript-eslint/no-unused-vars logout(logoutRequest?: EndSessionRequest | undefined): Promise { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return {} as Promise; } logoutRedirect( // eslint-disable-next-line @typescript-eslint/no-unused-vars logoutRequest?: EndSessionRequest | undefined ): Promise { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return {} as Promise; } logoutPopup( // eslint-disable-next-line @typescript-eslint/no-unused-vars logoutRequest?: EndSessionPopupRequest | undefined ): Promise { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return {} as Promise; } ssoSilent( // eslint-disable-next-line @typescript-eslint/no-unused-vars request: Partial< Omit< CommonAuthorizationUrlRequest, | "responseMode" | "codeChallenge" | "codeChallengeMethod" | "requestedClaimsHash" | "nativeBroker" > > ): Promise { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return {} as Promise; } getTokenCache(): ITokenCache { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return {} as ITokenCache; } getLogger(): Logger { return this.logger; } // eslint-disable-next-line @typescript-eslint/no-unused-vars setLogger(logger: Logger): void { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); } // eslint-disable-next-line @typescript-eslint/no-unused-vars setActiveAccount(account: AccountInfo | null): void { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); } getActiveAccount(): AccountInfo | null { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return null; } // eslint-disable-next-line @typescript-eslint/no-unused-vars initializeWrapperLibrary(sku: WrapperSKU, version: string): void { this.browserStorage.setWrapperMetadata(sku, version); } // eslint-disable-next-line @typescript-eslint/no-unused-vars setNavigationClient(navigationClient: INavigationClient): void { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); } getConfiguration(): BrowserConfiguration { return this.config; } isBrowserEnv(): boolean { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return true; } getBrowserCrypto(): ICrypto { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return {} as ICrypto; } getPerformanceClient(): IPerformanceClient { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return {} as IPerformanceClient; } getRedirectResponse(): Map> { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); return {} as Map>; } // eslint-disable-next-line @typescript-eslint/no-unused-vars async clearCache(logoutRequest?: ClearCacheRequest): Promise { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); } // eslint-disable-next-line @typescript-eslint/no-unused-vars async hydrateCache( // eslint-disable-next-line @typescript-eslint/no-unused-vars result: AuthenticationResult, // eslint-disable-next-line @typescript-eslint/no-unused-vars request: | SilentRequest | SsoSilentRequest | RedirectRequest | PopupRequest ): Promise { blockAPICallsBeforeInitialize(this.initialized); blockNonBrowserEnvironment(); } }