@azure/communication-common 2.4.2-alpha.20260210.1 → 2.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +1 -1
  2. package/dist/browser/credential/communicationAccessKeyCredentialPolicy.d.ts.map +1 -1
  3. package/dist/browser/credential/communicationAccessKeyCredentialPolicy.js +6 -10
  4. package/dist/browser/credential/communicationAccessKeyCredentialPolicy.js.map +1 -1
  5. package/dist/browser/entraTokenCredential.d.ts.map +1 -1
  6. package/dist/browser/entraTokenCredential.js +12 -7
  7. package/dist/browser/entraTokenCredential.js.map +1 -1
  8. package/dist/browser/index.d.ts +3 -3
  9. package/dist/browser/index.d.ts.map +1 -1
  10. package/dist/browser/index.js.map +1 -1
  11. package/dist/commonjs/autoRefreshTokenCredential.js +110 -95
  12. package/dist/commonjs/autoRefreshTokenCredential.js.map +7 -1
  13. package/dist/commonjs/azureCommunicationTokenCredential.js +64 -47
  14. package/dist/commonjs/azureCommunicationTokenCredential.js.map +7 -1
  15. package/dist/commonjs/communicationTokenCredential.js +16 -5
  16. package/dist/commonjs/communicationTokenCredential.js.map +7 -1
  17. package/dist/commonjs/credential/clientArguments.js +46 -40
  18. package/dist/commonjs/credential/clientArguments.js.map +7 -1
  19. package/dist/commonjs/credential/communicationAccessKeyCredentialPolicy.d.ts.map +1 -1
  20. package/dist/commonjs/credential/communicationAccessKeyCredentialPolicy.js +53 -42
  21. package/dist/commonjs/credential/communicationAccessKeyCredentialPolicy.js.map +7 -1
  22. package/dist/commonjs/credential/communicationAuthPolicy.js +39 -26
  23. package/dist/commonjs/credential/communicationAuthPolicy.js.map +7 -1
  24. package/dist/commonjs/credential/connectionString.js +39 -28
  25. package/dist/commonjs/credential/connectionString.js.map +7 -1
  26. package/dist/commonjs/credential/index.js +28 -10
  27. package/dist/commonjs/credential/index.js.map +7 -1
  28. package/dist/commonjs/entraTokenCredential.d.ts.map +1 -1
  29. package/dist/commonjs/entraTokenCredential.js +137 -113
  30. package/dist/commonjs/entraTokenCredential.js.map +7 -1
  31. package/dist/commonjs/identifierModelSerializer.js +172 -159
  32. package/dist/commonjs/identifierModelSerializer.js.map +7 -1
  33. package/dist/commonjs/identifierModels.js +183 -205
  34. package/dist/commonjs/identifierModels.js.map +7 -1
  35. package/dist/commonjs/index.d.ts +3 -3
  36. package/dist/commonjs/index.d.ts.map +1 -1
  37. package/dist/commonjs/index.js +35 -12
  38. package/dist/commonjs/index.js.map +7 -1
  39. package/dist/commonjs/staticTokenCredential.js +36 -20
  40. package/dist/commonjs/staticTokenCredential.js.map +7 -1
  41. package/dist/commonjs/tokenParser.js +33 -13
  42. package/dist/commonjs/tokenParser.js.map +7 -1
  43. package/dist/commonjs/tsdoc-metadata.json +1 -1
  44. package/dist/esm/credential/communicationAccessKeyCredentialPolicy.d.ts.map +1 -1
  45. package/dist/esm/credential/communicationAccessKeyCredentialPolicy.js +6 -10
  46. package/dist/esm/credential/communicationAccessKeyCredentialPolicy.js.map +1 -1
  47. package/dist/esm/entraTokenCredential.d.ts.map +1 -1
  48. package/dist/esm/entraTokenCredential.js +12 -7
  49. package/dist/esm/entraTokenCredential.js.map +1 -1
  50. package/dist/esm/index.d.ts +3 -3
  51. package/dist/esm/index.d.ts.map +1 -1
  52. package/dist/esm/index.js.map +1 -1
  53. package/dist/react-native/credential/communicationAccessKeyCredentialPolicy.d.ts.map +1 -1
  54. package/dist/react-native/credential/communicationAccessKeyCredentialPolicy.js +6 -10
  55. package/dist/react-native/credential/communicationAccessKeyCredentialPolicy.js.map +1 -1
  56. package/dist/react-native/entraTokenCredential.d.ts.map +1 -1
  57. package/dist/react-native/entraTokenCredential.js +12 -7
  58. package/dist/react-native/entraTokenCredential.js.map +1 -1
  59. package/dist/react-native/index.d.ts +3 -3
  60. package/dist/react-native/index.d.ts.map +1 -1
  61. package/dist/react-native/index.js.map +1 -1
  62. package/package.json +30 -37
  63. package/dist/browser/credential/cryptoUtils-browser.d.mts.map +0 -1
  64. package/dist/browser/credential/cryptoUtils-browser.mjs.map +0 -1
  65. package/dist/browser/credential/cryptoUtils.d.ts +0 -3
  66. package/dist/browser/credential/cryptoUtils.js +0 -19
  67. package/dist/browser/credential/encodeUtils-browser.d.mts +0 -4
  68. package/dist/browser/credential/encodeUtils-browser.d.mts.map +0 -1
  69. package/dist/browser/credential/encodeUtils-browser.mjs +0 -19
  70. package/dist/browser/credential/encodeUtils-browser.mjs.map +0 -1
  71. package/dist/commonjs/credential/cryptoUtils.d.ts +0 -3
  72. package/dist/commonjs/credential/cryptoUtils.d.ts.map +0 -1
  73. package/dist/commonjs/credential/cryptoUtils.js +0 -14
  74. package/dist/commonjs/credential/cryptoUtils.js.map +0 -1
  75. package/dist/esm/credential/cryptoUtils.d.ts +0 -3
  76. package/dist/esm/credential/cryptoUtils.d.ts.map +0 -1
  77. package/dist/esm/credential/cryptoUtils.js +0 -9
  78. package/dist/esm/credential/cryptoUtils.js.map +0 -1
  79. package/dist/esm/credential/encodeUtils-browser.d.mts +0 -4
  80. package/dist/esm/credential/encodeUtils-browser.d.mts.map +0 -1
  81. package/dist/esm/credential/encodeUtils-browser.mjs +0 -19
  82. package/dist/esm/credential/encodeUtils-browser.mjs.map +0 -1
  83. package/dist/react-native/credential/cryptoUtils.d.ts +0 -3
  84. package/dist/react-native/credential/cryptoUtils.d.ts.map +0 -1
  85. package/dist/react-native/credential/cryptoUtils.js +0 -9
  86. package/dist/react-native/credential/cryptoUtils.js.map +0 -1
  87. package/dist/react-native/credential/encodeUtils-browser.d.mts +0 -4
  88. package/dist/react-native/credential/encodeUtils-browser.d.mts.map +0 -1
  89. package/dist/react-native/credential/encodeUtils-browser.mjs +0 -19
  90. package/dist/react-native/credential/encodeUtils-browser.mjs.map +0 -1
@@ -1,22 +1,38 @@
1
- "use strict";
2
- // Copyright (c) Microsoft Corporation.
3
- // Licensed under the MIT License.
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.StaticTokenCredential = void 0;
6
- /**
7
- * StaticTokenCredential
8
- */
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var staticTokenCredential_exports = {};
19
+ __export(staticTokenCredential_exports, {
20
+ StaticTokenCredential: () => StaticTokenCredential
21
+ });
22
+ module.exports = __toCommonJS(staticTokenCredential_exports);
9
23
  class StaticTokenCredential {
10
- token;
11
- constructor(token) {
12
- this.token = token;
13
- }
14
- async getToken() {
15
- return this.token;
16
- }
17
- dispose() {
18
- /* intentionally empty */
19
- }
24
+ constructor(token) {
25
+ this.token = token;
26
+ }
27
+ token;
28
+ async getToken() {
29
+ return this.token;
30
+ }
31
+ dispose() {
32
+ }
20
33
  }
21
- exports.StaticTokenCredential = StaticTokenCredential;
22
- //# sourceMappingURL=staticTokenCredential.js.map
34
+ // Annotate the CommonJS export names for ESM import in node:
35
+ 0 && (module.exports = {
36
+ StaticTokenCredential
37
+ });
38
+ //# sourceMappingURL=staticTokenCredential.js.map
@@ -1 +1,7 @@
1
- {"version":3,"file":"staticTokenCredential.js","sourceRoot":"","sources":["../../src/staticTokenCredential.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;;;AAKlC;;GAEG;AACH,MAAa,qBAAqB;IACH;IAA7B,YAA6B,KAAkB;QAAlB,UAAK,GAAL,KAAK,CAAa;IAAG,CAAC;IAE5C,KAAK,CAAC,QAAQ;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAEM,OAAO;QACZ,yBAAyB;IAC3B,CAAC;CACF;AAVD,sDAUC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AccessToken } from \"@azure/core-auth\";\nimport type { TokenCredential } from \"./communicationTokenCredential.js\";\n\n/**\n * StaticTokenCredential\n */\nexport class StaticTokenCredential implements TokenCredential {\n constructor(private readonly token: AccessToken) {}\n\n public async getToken(): Promise<AccessToken> {\n return this.token;\n }\n\n public dispose(): void {\n /* intentionally empty */\n }\n}\n"]}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/staticTokenCredential.ts"],
4
+ "sourcesContent": ["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AccessToken } from \"@azure/core-auth\";\nimport type { TokenCredential } from \"./communicationTokenCredential.js\";\n\n/**\n * StaticTokenCredential\n */\nexport class StaticTokenCredential implements TokenCredential {\n constructor(private readonly token: AccessToken) {}\n\n public async getToken(): Promise<AccessToken> {\n return this.token;\n }\n\n public dispose(): void {\n /* intentionally empty */\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AASO,MAAM,sBAAiD;AAAA,EAC5D,YAA6B,OAAoB;AAApB;AAAA,EAAqB;AAAA,EAArB;AAAA,EAE7B,MAAa,WAAiC;AAC5C,WAAO,KAAK;AAAA,EACd;AAAA,EAEO,UAAgB;AAAA,EAEvB;AACF;",
6
+ "names": []
7
+ }
@@ -1,15 +1,35 @@
1
- "use strict";
2
- // Copyright (c) Microsoft Corporation.
3
- // Licensed under the MIT License.
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.parseToken = void 0;
6
- const jwt_decode_1 = require("jwt-decode");
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var tokenParser_exports = {};
19
+ __export(tokenParser_exports, {
20
+ parseToken: () => parseToken
21
+ });
22
+ module.exports = __toCommonJS(tokenParser_exports);
23
+ var import_jwt_decode = require("jwt-decode");
7
24
  const parseToken = (token) => {
8
- const { exp } = (0, jwt_decode_1.jwtDecode)(token);
9
- return {
10
- token,
11
- expiresOnTimestamp: exp * 1000,
12
- };
25
+ const { exp } = (0, import_jwt_decode.jwtDecode)(token);
26
+ return {
27
+ token,
28
+ expiresOnTimestamp: exp * 1e3
29
+ };
13
30
  };
14
- exports.parseToken = parseToken;
15
- //# sourceMappingURL=tokenParser.js.map
31
+ // Annotate the CommonJS export names for ESM import in node:
32
+ 0 && (module.exports = {
33
+ parseToken
34
+ });
35
+ //# sourceMappingURL=tokenParser.js.map
@@ -1 +1,7 @@
1
- {"version":3,"file":"tokenParser.js","sourceRoot":"","sources":["../../src/tokenParser.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;;;AAGlC,2CAAuC;AAMhC,MAAM,UAAU,GAAG,CAAC,KAAa,EAAe,EAAE;IACvD,MAAM,EAAE,GAAG,EAAE,GAAG,IAAA,sBAAS,EAAW,KAAK,CAAC,CAAC;IAC3C,OAAO;QACL,KAAK;QACL,kBAAkB,EAAE,GAAG,GAAG,IAAI;KAC/B,CAAC;AACJ,CAAC,CAAC;AANW,QAAA,UAAU,cAMrB","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AccessToken } from \"@azure/core-auth\";\nimport { jwtDecode } from \"jwt-decode\";\n\ninterface JwtToken {\n exp: number;\n}\n\nexport const parseToken = (token: string): AccessToken => {\n const { exp } = jwtDecode<JwtToken>(token);\n return {\n token,\n expiresOnTimestamp: exp * 1000,\n };\n};\n"]}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/tokenParser.ts"],
4
+ "sourcesContent": ["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AccessToken } from \"@azure/core-auth\";\nimport { jwtDecode } from \"jwt-decode\";\n\ninterface JwtToken {\n exp: number;\n}\n\nexport const parseToken = (token: string): AccessToken => {\n const { exp } = jwtDecode<JwtToken>(token);\n return {\n token,\n expiresOnTimestamp: exp * 1000,\n };\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,wBAA0B;AAMnB,MAAM,aAAa,CAAC,UAA+B;AACxD,QAAM,EAAE,IAAI,QAAI,6BAAoB,KAAK;AACzC,SAAO;AAAA,IACL;AAAA,IACA,oBAAoB,MAAM;AAAA,EAC5B;AACF;",
6
+ "names": []
7
+ }
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.56.3"
8
+ "packageVersion": "7.58.7"
9
9
  }
10
10
  ]
11
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"communicationAccessKeyCredentialPolicy.d.ts","sourceRoot":"","sources":["../../../src/credential/communicationAccessKeyCredentialPolicy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,cAAc,EAIf,MAAM,2BAA2B,CAAC;AAEnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAStD;;;;;GAKG;AACH,wBAAgB,4CAA4C,CAC1D,UAAU,EAAE,aAAa,GACxB,cAAc,CAgChB"}
1
+ {"version":3,"file":"communicationAccessKeyCredentialPolicy.d.ts","sourceRoot":"","sources":["../../../src/credential/communicationAccessKeyCredentialPolicy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,cAAc,EAIf,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAStD;;;;;GAKG;AACH,wBAAgB,4CAA4C,CAC1D,UAAU,EAAE,aAAa,GACxB,cAAc,CA4BhB"}
@@ -1,7 +1,6 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
- import { shaHMAC, shaHash } from "./cryptoUtils.js";
4
- import { isNodeLike } from "@azure/core-util";
3
+ import { computeSha256Hash, computeSha256Hmac } from "@azure/core-util";
5
4
  /**
6
5
  * CommunicationKeyCredentialPolicy provides a means of signing requests made through
7
6
  * the SmsClient.
@@ -19,19 +18,16 @@ export function createCommunicationAccessKeyCredentialPolicy(credential) {
19
18
  async sendRequest(request, next) {
20
19
  const verb = request.method.toUpperCase();
21
20
  const utcNow = new Date().toUTCString();
22
- const contentHash = await shaHash(request.body?.toString() || "");
21
+ const contentHash = await computeSha256Hash(request.body?.toString() || "", "base64");
23
22
  const dateHeader = "x-ms-date";
24
23
  const signedHeaders = `${dateHeader};host;x-ms-content-sha256`;
25
24
  const url = new URL(request.url);
26
25
  const query = url.searchParams.toString();
27
26
  const urlPathAndQuery = query ? `${url.pathname}?${query}` : url.pathname;
28
- const port = url.port;
29
- const hostAndPort = port ? `${url.host}:${port}` : url.host;
30
- const stringToSign = `${verb}\n${urlPathAndQuery}\n${utcNow};${hostAndPort};${contentHash}`;
31
- const signature = await shaHMAC(credential.key, stringToSign);
32
- if (isNodeLike) {
33
- request.headers.set("Host", hostAndPort || "");
34
- }
27
+ const stringToSign = `${verb}\n${urlPathAndQuery}\n${utcNow};${url.host};${contentHash}`;
28
+ const signature = await computeSha256Hmac(credential.key, stringToSign, "base64");
29
+ // Host is a forbidden header in browsers (silently ignored), but needed in Node.js
30
+ request.headers.set("Host", url.host);
35
31
  request.headers.set(dateHeader, utcNow);
36
32
  request.headers.set("x-ms-content-sha256", contentHash);
37
33
  request.headers.set("Authorization", `HMAC-SHA256 SignedHeaders=${signedHeaders}&Signature=${signature}`);
@@ -1 +1 @@
1
- {"version":3,"file":"communicationAccessKeyCredentialPolicy.js","sourceRoot":"","sources":["../../../src/credential/communicationAccessKeyCredentialPolicy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAQlC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;;GAGG;AACH,MAAM,sCAAsC,GAAG,wCAAwC,CAAC;AAExF;;;;;GAKG;AACH,MAAM,UAAU,4CAA4C,CAC1D,UAAyB;IAEzB,OAAO;QACL,IAAI,EAAE,sCAAsC;QAC5C,KAAK,CAAC,WAAW,CAAC,OAAwB,EAAE,IAAiB;YAC3D,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACxC,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YAClE,MAAM,UAAU,GAAG,WAAW,CAAC;YAC/B,MAAM,aAAa,GAAG,GAAG,UAAU,2BAA2B,CAAC;YAE/D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACjC,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;YAC1C,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,QAAQ,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC1E,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;YACtB,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;YAE5D,MAAM,YAAY,GAAG,GAAG,IAAI,KAAK,eAAe,KAAK,MAAM,IAAI,WAAW,IAAI,WAAW,EAAE,CAAC;YAC5F,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;YAE9D,IAAI,UAAU,EAAE,CAAC;gBACf,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC;YACjD,CAAC;YAED,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YACxC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,WAAW,CAAC,CAAC;YACxD,OAAO,CAAC,OAAO,CAAC,GAAG,CACjB,eAAe,EACf,6BAA6B,aAAa,cAAc,SAAS,EAAE,CACpE,CAAC;YACF,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type {\n PipelinePolicy,\n PipelineRequest,\n PipelineResponse,\n SendRequest,\n} from \"@azure/core-rest-pipeline\";\nimport { shaHMAC, shaHash } from \"./cryptoUtils.js\";\nimport type { KeyCredential } from \"@azure/core-auth\";\nimport { isNodeLike } from \"@azure/core-util\";\n\n/**\n * CommunicationKeyCredentialPolicy provides a means of signing requests made through\n * the SmsClient.\n */\nconst communicationAccessKeyCredentialPolicy = \"CommunicationAccessKeyCredentialPolicy\";\n\n/**\n * Creates an HTTP pipeline policy to authenticate a request using a `KeyCredential`.\n * @hidden\n *\n * @param credential - The key credential.\n */\nexport function createCommunicationAccessKeyCredentialPolicy(\n credential: KeyCredential,\n): PipelinePolicy {\n return {\n name: communicationAccessKeyCredentialPolicy,\n async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {\n const verb = request.method.toUpperCase();\n const utcNow = new Date().toUTCString();\n const contentHash = await shaHash(request.body?.toString() || \"\");\n const dateHeader = \"x-ms-date\";\n const signedHeaders = `${dateHeader};host;x-ms-content-sha256`;\n\n const url = new URL(request.url);\n const query = url.searchParams.toString();\n const urlPathAndQuery = query ? `${url.pathname}?${query}` : url.pathname;\n const port = url.port;\n const hostAndPort = port ? `${url.host}:${port}` : url.host;\n\n const stringToSign = `${verb}\\n${urlPathAndQuery}\\n${utcNow};${hostAndPort};${contentHash}`;\n const signature = await shaHMAC(credential.key, stringToSign);\n\n if (isNodeLike) {\n request.headers.set(\"Host\", hostAndPort || \"\");\n }\n\n request.headers.set(dateHeader, utcNow);\n request.headers.set(\"x-ms-content-sha256\", contentHash);\n request.headers.set(\n \"Authorization\",\n `HMAC-SHA256 SignedHeaders=${signedHeaders}&Signature=${signature}`,\n );\n return next(request);\n },\n };\n}\n"]}
1
+ {"version":3,"file":"communicationAccessKeyCredentialPolicy.js","sourceRoot":"","sources":["../../../src/credential/communicationAccessKeyCredentialPolicy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AASlC,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAExE;;;GAGG;AACH,MAAM,sCAAsC,GAAG,wCAAwC,CAAC;AAExF;;;;;GAKG;AACH,MAAM,UAAU,4CAA4C,CAC1D,UAAyB;IAEzB,OAAO;QACL,IAAI,EAAE,sCAAsC;QAC5C,KAAK,CAAC,WAAW,CAAC,OAAwB,EAAE,IAAiB;YAC3D,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACxC,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC;YACtF,MAAM,UAAU,GAAG,WAAW,CAAC;YAC/B,MAAM,aAAa,GAAG,GAAG,UAAU,2BAA2B,CAAC;YAE/D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACjC,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;YAC1C,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,QAAQ,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;YAE1E,MAAM,YAAY,GAAG,GAAG,IAAI,KAAK,eAAe,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC;YACzF,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC,UAAU,CAAC,GAAG,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;YAElF,mFAAmF;YACnF,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;YACtC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YACxC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,WAAW,CAAC,CAAC;YACxD,OAAO,CAAC,OAAO,CAAC,GAAG,CACjB,eAAe,EACf,6BAA6B,aAAa,cAAc,SAAS,EAAE,CACpE,CAAC;YACF,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type {\n PipelinePolicy,\n PipelineRequest,\n PipelineResponse,\n SendRequest,\n} from \"@azure/core-rest-pipeline\";\nimport type { KeyCredential } from \"@azure/core-auth\";\nimport { computeSha256Hash, computeSha256Hmac } from \"@azure/core-util\";\n\n/**\n * CommunicationKeyCredentialPolicy provides a means of signing requests made through\n * the SmsClient.\n */\nconst communicationAccessKeyCredentialPolicy = \"CommunicationAccessKeyCredentialPolicy\";\n\n/**\n * Creates an HTTP pipeline policy to authenticate a request using a `KeyCredential`.\n * @hidden\n *\n * @param credential - The key credential.\n */\nexport function createCommunicationAccessKeyCredentialPolicy(\n credential: KeyCredential,\n): PipelinePolicy {\n return {\n name: communicationAccessKeyCredentialPolicy,\n async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {\n const verb = request.method.toUpperCase();\n const utcNow = new Date().toUTCString();\n const contentHash = await computeSha256Hash(request.body?.toString() || \"\", \"base64\");\n const dateHeader = \"x-ms-date\";\n const signedHeaders = `${dateHeader};host;x-ms-content-sha256`;\n\n const url = new URL(request.url);\n const query = url.searchParams.toString();\n const urlPathAndQuery = query ? `${url.pathname}?${query}` : url.pathname;\n\n const stringToSign = `${verb}\\n${urlPathAndQuery}\\n${utcNow};${url.host};${contentHash}`;\n const signature = await computeSha256Hmac(credential.key, stringToSign, \"base64\");\n\n // Host is a forbidden header in browsers (silently ignored), but needed in Node.js\n request.headers.set(\"Host\", url.host);\n request.headers.set(dateHeader, utcNow);\n request.headers.set(\"x-ms-content-sha256\", contentHash);\n request.headers.set(\n \"Authorization\",\n `HMAC-SHA256 SignedHeaders=${signedHeaders}&Signature=${signature}`,\n );\n return next(request);\n },\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"entraTokenCredential.d.ts","sourceRoot":"","sources":["../../src/entraTokenCredential.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EACL,KAAK,eAAe,IAAI,kBAAkB,EAC1C,KAAK,4BAA4B,EAClC,MAAM,mCAAmC,CAAC;AAiB3C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,wCAAwC;IACvD;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,eAAe,EAAE,eAAe,CAAC;IACjC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,oBAAqB,YAAW,kBAAkB;IASjD,OAAO,CAAC,OAAO;IAR3B,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,MAAM,CAGZ;IACF,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAa;gBAEX,OAAO,EAAE,wCAAwC;IAYxD,QAAQ,CAAC,OAAO,CAAC,EAAE,4BAA4B,GAAG,OAAO,CAAC,WAAW,CAAC;YAoBrE,gBAAgB;IAmCvB,OAAO,IAAI,IAAI;YAOR,kBAAkB;IA8BhC,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,8BAA8B;CAiBvC"}
1
+ {"version":3,"file":"entraTokenCredential.d.ts","sourceRoot":"","sources":["../../src/entraTokenCredential.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EACL,KAAK,eAAe,IAAI,kBAAkB,EAC1C,KAAK,4BAA4B,EAClC,MAAM,mCAAmC,CAAC;AAwB3C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,wCAAwC;IACvD;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,eAAe,EAAE,eAAe,CAAC;IACjC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,oBAAqB,YAAW,kBAAkB;IASjD,OAAO,CAAC,OAAO;IAR3B,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,MAAM,CAGZ;IACF,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAa;gBAEX,OAAO,EAAE,wCAAwC;IAYxD,QAAQ,CAAC,OAAO,CAAC,EAAE,4BAA4B,GAAG,OAAO,CAAC,WAAW,CAAC;YAoBrE,gBAAgB;IAmCvB,OAAO,IAAI,IAAI;YAOR,kBAAkB;IA8BhC,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,8BAA8B;CAmBvC"}
@@ -2,8 +2,15 @@
2
2
  // Licensed under the MIT License.
3
3
  import { getClient } from "@azure-rest/core-client";
4
4
  import { createDefaultHttpClient, createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
5
- const TeamsExtensionScopePrefix = "https://auth.msft.communication.azure.com/";
5
+ const TeamsExtensionScopePrefixes = [
6
+ "https://auth.msft.communication.azure.com/",
7
+ "https://auth.msft.communication.azure.us/",
8
+ ];
6
9
  const CommunicationClientsScopePrefix = "https://communication.azure.com/clients/";
10
+ const ScopeValidationErrorMessage = `Scopes validation failed. Ensure all scopes start with one of ${[
11
+ ...TeamsExtensionScopePrefixes,
12
+ CommunicationClientsScopePrefix,
13
+ ].join(", ")}.`;
7
14
  const TeamsExtensionEndpoint = "/access/teamsExtension/:exchangeAccessToken";
8
15
  const TeamsExtensionApiVersion = "2025-06-30";
9
16
  const CommunicationClientsEndpoint = "/access/entra/:exchangeAccessToken";
@@ -107,17 +114,15 @@ export class EntraTokenCredential {
107
114
  }
108
115
  determineEndpointAndApiVersion() {
109
116
  if (!this.options.scopes || this.options.scopes.length === 0) {
110
- throw new Error(`Scopes validation failed. Ensure all scopes start with either {TeamsExtensionScopePrefix} or {CommunicationClientsScopePrefix}.`);
117
+ throw new Error(ScopeValidationErrorMessage);
111
118
  }
112
- else if (this.options.scopes.every((scope) => scope.startsWith(TeamsExtensionScopePrefix))) {
119
+ if (this.options.scopes.every((scope) => TeamsExtensionScopePrefixes.some((prefix) => scope.startsWith(prefix)))) {
113
120
  return [TeamsExtensionEndpoint, TeamsExtensionApiVersion];
114
121
  }
115
- else if (this.options.scopes.every((scope) => scope.startsWith(CommunicationClientsScopePrefix))) {
122
+ if (this.options.scopes.every((scope) => scope.startsWith(CommunicationClientsScopePrefix))) {
116
123
  return [CommunicationClientsEndpoint, CommunicationClientsApiVersion];
117
124
  }
118
- else {
119
- throw new Error(`Scopes validation failed. Ensure all scopes start with either {TeamsExtensionScopePrefix} or {CommunicationClientsScopePrefix}.`);
120
- }
125
+ throw new Error(ScopeValidationErrorMessage);
121
126
  }
122
127
  }
123
128
  //# sourceMappingURL=entraTokenCredential.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"entraTokenCredential.js","sourceRoot":"","sources":["../../src/entraTokenCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { type AccessToken, type TokenCredential } from \"@azure/core-auth\";\nimport {\n type TokenCredential as AcsTokenCredential,\n type CommunicationGetTokenOptions,\n} from \"./communicationTokenCredential.js\";\nimport { type AbortSignalLike } from \"@azure/abort-controller\";\nimport { type Client, getClient } from \"@azure-rest/core-client\";\nimport {\n type HttpClient,\n createDefaultHttpClient,\n createHttpHeaders,\n createPipelineRequest,\n} from \"@azure/core-rest-pipeline\";\n\nconst TeamsExtensionScopePrefix = \"https://auth.msft.communication.azure.com/\";\nconst CommunicationClientsScopePrefix = \"https://communication.azure.com/clients/\";\nconst TeamsExtensionEndpoint = \"/access/teamsExtension/:exchangeAccessToken\";\nconst TeamsExtensionApiVersion = \"2025-06-30\";\nconst CommunicationClientsEndpoint = \"/access/entra/:exchangeAccessToken\";\nconst CommunicationClientsApiVersion = \"2025-03-02-preview\";\n\nexport interface ExchangeTokenResponse {\n identity: string;\n accessToken: {\n token: string;\n expiresOn: string;\n };\n}\n\n/**\n * The Entra Communication Token Options.\n */\nexport interface EntraCommunicationTokenCredentialOptions {\n /**\n * The Azure Communication Service resource endpoint URL, e.g. https://myResource.communication.azure.com.\n */\n resourceEndpoint: string;\n /**\n * The Entra ID token credential.\n */\n tokenCredential: TokenCredential;\n /**\n * The scopes for retrieving the Entra ID access token.\n */\n scopes?: string[];\n}\n\n/**\n * Represents a credential that exchanges an Entra token for an Azure Communication Services (ACS) token, enabling access to ACS resources.\n */\nexport class EntraTokenCredential implements AcsTokenCredential {\n private isPending: Promise<AccessToken> | null;\n private result = {\n entraToken: undefined as string | undefined,\n acsToken: { token: \"\", expiresOnTimestamp: 0 },\n };\n private client: Client;\n private httpClient: HttpClient;\n\n constructor(private options: EntraCommunicationTokenCredentialOptions) {\n this.client = getClient(options.resourceEndpoint);\n this.httpClient = createDefaultHttpClient();\n this.options = options;\n this.options.scopes = this.options.scopes || [\n \"https://communication.azure.com/clients/.default\",\n ];\n\n // immediately fetch the token to pre-warm\n this.isPending = this.getToken();\n }\n\n public async getToken(options?: CommunicationGetTokenOptions): Promise<AccessToken> {\n if (options?.abortSignal?.aborted) {\n return { token: \"\", expiresOnTimestamp: 0 };\n }\n\n // we're awaiting the token fetch, so we don't want to start another one\n // however, we're ignoring the new abortSignal, unfortunately\n if (!this.isPending) {\n this.isPending = this.getTokenInternal(options);\n }\n\n try {\n await this.isPending;\n } finally {\n this.isPending = null;\n }\n\n return this.result.acsToken;\n }\n\n private async getTokenInternal(options?: CommunicationGetTokenOptions): Promise<AccessToken> {\n const getTokenOptions = options?.abortSignal ? { abortSignal: options.abortSignal } : undefined;\n const token = await this.options.tokenCredential.getToken(\n this.options.scopes\n ? this.options.scopes\n : [\"https://communication.azure.com/clients/.default\"],\n getTokenOptions,\n );\n const currentDateTime = new Date();\n const tokenExpiresOn = new Date(this.result.acsToken.expiresOnTimestamp);\n\n if (token === null) {\n this.result = {\n entraToken: undefined,\n acsToken: { token: \"\", expiresOnTimestamp: 0 },\n };\n } else if (\n this.result.acsToken.token === \"\" ||\n token.token !== this.result.entraToken ||\n tokenExpiresOn < currentDateTime\n ) {\n const acsToken = await this.exchangeEntraToken(\n this.options.resourceEndpoint,\n token.token,\n getTokenOptions,\n );\n this.result = {\n entraToken: token.token,\n acsToken,\n };\n }\n\n return this.result.acsToken;\n }\n\n public dispose(): void {\n this.result = {\n entraToken: undefined,\n acsToken: { token: \"\", expiresOnTimestamp: 0 },\n };\n }\n\n private async exchangeEntraToken(\n resourceEndpoint: string,\n entraToken: string,\n options?: { abortSignal: AbortSignalLike },\n ): Promise<AccessToken> {\n const request = createPipelineRequest({\n url: this.createRequestUri(resourceEndpoint),\n method: \"POST\",\n headers: createHttpHeaders({\n Authorization: `Bearer ${entraToken}`,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n }),\n abortSignal: options?.abortSignal,\n body: JSON.stringify({}),\n });\n const response = await this.client.pipeline.sendRequest(this.httpClient, request);\n\n if (response.status !== 200 || !response.bodyAsText) {\n throw new Error(\n `Service request failed. Status: ${response.status}, Body: ${response.bodyAsText}`,\n );\n }\n const json = JSON.parse(response.bodyAsText) as ExchangeTokenResponse;\n return {\n token: json.accessToken.token,\n expiresOnTimestamp: Date.parse(json.accessToken.expiresOn),\n };\n }\n\n private createRequestUri(resourceEndpoint: string): string {\n const [endpoint, apiVersion] = this.determineEndpointAndApiVersion();\n const requestUri = `${resourceEndpoint}${endpoint}?api-version=${apiVersion}`;\n return requestUri;\n }\n\n private determineEndpointAndApiVersion(): [string, string] {\n if (!this.options.scopes || this.options.scopes.length === 0) {\n throw new Error(\n `Scopes validation failed. Ensure all scopes start with either {TeamsExtensionScopePrefix} or {CommunicationClientsScopePrefix}.`,\n );\n } else if (this.options.scopes.every((scope) => scope.startsWith(TeamsExtensionScopePrefix))) {\n return [TeamsExtensionEndpoint, TeamsExtensionApiVersion];\n } else if (\n this.options.scopes.every((scope) => scope.startsWith(CommunicationClientsScopePrefix))\n ) {\n return [CommunicationClientsEndpoint, CommunicationClientsApiVersion];\n } else {\n throw new Error(\n `Scopes validation failed. Ensure all scopes start with either {TeamsExtensionScopePrefix} or {CommunicationClientsScopePrefix}.`,\n );\n }\n }\n}\n"]}
1
+ {"version":3,"file":"entraTokenCredential.js","sourceRoot":"","sources":["../../src/entraTokenCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { type AccessToken, type TokenCredential } from \"@azure/core-auth\";\nimport {\n type TokenCredential as AcsTokenCredential,\n type CommunicationGetTokenOptions,\n} from \"./communicationTokenCredential.js\";\nimport { type AbortSignalLike } from \"@azure/abort-controller\";\nimport { type Client, getClient } from \"@azure-rest/core-client\";\nimport {\n type HttpClient,\n createDefaultHttpClient,\n createHttpHeaders,\n createPipelineRequest,\n} from \"@azure/core-rest-pipeline\";\n\nconst TeamsExtensionScopePrefixes = [\n \"https://auth.msft.communication.azure.com/\",\n \"https://auth.msft.communication.azure.us/\",\n];\nconst CommunicationClientsScopePrefix = \"https://communication.azure.com/clients/\";\nconst ScopeValidationErrorMessage = `Scopes validation failed. Ensure all scopes start with one of ${[\n ...TeamsExtensionScopePrefixes,\n CommunicationClientsScopePrefix,\n].join(\", \")}.`;\nconst TeamsExtensionEndpoint = \"/access/teamsExtension/:exchangeAccessToken\";\nconst TeamsExtensionApiVersion = \"2025-06-30\";\nconst CommunicationClientsEndpoint = \"/access/entra/:exchangeAccessToken\";\nconst CommunicationClientsApiVersion = \"2025-03-02-preview\";\n\nexport interface ExchangeTokenResponse {\n identity: string;\n accessToken: {\n token: string;\n expiresOn: string;\n };\n}\n\n/**\n * The Entra Communication Token Options.\n */\nexport interface EntraCommunicationTokenCredentialOptions {\n /**\n * The Azure Communication Service resource endpoint URL, e.g. https://myResource.communication.azure.com.\n */\n resourceEndpoint: string;\n /**\n * The Entra ID token credential.\n */\n tokenCredential: TokenCredential;\n /**\n * The scopes for retrieving the Entra ID access token.\n */\n scopes?: string[];\n}\n\n/**\n * Represents a credential that exchanges an Entra token for an Azure Communication Services (ACS) token, enabling access to ACS resources.\n */\nexport class EntraTokenCredential implements AcsTokenCredential {\n private isPending: Promise<AccessToken> | null;\n private result = {\n entraToken: undefined as string | undefined,\n acsToken: { token: \"\", expiresOnTimestamp: 0 },\n };\n private client: Client;\n private httpClient: HttpClient;\n\n constructor(private options: EntraCommunicationTokenCredentialOptions) {\n this.client = getClient(options.resourceEndpoint);\n this.httpClient = createDefaultHttpClient();\n this.options = options;\n this.options.scopes = this.options.scopes || [\n \"https://communication.azure.com/clients/.default\",\n ];\n\n // immediately fetch the token to pre-warm\n this.isPending = this.getToken();\n }\n\n public async getToken(options?: CommunicationGetTokenOptions): Promise<AccessToken> {\n if (options?.abortSignal?.aborted) {\n return { token: \"\", expiresOnTimestamp: 0 };\n }\n\n // we're awaiting the token fetch, so we don't want to start another one\n // however, we're ignoring the new abortSignal, unfortunately\n if (!this.isPending) {\n this.isPending = this.getTokenInternal(options);\n }\n\n try {\n await this.isPending;\n } finally {\n this.isPending = null;\n }\n\n return this.result.acsToken;\n }\n\n private async getTokenInternal(options?: CommunicationGetTokenOptions): Promise<AccessToken> {\n const getTokenOptions = options?.abortSignal ? { abortSignal: options.abortSignal } : undefined;\n const token = await this.options.tokenCredential.getToken(\n this.options.scopes\n ? this.options.scopes\n : [\"https://communication.azure.com/clients/.default\"],\n getTokenOptions,\n );\n const currentDateTime = new Date();\n const tokenExpiresOn = new Date(this.result.acsToken.expiresOnTimestamp);\n\n if (token === null) {\n this.result = {\n entraToken: undefined,\n acsToken: { token: \"\", expiresOnTimestamp: 0 },\n };\n } else if (\n this.result.acsToken.token === \"\" ||\n token.token !== this.result.entraToken ||\n tokenExpiresOn < currentDateTime\n ) {\n const acsToken = await this.exchangeEntraToken(\n this.options.resourceEndpoint,\n token.token,\n getTokenOptions,\n );\n this.result = {\n entraToken: token.token,\n acsToken,\n };\n }\n\n return this.result.acsToken;\n }\n\n public dispose(): void {\n this.result = {\n entraToken: undefined,\n acsToken: { token: \"\", expiresOnTimestamp: 0 },\n };\n }\n\n private async exchangeEntraToken(\n resourceEndpoint: string,\n entraToken: string,\n options?: { abortSignal: AbortSignalLike },\n ): Promise<AccessToken> {\n const request = createPipelineRequest({\n url: this.createRequestUri(resourceEndpoint),\n method: \"POST\",\n headers: createHttpHeaders({\n Authorization: `Bearer ${entraToken}`,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n }),\n abortSignal: options?.abortSignal,\n body: JSON.stringify({}),\n });\n const response = await this.client.pipeline.sendRequest(this.httpClient, request);\n\n if (response.status !== 200 || !response.bodyAsText) {\n throw new Error(\n `Service request failed. Status: ${response.status}, Body: ${response.bodyAsText}`,\n );\n }\n const json = JSON.parse(response.bodyAsText) as ExchangeTokenResponse;\n return {\n token: json.accessToken.token,\n expiresOnTimestamp: Date.parse(json.accessToken.expiresOn),\n };\n }\n\n private createRequestUri(resourceEndpoint: string): string {\n const [endpoint, apiVersion] = this.determineEndpointAndApiVersion();\n const requestUri = `${resourceEndpoint}${endpoint}?api-version=${apiVersion}`;\n return requestUri;\n }\n\n private determineEndpointAndApiVersion(): [string, string] {\n if (!this.options.scopes || this.options.scopes.length === 0) {\n throw new Error(ScopeValidationErrorMessage);\n }\n\n if (\n this.options.scopes.every((scope) =>\n TeamsExtensionScopePrefixes.some((prefix) => scope.startsWith(prefix)),\n )\n ) {\n return [TeamsExtensionEndpoint, TeamsExtensionApiVersion];\n }\n\n if (this.options.scopes.every((scope) => scope.startsWith(CommunicationClientsScopePrefix))) {\n return [CommunicationClientsEndpoint, CommunicationClientsApiVersion];\n }\n\n throw new Error(ScopeValidationErrorMessage);\n }\n}\n"]}
@@ -1,7 +1,7 @@
1
- export { CommunicationTokenCredential, CommunicationGetTokenOptions, } from "./communicationTokenCredential.js";
1
+ export type { CommunicationTokenCredential, CommunicationGetTokenOptions, } from "./communicationTokenCredential.js";
2
2
  export { AzureCommunicationTokenCredential } from "./azureCommunicationTokenCredential.js";
3
- export { CommunicationTokenRefreshOptions } from "./autoRefreshTokenCredential.js";
4
- export { EntraCommunicationTokenCredentialOptions } from "./entraTokenCredential.js";
3
+ export type { CommunicationTokenRefreshOptions } from "./autoRefreshTokenCredential.js";
4
+ export type { EntraCommunicationTokenCredentialOptions } from "./entraTokenCredential.js";
5
5
  export * from "./credential/index.js";
6
6
  export * from "./identifierModels.js";
7
7
  export * from "./identifierModelSerializer.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,iCAAiC,EAAE,MAAM,wCAAwC,CAAC;AAC3F,OAAO,EAAE,gCAAgC,EAAE,MAAM,iCAAiC,CAAC;AACnF,OAAO,EAAE,wCAAwC,EAAE,MAAM,2BAA2B,CAAC;AACrF,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,iCAAiC,EAAE,MAAM,wCAAwC,CAAC;AAC3F,YAAY,EAAE,gCAAgC,EAAE,MAAM,iCAAiC,CAAC;AACxF,YAAY,EAAE,wCAAwC,EAAE,MAAM,2BAA2B,CAAC;AAC1F,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAMlC,OAAO,EAAE,iCAAiC,EAAE,MAAM,wCAAwC,CAAC;AAG3F,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nexport {\n CommunicationTokenCredential,\n CommunicationGetTokenOptions,\n} from \"./communicationTokenCredential.js\";\nexport { AzureCommunicationTokenCredential } from \"./azureCommunicationTokenCredential.js\";\nexport { CommunicationTokenRefreshOptions } from \"./autoRefreshTokenCredential.js\";\nexport { EntraCommunicationTokenCredentialOptions } from \"./entraTokenCredential.js\";\nexport * from \"./credential/index.js\";\nexport * from \"./identifierModels.js\";\nexport * from \"./identifierModelSerializer.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAMlC,OAAO,EAAE,iCAAiC,EAAE,MAAM,wCAAwC,CAAC;AAG3F,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nexport type {\n CommunicationTokenCredential,\n CommunicationGetTokenOptions,\n} from \"./communicationTokenCredential.js\";\nexport { AzureCommunicationTokenCredential } from \"./azureCommunicationTokenCredential.js\";\nexport type { CommunicationTokenRefreshOptions } from \"./autoRefreshTokenCredential.js\";\nexport type { EntraCommunicationTokenCredentialOptions } from \"./entraTokenCredential.js\";\nexport * from \"./credential/index.js\";\nexport * from \"./identifierModels.js\";\nexport * from \"./identifierModelSerializer.js\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"communicationAccessKeyCredentialPolicy.d.ts","sourceRoot":"","sources":["../../../src/credential/communicationAccessKeyCredentialPolicy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,cAAc,EAIf,MAAM,2BAA2B,CAAC;AAEnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAStD;;;;;GAKG;AACH,wBAAgB,4CAA4C,CAC1D,UAAU,EAAE,aAAa,GACxB,cAAc,CAgChB"}
1
+ {"version":3,"file":"communicationAccessKeyCredentialPolicy.d.ts","sourceRoot":"","sources":["../../../src/credential/communicationAccessKeyCredentialPolicy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,cAAc,EAIf,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAStD;;;;;GAKG;AACH,wBAAgB,4CAA4C,CAC1D,UAAU,EAAE,aAAa,GACxB,cAAc,CA4BhB"}
@@ -1,7 +1,6 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
- import { shaHMAC, shaHash } from "./cryptoUtils.js";
4
- import { isNodeLike } from "@azure/core-util";
3
+ import { computeSha256Hash, computeSha256Hmac } from "@azure/core-util";
5
4
  /**
6
5
  * CommunicationKeyCredentialPolicy provides a means of signing requests made through
7
6
  * the SmsClient.
@@ -19,19 +18,16 @@ export function createCommunicationAccessKeyCredentialPolicy(credential) {
19
18
  async sendRequest(request, next) {
20
19
  const verb = request.method.toUpperCase();
21
20
  const utcNow = new Date().toUTCString();
22
- const contentHash = await shaHash(request.body?.toString() || "");
21
+ const contentHash = await computeSha256Hash(request.body?.toString() || "", "base64");
23
22
  const dateHeader = "x-ms-date";
24
23
  const signedHeaders = `${dateHeader};host;x-ms-content-sha256`;
25
24
  const url = new URL(request.url);
26
25
  const query = url.searchParams.toString();
27
26
  const urlPathAndQuery = query ? `${url.pathname}?${query}` : url.pathname;
28
- const port = url.port;
29
- const hostAndPort = port ? `${url.host}:${port}` : url.host;
30
- const stringToSign = `${verb}\n${urlPathAndQuery}\n${utcNow};${hostAndPort};${contentHash}`;
31
- const signature = await shaHMAC(credential.key, stringToSign);
32
- if (isNodeLike) {
33
- request.headers.set("Host", hostAndPort || "");
34
- }
27
+ const stringToSign = `${verb}\n${urlPathAndQuery}\n${utcNow};${url.host};${contentHash}`;
28
+ const signature = await computeSha256Hmac(credential.key, stringToSign, "base64");
29
+ // Host is a forbidden header in browsers (silently ignored), but needed in Node.js
30
+ request.headers.set("Host", url.host);
35
31
  request.headers.set(dateHeader, utcNow);
36
32
  request.headers.set("x-ms-content-sha256", contentHash);
37
33
  request.headers.set("Authorization", `HMAC-SHA256 SignedHeaders=${signedHeaders}&Signature=${signature}`);
@@ -1 +1 @@
1
- {"version":3,"file":"communicationAccessKeyCredentialPolicy.js","sourceRoot":"","sources":["../../../src/credential/communicationAccessKeyCredentialPolicy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAQlC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;;GAGG;AACH,MAAM,sCAAsC,GAAG,wCAAwC,CAAC;AAExF;;;;;GAKG;AACH,MAAM,UAAU,4CAA4C,CAC1D,UAAyB;IAEzB,OAAO;QACL,IAAI,EAAE,sCAAsC;QAC5C,KAAK,CAAC,WAAW,CAAC,OAAwB,EAAE,IAAiB;YAC3D,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACxC,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YAClE,MAAM,UAAU,GAAG,WAAW,CAAC;YAC/B,MAAM,aAAa,GAAG,GAAG,UAAU,2BAA2B,CAAC;YAE/D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACjC,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;YAC1C,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,QAAQ,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC1E,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;YACtB,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;YAE5D,MAAM,YAAY,GAAG,GAAG,IAAI,KAAK,eAAe,KAAK,MAAM,IAAI,WAAW,IAAI,WAAW,EAAE,CAAC;YAC5F,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;YAE9D,IAAI,UAAU,EAAE,CAAC;gBACf,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC;YACjD,CAAC;YAED,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YACxC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,WAAW,CAAC,CAAC;YACxD,OAAO,CAAC,OAAO,CAAC,GAAG,CACjB,eAAe,EACf,6BAA6B,aAAa,cAAc,SAAS,EAAE,CACpE,CAAC;YACF,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type {\n PipelinePolicy,\n PipelineRequest,\n PipelineResponse,\n SendRequest,\n} from \"@azure/core-rest-pipeline\";\nimport { shaHMAC, shaHash } from \"./cryptoUtils.js\";\nimport type { KeyCredential } from \"@azure/core-auth\";\nimport { isNodeLike } from \"@azure/core-util\";\n\n/**\n * CommunicationKeyCredentialPolicy provides a means of signing requests made through\n * the SmsClient.\n */\nconst communicationAccessKeyCredentialPolicy = \"CommunicationAccessKeyCredentialPolicy\";\n\n/**\n * Creates an HTTP pipeline policy to authenticate a request using a `KeyCredential`.\n * @hidden\n *\n * @param credential - The key credential.\n */\nexport function createCommunicationAccessKeyCredentialPolicy(\n credential: KeyCredential,\n): PipelinePolicy {\n return {\n name: communicationAccessKeyCredentialPolicy,\n async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {\n const verb = request.method.toUpperCase();\n const utcNow = new Date().toUTCString();\n const contentHash = await shaHash(request.body?.toString() || \"\");\n const dateHeader = \"x-ms-date\";\n const signedHeaders = `${dateHeader};host;x-ms-content-sha256`;\n\n const url = new URL(request.url);\n const query = url.searchParams.toString();\n const urlPathAndQuery = query ? `${url.pathname}?${query}` : url.pathname;\n const port = url.port;\n const hostAndPort = port ? `${url.host}:${port}` : url.host;\n\n const stringToSign = `${verb}\\n${urlPathAndQuery}\\n${utcNow};${hostAndPort};${contentHash}`;\n const signature = await shaHMAC(credential.key, stringToSign);\n\n if (isNodeLike) {\n request.headers.set(\"Host\", hostAndPort || \"\");\n }\n\n request.headers.set(dateHeader, utcNow);\n request.headers.set(\"x-ms-content-sha256\", contentHash);\n request.headers.set(\n \"Authorization\",\n `HMAC-SHA256 SignedHeaders=${signedHeaders}&Signature=${signature}`,\n );\n return next(request);\n },\n };\n}\n"]}
1
+ {"version":3,"file":"communicationAccessKeyCredentialPolicy.js","sourceRoot":"","sources":["../../../src/credential/communicationAccessKeyCredentialPolicy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AASlC,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAExE;;;GAGG;AACH,MAAM,sCAAsC,GAAG,wCAAwC,CAAC;AAExF;;;;;GAKG;AACH,MAAM,UAAU,4CAA4C,CAC1D,UAAyB;IAEzB,OAAO;QACL,IAAI,EAAE,sCAAsC;QAC5C,KAAK,CAAC,WAAW,CAAC,OAAwB,EAAE,IAAiB;YAC3D,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACxC,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC;YACtF,MAAM,UAAU,GAAG,WAAW,CAAC;YAC/B,MAAM,aAAa,GAAG,GAAG,UAAU,2BAA2B,CAAC;YAE/D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACjC,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;YAC1C,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,QAAQ,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;YAE1E,MAAM,YAAY,GAAG,GAAG,IAAI,KAAK,eAAe,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC;YACzF,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC,UAAU,CAAC,GAAG,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;YAElF,mFAAmF;YACnF,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;YACtC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YACxC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,WAAW,CAAC,CAAC;YACxD,OAAO,CAAC,OAAO,CAAC,GAAG,CACjB,eAAe,EACf,6BAA6B,aAAa,cAAc,SAAS,EAAE,CACpE,CAAC;YACF,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type {\n PipelinePolicy,\n PipelineRequest,\n PipelineResponse,\n SendRequest,\n} from \"@azure/core-rest-pipeline\";\nimport type { KeyCredential } from \"@azure/core-auth\";\nimport { computeSha256Hash, computeSha256Hmac } from \"@azure/core-util\";\n\n/**\n * CommunicationKeyCredentialPolicy provides a means of signing requests made through\n * the SmsClient.\n */\nconst communicationAccessKeyCredentialPolicy = \"CommunicationAccessKeyCredentialPolicy\";\n\n/**\n * Creates an HTTP pipeline policy to authenticate a request using a `KeyCredential`.\n * @hidden\n *\n * @param credential - The key credential.\n */\nexport function createCommunicationAccessKeyCredentialPolicy(\n credential: KeyCredential,\n): PipelinePolicy {\n return {\n name: communicationAccessKeyCredentialPolicy,\n async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {\n const verb = request.method.toUpperCase();\n const utcNow = new Date().toUTCString();\n const contentHash = await computeSha256Hash(request.body?.toString() || \"\", \"base64\");\n const dateHeader = \"x-ms-date\";\n const signedHeaders = `${dateHeader};host;x-ms-content-sha256`;\n\n const url = new URL(request.url);\n const query = url.searchParams.toString();\n const urlPathAndQuery = query ? `${url.pathname}?${query}` : url.pathname;\n\n const stringToSign = `${verb}\\n${urlPathAndQuery}\\n${utcNow};${url.host};${contentHash}`;\n const signature = await computeSha256Hmac(credential.key, stringToSign, \"base64\");\n\n // Host is a forbidden header in browsers (silently ignored), but needed in Node.js\n request.headers.set(\"Host\", url.host);\n request.headers.set(dateHeader, utcNow);\n request.headers.set(\"x-ms-content-sha256\", contentHash);\n request.headers.set(\n \"Authorization\",\n `HMAC-SHA256 SignedHeaders=${signedHeaders}&Signature=${signature}`,\n );\n return next(request);\n },\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"entraTokenCredential.d.ts","sourceRoot":"","sources":["../../src/entraTokenCredential.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EACL,KAAK,eAAe,IAAI,kBAAkB,EAC1C,KAAK,4BAA4B,EAClC,MAAM,mCAAmC,CAAC;AAiB3C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,wCAAwC;IACvD;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,eAAe,EAAE,eAAe,CAAC;IACjC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,oBAAqB,YAAW,kBAAkB;IASjD,OAAO,CAAC,OAAO;IAR3B,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,MAAM,CAGZ;IACF,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAa;gBAEX,OAAO,EAAE,wCAAwC;IAYxD,QAAQ,CAAC,OAAO,CAAC,EAAE,4BAA4B,GAAG,OAAO,CAAC,WAAW,CAAC;YAoBrE,gBAAgB;IAmCvB,OAAO,IAAI,IAAI;YAOR,kBAAkB;IA8BhC,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,8BAA8B;CAiBvC"}
1
+ {"version":3,"file":"entraTokenCredential.d.ts","sourceRoot":"","sources":["../../src/entraTokenCredential.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EACL,KAAK,eAAe,IAAI,kBAAkB,EAC1C,KAAK,4BAA4B,EAClC,MAAM,mCAAmC,CAAC;AAwB3C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,wCAAwC;IACvD;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,eAAe,EAAE,eAAe,CAAC;IACjC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,oBAAqB,YAAW,kBAAkB;IASjD,OAAO,CAAC,OAAO;IAR3B,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,MAAM,CAGZ;IACF,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAa;gBAEX,OAAO,EAAE,wCAAwC;IAYxD,QAAQ,CAAC,OAAO,CAAC,EAAE,4BAA4B,GAAG,OAAO,CAAC,WAAW,CAAC;YAoBrE,gBAAgB;IAmCvB,OAAO,IAAI,IAAI;YAOR,kBAAkB;IA8BhC,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,8BAA8B;CAmBvC"}
@@ -2,8 +2,15 @@
2
2
  // Licensed under the MIT License.
3
3
  import { getClient } from "@azure-rest/core-client";
4
4
  import { createDefaultHttpClient, createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
5
- const TeamsExtensionScopePrefix = "https://auth.msft.communication.azure.com/";
5
+ const TeamsExtensionScopePrefixes = [
6
+ "https://auth.msft.communication.azure.com/",
7
+ "https://auth.msft.communication.azure.us/",
8
+ ];
6
9
  const CommunicationClientsScopePrefix = "https://communication.azure.com/clients/";
10
+ const ScopeValidationErrorMessage = `Scopes validation failed. Ensure all scopes start with one of ${[
11
+ ...TeamsExtensionScopePrefixes,
12
+ CommunicationClientsScopePrefix,
13
+ ].join(", ")}.`;
7
14
  const TeamsExtensionEndpoint = "/access/teamsExtension/:exchangeAccessToken";
8
15
  const TeamsExtensionApiVersion = "2025-06-30";
9
16
  const CommunicationClientsEndpoint = "/access/entra/:exchangeAccessToken";
@@ -107,17 +114,15 @@ export class EntraTokenCredential {
107
114
  }
108
115
  determineEndpointAndApiVersion() {
109
116
  if (!this.options.scopes || this.options.scopes.length === 0) {
110
- throw new Error(`Scopes validation failed. Ensure all scopes start with either {TeamsExtensionScopePrefix} or {CommunicationClientsScopePrefix}.`);
117
+ throw new Error(ScopeValidationErrorMessage);
111
118
  }
112
- else if (this.options.scopes.every((scope) => scope.startsWith(TeamsExtensionScopePrefix))) {
119
+ if (this.options.scopes.every((scope) => TeamsExtensionScopePrefixes.some((prefix) => scope.startsWith(prefix)))) {
113
120
  return [TeamsExtensionEndpoint, TeamsExtensionApiVersion];
114
121
  }
115
- else if (this.options.scopes.every((scope) => scope.startsWith(CommunicationClientsScopePrefix))) {
122
+ if (this.options.scopes.every((scope) => scope.startsWith(CommunicationClientsScopePrefix))) {
116
123
  return [CommunicationClientsEndpoint, CommunicationClientsApiVersion];
117
124
  }
118
- else {
119
- throw new Error(`Scopes validation failed. Ensure all scopes start with either {TeamsExtensionScopePrefix} or {CommunicationClientsScopePrefix}.`);
120
- }
125
+ throw new Error(ScopeValidationErrorMessage);
121
126
  }
122
127
  }
123
128
  //# sourceMappingURL=entraTokenCredential.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"entraTokenCredential.js","sourceRoot":"","sources":["../../src/entraTokenCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { type AccessToken, type TokenCredential } from \"@azure/core-auth\";\nimport {\n type TokenCredential as AcsTokenCredential,\n type CommunicationGetTokenOptions,\n} from \"./communicationTokenCredential.js\";\nimport { type AbortSignalLike } from \"@azure/abort-controller\";\nimport { type Client, getClient } from \"@azure-rest/core-client\";\nimport {\n type HttpClient,\n createDefaultHttpClient,\n createHttpHeaders,\n createPipelineRequest,\n} from \"@azure/core-rest-pipeline\";\n\nconst TeamsExtensionScopePrefix = \"https://auth.msft.communication.azure.com/\";\nconst CommunicationClientsScopePrefix = \"https://communication.azure.com/clients/\";\nconst TeamsExtensionEndpoint = \"/access/teamsExtension/:exchangeAccessToken\";\nconst TeamsExtensionApiVersion = \"2025-06-30\";\nconst CommunicationClientsEndpoint = \"/access/entra/:exchangeAccessToken\";\nconst CommunicationClientsApiVersion = \"2025-03-02-preview\";\n\nexport interface ExchangeTokenResponse {\n identity: string;\n accessToken: {\n token: string;\n expiresOn: string;\n };\n}\n\n/**\n * The Entra Communication Token Options.\n */\nexport interface EntraCommunicationTokenCredentialOptions {\n /**\n * The Azure Communication Service resource endpoint URL, e.g. https://myResource.communication.azure.com.\n */\n resourceEndpoint: string;\n /**\n * The Entra ID token credential.\n */\n tokenCredential: TokenCredential;\n /**\n * The scopes for retrieving the Entra ID access token.\n */\n scopes?: string[];\n}\n\n/**\n * Represents a credential that exchanges an Entra token for an Azure Communication Services (ACS) token, enabling access to ACS resources.\n */\nexport class EntraTokenCredential implements AcsTokenCredential {\n private isPending: Promise<AccessToken> | null;\n private result = {\n entraToken: undefined as string | undefined,\n acsToken: { token: \"\", expiresOnTimestamp: 0 },\n };\n private client: Client;\n private httpClient: HttpClient;\n\n constructor(private options: EntraCommunicationTokenCredentialOptions) {\n this.client = getClient(options.resourceEndpoint);\n this.httpClient = createDefaultHttpClient();\n this.options = options;\n this.options.scopes = this.options.scopes || [\n \"https://communication.azure.com/clients/.default\",\n ];\n\n // immediately fetch the token to pre-warm\n this.isPending = this.getToken();\n }\n\n public async getToken(options?: CommunicationGetTokenOptions): Promise<AccessToken> {\n if (options?.abortSignal?.aborted) {\n return { token: \"\", expiresOnTimestamp: 0 };\n }\n\n // we're awaiting the token fetch, so we don't want to start another one\n // however, we're ignoring the new abortSignal, unfortunately\n if (!this.isPending) {\n this.isPending = this.getTokenInternal(options);\n }\n\n try {\n await this.isPending;\n } finally {\n this.isPending = null;\n }\n\n return this.result.acsToken;\n }\n\n private async getTokenInternal(options?: CommunicationGetTokenOptions): Promise<AccessToken> {\n const getTokenOptions = options?.abortSignal ? { abortSignal: options.abortSignal } : undefined;\n const token = await this.options.tokenCredential.getToken(\n this.options.scopes\n ? this.options.scopes\n : [\"https://communication.azure.com/clients/.default\"],\n getTokenOptions,\n );\n const currentDateTime = new Date();\n const tokenExpiresOn = new Date(this.result.acsToken.expiresOnTimestamp);\n\n if (token === null) {\n this.result = {\n entraToken: undefined,\n acsToken: { token: \"\", expiresOnTimestamp: 0 },\n };\n } else if (\n this.result.acsToken.token === \"\" ||\n token.token !== this.result.entraToken ||\n tokenExpiresOn < currentDateTime\n ) {\n const acsToken = await this.exchangeEntraToken(\n this.options.resourceEndpoint,\n token.token,\n getTokenOptions,\n );\n this.result = {\n entraToken: token.token,\n acsToken,\n };\n }\n\n return this.result.acsToken;\n }\n\n public dispose(): void {\n this.result = {\n entraToken: undefined,\n acsToken: { token: \"\", expiresOnTimestamp: 0 },\n };\n }\n\n private async exchangeEntraToken(\n resourceEndpoint: string,\n entraToken: string,\n options?: { abortSignal: AbortSignalLike },\n ): Promise<AccessToken> {\n const request = createPipelineRequest({\n url: this.createRequestUri(resourceEndpoint),\n method: \"POST\",\n headers: createHttpHeaders({\n Authorization: `Bearer ${entraToken}`,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n }),\n abortSignal: options?.abortSignal,\n body: JSON.stringify({}),\n });\n const response = await this.client.pipeline.sendRequest(this.httpClient, request);\n\n if (response.status !== 200 || !response.bodyAsText) {\n throw new Error(\n `Service request failed. Status: ${response.status}, Body: ${response.bodyAsText}`,\n );\n }\n const json = JSON.parse(response.bodyAsText) as ExchangeTokenResponse;\n return {\n token: json.accessToken.token,\n expiresOnTimestamp: Date.parse(json.accessToken.expiresOn),\n };\n }\n\n private createRequestUri(resourceEndpoint: string): string {\n const [endpoint, apiVersion] = this.determineEndpointAndApiVersion();\n const requestUri = `${resourceEndpoint}${endpoint}?api-version=${apiVersion}`;\n return requestUri;\n }\n\n private determineEndpointAndApiVersion(): [string, string] {\n if (!this.options.scopes || this.options.scopes.length === 0) {\n throw new Error(\n `Scopes validation failed. Ensure all scopes start with either {TeamsExtensionScopePrefix} or {CommunicationClientsScopePrefix}.`,\n );\n } else if (this.options.scopes.every((scope) => scope.startsWith(TeamsExtensionScopePrefix))) {\n return [TeamsExtensionEndpoint, TeamsExtensionApiVersion];\n } else if (\n this.options.scopes.every((scope) => scope.startsWith(CommunicationClientsScopePrefix))\n ) {\n return [CommunicationClientsEndpoint, CommunicationClientsApiVersion];\n } else {\n throw new Error(\n `Scopes validation failed. Ensure all scopes start with either {TeamsExtensionScopePrefix} or {CommunicationClientsScopePrefix}.`,\n );\n }\n }\n}\n"]}
1
+ {"version":3,"file":"entraTokenCredential.js","sourceRoot":"","sources":["../../src/entraTokenCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { type AccessToken, type TokenCredential } from \"@azure/core-auth\";\nimport {\n type TokenCredential as AcsTokenCredential,\n type CommunicationGetTokenOptions,\n} from \"./communicationTokenCredential.js\";\nimport { type AbortSignalLike } from \"@azure/abort-controller\";\nimport { type Client, getClient } from \"@azure-rest/core-client\";\nimport {\n type HttpClient,\n createDefaultHttpClient,\n createHttpHeaders,\n createPipelineRequest,\n} from \"@azure/core-rest-pipeline\";\n\nconst TeamsExtensionScopePrefixes = [\n \"https://auth.msft.communication.azure.com/\",\n \"https://auth.msft.communication.azure.us/\",\n];\nconst CommunicationClientsScopePrefix = \"https://communication.azure.com/clients/\";\nconst ScopeValidationErrorMessage = `Scopes validation failed. Ensure all scopes start with one of ${[\n ...TeamsExtensionScopePrefixes,\n CommunicationClientsScopePrefix,\n].join(\", \")}.`;\nconst TeamsExtensionEndpoint = \"/access/teamsExtension/:exchangeAccessToken\";\nconst TeamsExtensionApiVersion = \"2025-06-30\";\nconst CommunicationClientsEndpoint = \"/access/entra/:exchangeAccessToken\";\nconst CommunicationClientsApiVersion = \"2025-03-02-preview\";\n\nexport interface ExchangeTokenResponse {\n identity: string;\n accessToken: {\n token: string;\n expiresOn: string;\n };\n}\n\n/**\n * The Entra Communication Token Options.\n */\nexport interface EntraCommunicationTokenCredentialOptions {\n /**\n * The Azure Communication Service resource endpoint URL, e.g. https://myResource.communication.azure.com.\n */\n resourceEndpoint: string;\n /**\n * The Entra ID token credential.\n */\n tokenCredential: TokenCredential;\n /**\n * The scopes for retrieving the Entra ID access token.\n */\n scopes?: string[];\n}\n\n/**\n * Represents a credential that exchanges an Entra token for an Azure Communication Services (ACS) token, enabling access to ACS resources.\n */\nexport class EntraTokenCredential implements AcsTokenCredential {\n private isPending: Promise<AccessToken> | null;\n private result = {\n entraToken: undefined as string | undefined,\n acsToken: { token: \"\", expiresOnTimestamp: 0 },\n };\n private client: Client;\n private httpClient: HttpClient;\n\n constructor(private options: EntraCommunicationTokenCredentialOptions) {\n this.client = getClient(options.resourceEndpoint);\n this.httpClient = createDefaultHttpClient();\n this.options = options;\n this.options.scopes = this.options.scopes || [\n \"https://communication.azure.com/clients/.default\",\n ];\n\n // immediately fetch the token to pre-warm\n this.isPending = this.getToken();\n }\n\n public async getToken(options?: CommunicationGetTokenOptions): Promise<AccessToken> {\n if (options?.abortSignal?.aborted) {\n return { token: \"\", expiresOnTimestamp: 0 };\n }\n\n // we're awaiting the token fetch, so we don't want to start another one\n // however, we're ignoring the new abortSignal, unfortunately\n if (!this.isPending) {\n this.isPending = this.getTokenInternal(options);\n }\n\n try {\n await this.isPending;\n } finally {\n this.isPending = null;\n }\n\n return this.result.acsToken;\n }\n\n private async getTokenInternal(options?: CommunicationGetTokenOptions): Promise<AccessToken> {\n const getTokenOptions = options?.abortSignal ? { abortSignal: options.abortSignal } : undefined;\n const token = await this.options.tokenCredential.getToken(\n this.options.scopes\n ? this.options.scopes\n : [\"https://communication.azure.com/clients/.default\"],\n getTokenOptions,\n );\n const currentDateTime = new Date();\n const tokenExpiresOn = new Date(this.result.acsToken.expiresOnTimestamp);\n\n if (token === null) {\n this.result = {\n entraToken: undefined,\n acsToken: { token: \"\", expiresOnTimestamp: 0 },\n };\n } else if (\n this.result.acsToken.token === \"\" ||\n token.token !== this.result.entraToken ||\n tokenExpiresOn < currentDateTime\n ) {\n const acsToken = await this.exchangeEntraToken(\n this.options.resourceEndpoint,\n token.token,\n getTokenOptions,\n );\n this.result = {\n entraToken: token.token,\n acsToken,\n };\n }\n\n return this.result.acsToken;\n }\n\n public dispose(): void {\n this.result = {\n entraToken: undefined,\n acsToken: { token: \"\", expiresOnTimestamp: 0 },\n };\n }\n\n private async exchangeEntraToken(\n resourceEndpoint: string,\n entraToken: string,\n options?: { abortSignal: AbortSignalLike },\n ): Promise<AccessToken> {\n const request = createPipelineRequest({\n url: this.createRequestUri(resourceEndpoint),\n method: \"POST\",\n headers: createHttpHeaders({\n Authorization: `Bearer ${entraToken}`,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n }),\n abortSignal: options?.abortSignal,\n body: JSON.stringify({}),\n });\n const response = await this.client.pipeline.sendRequest(this.httpClient, request);\n\n if (response.status !== 200 || !response.bodyAsText) {\n throw new Error(\n `Service request failed. Status: ${response.status}, Body: ${response.bodyAsText}`,\n );\n }\n const json = JSON.parse(response.bodyAsText) as ExchangeTokenResponse;\n return {\n token: json.accessToken.token,\n expiresOnTimestamp: Date.parse(json.accessToken.expiresOn),\n };\n }\n\n private createRequestUri(resourceEndpoint: string): string {\n const [endpoint, apiVersion] = this.determineEndpointAndApiVersion();\n const requestUri = `${resourceEndpoint}${endpoint}?api-version=${apiVersion}`;\n return requestUri;\n }\n\n private determineEndpointAndApiVersion(): [string, string] {\n if (!this.options.scopes || this.options.scopes.length === 0) {\n throw new Error(ScopeValidationErrorMessage);\n }\n\n if (\n this.options.scopes.every((scope) =>\n TeamsExtensionScopePrefixes.some((prefix) => scope.startsWith(prefix)),\n )\n ) {\n return [TeamsExtensionEndpoint, TeamsExtensionApiVersion];\n }\n\n if (this.options.scopes.every((scope) => scope.startsWith(CommunicationClientsScopePrefix))) {\n return [CommunicationClientsEndpoint, CommunicationClientsApiVersion];\n }\n\n throw new Error(ScopeValidationErrorMessage);\n }\n}\n"]}
@@ -1,7 +1,7 @@
1
- export { CommunicationTokenCredential, CommunicationGetTokenOptions, } from "./communicationTokenCredential.js";
1
+ export type { CommunicationTokenCredential, CommunicationGetTokenOptions, } from "./communicationTokenCredential.js";
2
2
  export { AzureCommunicationTokenCredential } from "./azureCommunicationTokenCredential.js";
3
- export { CommunicationTokenRefreshOptions } from "./autoRefreshTokenCredential.js";
4
- export { EntraCommunicationTokenCredentialOptions } from "./entraTokenCredential.js";
3
+ export type { CommunicationTokenRefreshOptions } from "./autoRefreshTokenCredential.js";
4
+ export type { EntraCommunicationTokenCredentialOptions } from "./entraTokenCredential.js";
5
5
  export * from "./credential/index.js";
6
6
  export * from "./identifierModels.js";
7
7
  export * from "./identifierModelSerializer.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,iCAAiC,EAAE,MAAM,wCAAwC,CAAC;AAC3F,OAAO,EAAE,gCAAgC,EAAE,MAAM,iCAAiC,CAAC;AACnF,OAAO,EAAE,wCAAwC,EAAE,MAAM,2BAA2B,CAAC;AACrF,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,iCAAiC,EAAE,MAAM,wCAAwC,CAAC;AAC3F,YAAY,EAAE,gCAAgC,EAAE,MAAM,iCAAiC,CAAC;AACxF,YAAY,EAAE,wCAAwC,EAAE,MAAM,2BAA2B,CAAC;AAC1F,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAMlC,OAAO,EAAE,iCAAiC,EAAE,MAAM,wCAAwC,CAAC;AAG3F,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nexport {\n CommunicationTokenCredential,\n CommunicationGetTokenOptions,\n} from \"./communicationTokenCredential.js\";\nexport { AzureCommunicationTokenCredential } from \"./azureCommunicationTokenCredential.js\";\nexport { CommunicationTokenRefreshOptions } from \"./autoRefreshTokenCredential.js\";\nexport { EntraCommunicationTokenCredentialOptions } from \"./entraTokenCredential.js\";\nexport * from \"./credential/index.js\";\nexport * from \"./identifierModels.js\";\nexport * from \"./identifierModelSerializer.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAMlC,OAAO,EAAE,iCAAiC,EAAE,MAAM,wCAAwC,CAAC;AAG3F,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nexport type {\n CommunicationTokenCredential,\n CommunicationGetTokenOptions,\n} from \"./communicationTokenCredential.js\";\nexport { AzureCommunicationTokenCredential } from \"./azureCommunicationTokenCredential.js\";\nexport type { CommunicationTokenRefreshOptions } from \"./autoRefreshTokenCredential.js\";\nexport type { EntraCommunicationTokenCredentialOptions } from \"./entraTokenCredential.js\";\nexport * from \"./credential/index.js\";\nexport * from \"./identifierModels.js\";\nexport * from \"./identifierModelSerializer.js\";\n"]}