UNPKG

@azure/communication-common

Version:
152 lines (151 loc) 5.76 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var entraTokenCredential_exports = {}; __export(entraTokenCredential_exports, { EntraTokenCredential: () => EntraTokenCredential }); module.exports = __toCommonJS(entraTokenCredential_exports); var import_core_client = require("@azure-rest/core-client"); var import_core_rest_pipeline = require("@azure/core-rest-pipeline"); const TeamsExtensionScopePrefixes = [ "https://auth.msft.communication.azure.com/", "https://auth.msft.communication.azure.us/" ]; const CommunicationClientsScopePrefix = "https://communication.azure.com/clients/"; const ScopeValidationErrorMessage = `Scopes validation failed. Ensure all scopes start with one of ${[ ...TeamsExtensionScopePrefixes, CommunicationClientsScopePrefix ].join(", ")}.`; const TeamsExtensionEndpoint = "/access/teamsExtension/:exchangeAccessToken"; const TeamsExtensionApiVersion = "2025-06-30"; const CommunicationClientsEndpoint = "/access/entra/:exchangeAccessToken"; const CommunicationClientsApiVersion = "2025-03-02-preview"; class EntraTokenCredential { constructor(options) { this.options = options; this.client = (0, import_core_client.getClient)(options.resourceEndpoint); this.httpClient = (0, import_core_rest_pipeline.createDefaultHttpClient)(); this.options = options; this.options.scopes = this.options.scopes || [ "https://communication.azure.com/clients/.default" ]; this.isPending = this.getToken(); } options; isPending; result = { entraToken: void 0, acsToken: { token: "", expiresOnTimestamp: 0 } }; client; httpClient; async getToken(options) { if (options?.abortSignal?.aborted) { return { token: "", expiresOnTimestamp: 0 }; } if (!this.isPending) { this.isPending = this.getTokenInternal(options); } try { await this.isPending; } finally { this.isPending = null; } return this.result.acsToken; } async getTokenInternal(options) { const getTokenOptions = options?.abortSignal ? { abortSignal: options.abortSignal } : void 0; const token = await this.options.tokenCredential.getToken( this.options.scopes ? this.options.scopes : ["https://communication.azure.com/clients/.default"], getTokenOptions ); const currentDateTime = /* @__PURE__ */ new Date(); const tokenExpiresOn = new Date(this.result.acsToken.expiresOnTimestamp); if (token === null) { this.result = { entraToken: void 0, acsToken: { token: "", expiresOnTimestamp: 0 } }; } else if (this.result.acsToken.token === "" || token.token !== this.result.entraToken || tokenExpiresOn < currentDateTime) { const acsToken = await this.exchangeEntraToken( this.options.resourceEndpoint, token.token, getTokenOptions ); this.result = { entraToken: token.token, acsToken }; } return this.result.acsToken; } dispose() { this.result = { entraToken: void 0, acsToken: { token: "", expiresOnTimestamp: 0 } }; } async exchangeEntraToken(resourceEndpoint, entraToken, options) { const request = (0, import_core_rest_pipeline.createPipelineRequest)({ url: this.createRequestUri(resourceEndpoint), method: "POST", headers: (0, import_core_rest_pipeline.createHttpHeaders)({ Authorization: `Bearer ${entraToken}`, "Content-Type": "application/json", Accept: "application/json" }), abortSignal: options?.abortSignal, body: JSON.stringify({}) }); const response = await this.client.pipeline.sendRequest(this.httpClient, request); if (response.status !== 200 || !response.bodyAsText) { throw new Error( `Service request failed. Status: ${response.status}, Body: ${response.bodyAsText}` ); } const json = JSON.parse(response.bodyAsText); return { token: json.accessToken.token, expiresOnTimestamp: Date.parse(json.accessToken.expiresOn) }; } createRequestUri(resourceEndpoint) { const [endpoint, apiVersion] = this.determineEndpointAndApiVersion(); const requestUri = `${resourceEndpoint}${endpoint}?api-version=${apiVersion}`; return requestUri; } determineEndpointAndApiVersion() { if (!this.options.scopes || this.options.scopes.length === 0) { throw new Error(ScopeValidationErrorMessage); } if (this.options.scopes.every( (scope) => TeamsExtensionScopePrefixes.some((prefix) => scope.startsWith(prefix)) )) { return [TeamsExtensionEndpoint, TeamsExtensionApiVersion]; } if (this.options.scopes.every((scope) => scope.startsWith(CommunicationClientsScopePrefix))) { return [CommunicationClientsEndpoint, CommunicationClientsApiVersion]; } throw new Error(ScopeValidationErrorMessage); } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { EntraTokenCredential }); //# sourceMappingURL=entraTokenCredential.js.map