wangzhibo
2026-05-09 53418655c061ac26f66058253f39200aced1ab1d
1
{"version":3,"file":"visualStudioCodeCredential.js","sourceRoot":"","sources":["../../../src/credentials/visualStudioCodeCredential.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 { credentialLogger, formatError } from \"../util/logging.js\";\nimport {\n  processMultiTenantRequest,\n  resolveAdditionallyAllowedTenantIds,\n} from \"../util/tenantIdUtils.js\";\nimport { CredentialUnavailableError } from \"../errors.js\";\nimport type { VisualStudioCodeCredentialOptions } from \"./visualStudioCodeCredentialOptions.js\";\nimport { checkTenantId } from \"../util/tenantIdUtils.js\";\nimport { createMsalClient, MsalClient } from \"../msal/nodeFlows/msalClient.js\";\nimport { ensureScopes } from \"../util/scopeUtils.js\";\nimport { hasVSCodePlugin, vsCodeAuthRecordPath } from \"../msal/nodeFlows/msalPlugins.js\";\nimport { deserializeAuthenticationRecord } from \"../msal/utils.js\";\nimport { readFile } from \"node:fs/promises\";\nimport { AuthenticationRecord } from \"../msal/types.js\";\n\nconst CommonTenantId = \"common\";\nconst VSCodeClientId = \"aebc6443-996d-45c2-90f0-388ff96faa56\";\nconst logger = credentialLogger(\"VisualStudioCodeCredential\");\n\n// Map of unsupported Tenant IDs and the errors we will be throwing.\nconst unsupportedTenantIds: Record<string, string> = {\n  adfs: \"The VisualStudioCodeCredential does not support authentication with ADFS tenants.\",\n};\n\nfunction checkUnsupportedTenant(tenantId: string): void {\n  // If the Tenant ID isn't supported, we throw.\n  const unsupportedTenantError = unsupportedTenantIds[tenantId];\n  if (unsupportedTenantError) {\n    throw new CredentialUnavailableError(unsupportedTenantError);\n  }\n}\n\n/**\n * Connects to Azure using the user account signed in through the Azure Resources extension in Visual Studio Code.\n * Once the user has logged in via the extension, this credential can share the same refresh token\n * that is cached by the extension.\n */\nexport class VisualStudioCodeCredential implements TokenCredential {\n  private tenantId: string;\n  private additionallyAllowedTenantIds: string[];\n  private msalClient: MsalClient | undefined;\n  private options: VisualStudioCodeCredentialOptions;\n\n  /**\n   * Creates an instance of VisualStudioCodeCredential to use for automatically authenticating via VSCode.\n   *\n   * **Note**: `VisualStudioCodeCredential` is provided by a plugin package:\n   * `@azure/identity-vscode`. If this package is not installed, then authentication using\n   * `VisualStudioCodeCredential` will not be available.\n   *\n   * @param options - Options for configuring the client which makes the authentication request.\n   */\n  constructor(options?: VisualStudioCodeCredentialOptions) {\n    this.options = options || {};\n\n    if (options && options.tenantId) {\n      checkTenantId(logger, options.tenantId);\n      this.tenantId = options.tenantId;\n    } else {\n      this.tenantId = CommonTenantId;\n    }\n\n    this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(\n      options?.additionallyAllowedTenants,\n    );\n\n    checkUnsupportedTenant(this.tenantId);\n  }\n\n  /**\n   * Runs preparations for any further getToken request:\n   *   - Validates that the plugin is available.\n   *   - Loads the authentication record from VSCode if available.\n   *   - Creates the MSAL client with the loaded plugin and authentication record.\n   */\n  private async prepare(scopes: string[]): Promise<void> {\n    const tenantId =\n      processMultiTenantRequest(\n        this.tenantId,\n        this.options,\n        this.additionallyAllowedTenantIds,\n        logger,\n      ) || this.tenantId;\n\n    if (!hasVSCodePlugin() || !vsCodeAuthRecordPath) {\n      throw new CredentialUnavailableError(\n        \"Visual Studio Code Authentication is not available.\" +\n          \" Ensure you have have Azure Resources Extension installed in VS Code,\" +\n          \" signed into Azure via VS Code, installed the @azure/identity-vscode package,\" +\n          \" and properly configured the extension.\",\n      );\n    }\n\n    // Load the authentication record directly from the path\n    const authenticationRecord = await this.loadAuthRecord(vsCodeAuthRecordPath, scopes);\n\n    this.msalClient = createMsalClient(VSCodeClientId, tenantId, {\n      ...this.options,\n      isVSCodeCredential: true,\n      brokerOptions: {\n        enabled: true,\n        parentWindowHandle: new Uint8Array(0),\n        useDefaultBrokerAccount: true,\n      },\n      authenticationRecord,\n    });\n  }\n  /**\n   * The promise of the single preparation that will be executed at the first getToken request for an instance of this class.\n   */\n  private preparePromise: Promise<void> | undefined;\n\n  /**\n   * Runs preparations for any further getToken, but only once.\n   */\n  private prepareOnce(scopes: string[]): Promise<void> | undefined {\n    if (!this.preparePromise) {\n      this.preparePromise = this.prepare(scopes);\n    }\n    return this.preparePromise;\n  }\n\n  /**\n   * Returns the token found by searching VSCode's authentication cache or\n   * returns null if no token could be found.\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  public async getToken(\n    scopes: string | string[],\n    options?: GetTokenOptions,\n  ): Promise<AccessToken> {\n    // Load the plugin and authentication record only once\n    const scopeArray = ensureScopes(scopes);\n    await this.prepareOnce(scopeArray);\n\n    if (!this.msalClient) {\n      throw new CredentialUnavailableError(\n        \"Visual Studio Code Authentication failed to initialize.\" +\n          \" Ensure you have have Azure Resources Extension installed in VS Code,\" +\n          \" signed into Azure via VS Code, installed the @azure/identity-vscode package,\" +\n          \" and properly configured the extension.\",\n      );\n    }\n    // Disable automatic authentication to ensure that the user is not prompted interactively if no token is available\n    return this.msalClient.getTokenByInteractiveRequest(scopeArray, {\n      ...options,\n      disableAutomaticAuthentication: true,\n    });\n  }\n\n  /**\n   * Loads the authentication record from the specified path.\n   * @param authRecordPath - The path to the authentication record file.\n   * @param scopes - The list of scopes for which the token will have access.\n   * @returns The authentication record or undefined if loading fails.\n   */\n  private async loadAuthRecord(\n    authRecordPath: string,\n    scopes: string[],\n  ): Promise<AuthenticationRecord> {\n    try {\n      const authRecordContent = await readFile(authRecordPath, { encoding: \"utf8\" });\n      return deserializeAuthenticationRecord(authRecordContent);\n    } catch (error: any) {\n      logger.getToken.info(formatError(scopes, error));\n      throw new CredentialUnavailableError(\n        \"Cannot load authentication record in Visual Studio Code.\" +\n          \" Ensure you have have Azure Resources Extension installed in VS Code,\" +\n          \" signed into Azure via VS Code, installed the @azure/identity-vscode package,\" +\n          \" and properly configured the extension.\",\n      );\n    }\n  }\n}\n"]}