wangzhibo
2026-05-09 53418655c061ac26f66058253f39200aced1ab1d
1
{"version":3,"file":"interactiveBrowserCredential.js","sourceRoot":"","sources":["../../../src/credentials/interactiveBrowserCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AccessToken, GetTokenOptions, TokenCredential } from \"@azure/core-auth\";\nimport type {\n  InteractiveBrowserCredentialInBrowserOptions,\n  InteractiveBrowserCredentialNodeOptions,\n} from \"./interactiveBrowserCredentialOptions.js\";\nimport {\n  processMultiTenantRequest,\n  resolveAdditionallyAllowedTenantIds,\n  resolveTenantId,\n} from \"../util/tenantIdUtils.js\";\n\nimport type { AuthenticationRecord } from \"../msal/types.js\";\nimport { credentialLogger } from \"../util/logging.js\";\nimport { ensureScopes } from \"../util/scopeUtils.js\";\nimport { tracingClient } from \"../util/tracing.js\";\nimport type { MsalClient, MsalClientOptions } from \"../msal/nodeFlows/msalClient.js\";\nimport { createMsalClient } from \"../msal/nodeFlows/msalClient.js\";\nimport { DeveloperSignOnClientId } from \"../constants.js\";\n\nconst logger = credentialLogger(\"InteractiveBrowserCredential\");\n\n/**\n * Enables authentication to Microsoft Entra ID inside of the web browser\n * using the interactive login flow.\n */\nexport class InteractiveBrowserCredential implements TokenCredential {\n  private tenantId?: string;\n  private additionallyAllowedTenantIds: string[];\n  private msalClient: MsalClient;\n  private disableAutomaticAuthentication?: boolean;\n  private browserCustomizationOptions: InteractiveBrowserCredentialNodeOptions[\"browserCustomizationOptions\"];\n  private loginHint?: string;\n\n  /**\n   * Creates an instance of InteractiveBrowserCredential with the details needed.\n   *\n   * This credential uses the [Authorization Code Flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-auth-code-flow).\n   * On Node.js, it will open a browser window while it listens for a redirect response from the authentication service.\n   * On browsers, it authenticates via popups. The `loginStyle` optional parameter can be set to `redirect` to authenticate by redirecting the user to an Azure secure login page, which then will redirect the user back to the web application where the authentication started.\n   *\n   * For Node.js, if a `clientId` is provided, the Microsoft Entra application will need to be configured to have a \"Mobile and desktop applications\" redirect endpoint.\n   * Follow our guide on [setting up Redirect URIs for Desktop apps that calls to web APIs](https://learn.microsoft.com/entra/identity-platform/scenario-desktop-app-registration#redirect-uris).\n   *\n   * @param options - Options for configuring the client which makes the authentication requests.\n   */\n  constructor(\n    options: InteractiveBrowserCredentialNodeOptions | InteractiveBrowserCredentialInBrowserOptions,\n  ) {\n    this.tenantId = resolveTenantId(logger, options.tenantId, options.clientId);\n    this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(\n      options?.additionallyAllowedTenants,\n    );\n\n    const msalClientOptions: MsalClientOptions = {\n      ...options,\n      tokenCredentialOptions: options,\n      logger,\n    };\n    const ibcNodeOptions = options as InteractiveBrowserCredentialNodeOptions;\n    this.browserCustomizationOptions = ibcNodeOptions.browserCustomizationOptions;\n    this.loginHint = ibcNodeOptions.loginHint;\n    if (ibcNodeOptions?.brokerOptions?.enabled) {\n      if (!ibcNodeOptions?.brokerOptions?.parentWindowHandle) {\n        throw new Error(\n          \"In order to do WAM authentication, `parentWindowHandle` under `brokerOptions` is a required parameter\",\n        );\n      } else {\n        msalClientOptions.brokerOptions = {\n          enabled: true,\n          parentWindowHandle: ibcNodeOptions.brokerOptions.parentWindowHandle,\n          legacyEnableMsaPassthrough: ibcNodeOptions.brokerOptions?.legacyEnableMsaPassthrough,\n          useDefaultBrokerAccount: ibcNodeOptions.brokerOptions?.useDefaultBrokerAccount,\n        };\n      }\n    }\n    this.msalClient = createMsalClient(\n      options.clientId ?? DeveloperSignOnClientId,\n      this.tenantId,\n      msalClientOptions,\n    );\n    this.disableAutomaticAuthentication = options?.disableAutomaticAuthentication;\n  }\n\n  /**\n   * Authenticates with Microsoft Entra ID and returns an access token if successful.\n   * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.\n   *\n   * If the user provided the option `disableAutomaticAuthentication`,\n   * once the token can't be retrieved silently,\n   * this method won't attempt to request user interaction to retrieve the token.\n   *\n   * @param scopes - The list of scopes for which the token will have access.\n   * @param options - The options used to configure any requests this\n   *                TokenCredential implementation might make.\n   */\n  async getToken(scopes: string | string[], options: GetTokenOptions = {}): Promise<AccessToken> {\n    return tracingClient.withSpan(\n      `${this.constructor.name}.getToken`,\n      options,\n      async (newOptions) => {\n        newOptions.tenantId = processMultiTenantRequest(\n          this.tenantId,\n          newOptions,\n          this.additionallyAllowedTenantIds,\n          logger,\n        );\n\n        const arrayScopes = ensureScopes(scopes);\n        return this.msalClient.getTokenByInteractiveRequest(arrayScopes, {\n          ...newOptions,\n          disableAutomaticAuthentication: this.disableAutomaticAuthentication,\n          browserCustomizationOptions: this.browserCustomizationOptions,\n          loginHint: this.loginHint,\n        });\n      },\n    );\n  }\n\n  /**\n   * Authenticates with Microsoft Entra ID and returns an access token if successful.\n   * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.\n   *\n   * If the token can't be retrieved silently, this method will always generate a challenge for the user.\n   *\n   * On Node.js, this credential has [Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636) enabled by default.\n   * PKCE is a security feature that mitigates authentication code interception attacks.\n   *\n   * @param scopes - The list of scopes for which the token will have access.\n   * @param options - The options used to configure any requests this\n   *                  TokenCredential implementation might make.\n   */\n  async authenticate(\n    scopes: string | string[],\n    options: GetTokenOptions = {},\n  ): Promise<AuthenticationRecord | undefined> {\n    return tracingClient.withSpan(\n      `${this.constructor.name}.authenticate`,\n      options,\n      async (newOptions) => {\n        const arrayScopes = ensureScopes(scopes);\n        await this.msalClient.getTokenByInteractiveRequest(arrayScopes, {\n          ...newOptions,\n          disableAutomaticAuthentication: false, // this method should always allow user interaction\n          browserCustomizationOptions: this.browserCustomizationOptions,\n          loginHint: this.loginHint,\n        });\n        return this.msalClient.getActiveAccount();\n      },\n    );\n  }\n}\n"]}