@azure/container-registry 1.0.0-beta.3 → 1.0.0

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 (72) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +70 -37
  3. package/dist/index.js +1255 -1123
  4. package/dist/index.js.map +1 -1
  5. package/dist-esm/src/containerRegistryChallengeHandler.js +35 -38
  6. package/dist-esm/src/containerRegistryChallengeHandler.js.map +1 -1
  7. package/dist-esm/src/containerRegistryClient.js +69 -50
  8. package/dist-esm/src/containerRegistryClient.js.map +1 -1
  9. package/dist-esm/src/containerRegistryTokenCredential.js +39 -126
  10. package/dist-esm/src/containerRegistryTokenCredential.js.map +1 -1
  11. package/dist-esm/src/containerRepository.js +100 -63
  12. package/dist-esm/src/containerRepository.js.map +1 -1
  13. package/dist-esm/src/generated/generatedClient.js +7 -6
  14. package/dist-esm/src/generated/generatedClient.js.map +1 -1
  15. package/dist-esm/src/generated/generatedClientContext.js +13 -2
  16. package/dist-esm/src/generated/generatedClientContext.js.map +1 -1
  17. package/dist-esm/src/generated/index.js +1 -0
  18. package/dist-esm/src/generated/index.js.map +1 -1
  19. package/dist-esm/src/generated/models/index.js +61 -1
  20. package/dist-esm/src/generated/models/index.js.map +1 -1
  21. package/dist-esm/src/generated/models/mappers.js +514 -557
  22. package/dist-esm/src/generated/models/mappers.js.map +1 -1
  23. package/dist-esm/src/generated/models/parameters.js +87 -7
  24. package/dist-esm/src/generated/models/parameters.js.map +1 -1
  25. package/dist-esm/src/generated/operations/authentication.js +28 -8
  26. package/dist-esm/src/generated/operations/authentication.js.map +1 -1
  27. package/dist-esm/src/generated/operations/containerRegistry.js +27 -7
  28. package/dist-esm/src/generated/operations/containerRegistry.js.map +1 -1
  29. package/dist-esm/src/generated/operations/containerRegistryBlob.js +2 -2
  30. package/dist-esm/src/generated/operations/containerRegistryBlob.js.map +1 -1
  31. package/dist-esm/src/generated/operationsInterfaces/authentication.js +9 -0
  32. package/dist-esm/src/generated/operationsInterfaces/authentication.js.map +1 -0
  33. package/dist-esm/src/generated/operationsInterfaces/containerRegistry.js +9 -0
  34. package/dist-esm/src/generated/operationsInterfaces/containerRegistry.js.map +1 -0
  35. package/dist-esm/src/generated/operationsInterfaces/containerRegistryBlob.js +9 -0
  36. package/dist-esm/src/generated/operationsInterfaces/containerRegistryBlob.js.map +1 -0
  37. package/dist-esm/src/generated/operationsInterfaces/index.js +11 -0
  38. package/dist-esm/src/generated/operationsInterfaces/index.js.map +1 -0
  39. package/dist-esm/src/index.js.map +1 -1
  40. package/dist-esm/src/models.js +43 -2
  41. package/dist-esm/src/models.js.map +1 -1
  42. package/dist-esm/src/registryArtifact.js +176 -135
  43. package/dist-esm/src/registryArtifact.js.map +1 -1
  44. package/dist-esm/src/tracing.js +1 -1
  45. package/dist-esm/src/tracing.js.map +1 -1
  46. package/dist-esm/src/transformations.js +2 -2
  47. package/dist-esm/src/transformations.js.map +1 -1
  48. package/dist-esm/src/{base64.browser.js → utils/base64.browser.js} +0 -0
  49. package/dist-esm/src/utils/base64.browser.js.map +1 -0
  50. package/dist-esm/src/{base64.js → utils/base64.js} +0 -0
  51. package/dist-esm/src/utils/base64.js.map +1 -0
  52. package/dist-esm/src/{utils.js → utils/helpers.js} +1 -1
  53. package/dist-esm/src/utils/helpers.js.map +1 -0
  54. package/dist-esm/src/{tokenCycler.js → utils/tokenCycler.js} +29 -34
  55. package/dist-esm/src/utils/tokenCycler.js.map +1 -0
  56. package/dist-esm/src/{url.browser.js → utils/url.browser.js} +0 -0
  57. package/dist-esm/src/utils/url.browser.js.map +1 -0
  58. package/dist-esm/src/{url.js → utils/url.js} +0 -0
  59. package/dist-esm/src/utils/url.js.map +1 -0
  60. package/dist-esm/src/{wwwAuthenticateParser.js → utils/wwwAuthenticateParser.js} +0 -0
  61. package/dist-esm/src/utils/wwwAuthenticateParser.js.map +1 -0
  62. package/package.json +22 -25
  63. package/types/container-registry.d.ts +258 -83
  64. package/dist-esm/src/base64.browser.js.map +0 -1
  65. package/dist-esm/src/base64.js.map +0 -1
  66. package/dist-esm/src/constants.js +0 -4
  67. package/dist-esm/src/constants.js.map +0 -1
  68. package/dist-esm/src/tokenCycler.js.map +0 -1
  69. package/dist-esm/src/url.browser.js.map +0 -1
  70. package/dist-esm/src/url.js.map +0 -1
  71. package/dist-esm/src/utils.js.map +0 -1
  72. package/dist-esm/src/wwwAuthenticateParser.js.map +0 -1
@@ -1,8 +1,7 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
- import { __awaiter } from "tslib";
4
- import { parseWWWAuthenticate } from "./wwwAuthenticateParser";
5
- import { createTokenCycler } from "./tokenCycler";
3
+ import { parseWWWAuthenticate } from "./utils/wwwAuthenticateParser";
4
+ import { createTokenCycler } from "./utils/tokenCycler";
6
5
  const fiveMinutesInMs = 5 * 60 * 1000;
7
6
  /**
8
7
  * Handles challenge based authentication for Container Registry Service.
@@ -27,7 +26,7 @@ export class ChallengeHandler {
27
26
  this.credential = credential;
28
27
  this.options = options;
29
28
  this.cycler = createTokenCycler(credential, {
30
- refreshWindowInMs: fiveMinutesInMs
29
+ refreshWindowInMs: fiveMinutesInMs,
31
30
  });
32
31
  }
33
32
  authorizeRequest(_options) {
@@ -36,41 +35,39 @@ export class ChallengeHandler {
36
35
  /**
37
36
  * Updates the authentication context based on the challenge.
38
37
  */
39
- authorizeRequestOnChallenge(options) {
38
+ async authorizeRequestOnChallenge(options) {
40
39
  var _a;
41
- return __awaiter(this, void 0, void 0, function* () {
42
- // Once we're here, we've completed Step 1.
43
- const challenge = (_a = options.response) === null || _a === void 0 ? void 0 : _a.headers.get("WWW-Authenticate");
44
- if (!challenge) {
45
- throw new Error("Failed to retrieve challenge from response headers");
46
- }
47
- // Step 2: Parse challenge string to retrieve serviceName and scope, where scope is the ACR Scope
48
- const { service, scope } = parseWWWAuthenticate(challenge);
49
- if (!service) {
50
- throw new Error("Failed to retrieve 'service' from challenge");
51
- }
52
- if (!scope) {
53
- throw new Error("Failed to retrieve 'scope' from challenge");
54
- }
55
- // Step 3: Exchange AAD Access Token for ACR Refresh Token
56
- // For anonymous access, we send the request with grant_type=password and an empty ACR refresh token
57
- // For non-anonymous access, we get an AAD token then exchange it for an ACR fresh token
58
- let grantType;
59
- let acrRefreshToken;
60
- if (this.credential.isAnonymousAccess) {
61
- grantType = "password";
62
- acrRefreshToken = "";
63
- }
64
- else {
65
- grantType = "refresh_token";
66
- acrRefreshToken = (yield this.cycler.getToken(scope, Object.assign(Object.assign({}, options), { service }))).token;
67
- }
68
- // Step 4: Send in acrRefreshToken and get back acrAccessToken
69
- const acrAccessToken = yield this.credential.tokenService.ExchangeAcrRefreshTokenForAcrAccessTokenAsync(acrRefreshToken, service, scope, grantType, this.options);
70
- // Step 5 - Authorize Request. At this point we're done with AAD and using an ACR access token.
71
- options.request.headers.set("Authorization", `Bearer ${acrAccessToken}`);
72
- return true;
73
- });
40
+ // Once we're here, we've completed Step 1.
41
+ const challenge = (_a = options.response) === null || _a === void 0 ? void 0 : _a.headers.get("WWW-Authenticate");
42
+ if (!challenge) {
43
+ throw new Error("Failed to retrieve challenge from response headers");
44
+ }
45
+ // Step 2: Parse challenge string to retrieve serviceName and scope, where scope is the ACR Scope
46
+ const { service, scope } = parseWWWAuthenticate(challenge);
47
+ if (!service) {
48
+ throw new Error("Failed to retrieve 'service' from challenge");
49
+ }
50
+ if (!scope) {
51
+ throw new Error("Failed to retrieve 'scope' from challenge");
52
+ }
53
+ // Step 3: Exchange AAD Access Token for ACR Refresh Token
54
+ // For anonymous access, we send the request with grant_type=password and an empty ACR refresh token
55
+ // For non-anonymous access, we get an AAD token then exchange it for an ACR fresh token
56
+ let grantType;
57
+ let acrRefreshToken;
58
+ if (this.credential.isAnonymousAccess) {
59
+ grantType = "password";
60
+ acrRefreshToken = "";
61
+ }
62
+ else {
63
+ grantType = "refresh_token";
64
+ acrRefreshToken = (await this.cycler.getToken(scope, Object.assign(Object.assign({}, options), { service }))).token;
65
+ }
66
+ // Step 4: Send in acrRefreshToken and get back acrAccessToken
67
+ const acrAccessToken = await this.credential.tokenService.ExchangeAcrRefreshTokenForAcrAccessTokenAsync(acrRefreshToken, service, scope, grantType, this.options);
68
+ // Step 5 - Authorize Request. At this point we're done with AAD and using an ACR access token.
69
+ options.request.headers.set("Authorization", `Bearer ${acrAccessToken}`);
70
+ return true;
74
71
  }
75
72
  }
76
73
  //# sourceMappingURL=containerRegistryChallengeHandler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"containerRegistryChallengeHandler.js","sourceRoot":"","sources":["../../src/containerRegistryChallengeHandler.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAQlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAK/D,OAAO,EAAwB,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAExE,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAEtC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,gBAAgB;IAE3B,YACU,UAAmD,EACnD,UAAiD,EAAE;QADnD,eAAU,GAAV,UAAU,CAAyC;QACnD,YAAO,GAAP,OAAO,CAA4C;QAE3D,IAAI,CAAC,MAAM,GAAG,iBAAiB,CAAC,UAAU,EAAE;YAC1C,iBAAiB,EAAE,eAAe;SACnC,CAAC,CAAC;IACL,CAAC;IAED,gBAAgB,CAAC,QAAiC;QAChD,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACG,2BAA2B,CAAC,OAA2C;;;YAC3E,2CAA2C;YAC3C,MAAM,SAAS,GAAG,MAAA,OAAO,CAAC,QAAQ,0CAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;YACpE,IAAI,CAAC,SAAS,EAAE;gBACd,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;aACvE;YACD,iGAAiG;YACjG,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;YAE3D,IAAI,CAAC,OAAO,EAAE;gBACZ,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;aAChE;YAED,IAAI,CAAC,KAAK,EAAE;gBACV,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;aAC9D;YAED,0DAA0D;YAC1D,sGAAsG;YACtG,0FAA0F;YAC1F,IAAI,SAAuC,CAAC;YAC5C,IAAI,eAAuB,CAAC;YAC5B,IAAI,IAAI,CAAC,UAAU,CAAC,iBAAiB,EAAE;gBACrC,SAAS,GAAG,UAAU,CAAC;gBACvB,eAAe,GAAG,EAAE,CAAC;aACtB;iBAAM;gBACL,SAAS,GAAG,eAAe,CAAC;gBAC5B,eAAe,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,kCAAO,OAAO,KAAE,OAAO,IAAG,CAAC,CAAC,KAAK,CAAC;aACtF;YAED,8DAA8D;YAC9D,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,6CAA6C,CACrG,eAAe,EACf,OAAO,EACP,KAAK,EACL,SAAS,EACT,IAAI,CAAC,OAAO,CACb,CAAC;YAEF,gGAAgG;YAChG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,cAAc,EAAE,CAAC,CAAC;YAEzE,OAAO,IAAI,CAAC;;KACb;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { GetTokenOptions } from \"@azure/core-auth\";\nimport {\n AuthorizeRequestOnChallengeOptions,\n ChallengeCallbacks,\n AuthorizeRequestOptions\n} from \"@azure/core-rest-pipeline\";\nimport { parseWWWAuthenticate } from \"./wwwAuthenticateParser\";\nimport {\n ContainerRegistryGetTokenOptions,\n ContainerRegistryRefreshTokenCredential\n} from \"./containerRegistryTokenCredential\";\nimport { AccessTokenRefresher, createTokenCycler } from \"./tokenCycler\";\n\nconst fiveMinutesInMs = 5 * 60 * 1000;\n\n/**\n * Handles challenge based authentication for Container Registry Service.\n *```\n * The challenge-based authorization flow for ACR is illustrated in the following steps.\n * For example, GET /api/v1/acr/repositories translates into the following calls.\n * Step 1: GET /api/v1/acr/repositories\n * Return Header: 401: www-authenticate header - Bearer realm=\"{url}\",service=\"{serviceName}\",scope=\"{scope}\",error=\"invalid_token\"\n * Step 2: Retrieve the serviceName, scope from the WWW-Authenticate header. (Parse the string.)\n * Step 3: POST /api/oauth2/exchange\n * Request Body : { service, scope, grant-type, aadToken with ARM scope }\n * Response Body: { acrRefreshToken }\n * Step 4: POST /api/oauth2/token\n * Request Body: { acrRefreshToken, scope, grant-type }\n * Response Body: { acrAccessToken }\n * Step 5: GET /api/v1/acr/repositories\n * Request Header: { Bearer acrTokenAccess }\n *```\n */\nexport class ChallengeHandler implements ChallengeCallbacks {\n private readonly cycler: AccessTokenRefresher<ContainerRegistryGetTokenOptions>;\n constructor(\n private credential: ContainerRegistryRefreshTokenCredential,\n private options: GetTokenOptions & { claims?: string } = {}\n ) {\n this.cycler = createTokenCycler(credential, {\n refreshWindowInMs: fiveMinutesInMs\n });\n }\n\n authorizeRequest(_options: AuthorizeRequestOptions): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Updates the authentication context based on the challenge.\n */\n async authorizeRequestOnChallenge(options: AuthorizeRequestOnChallengeOptions): Promise<boolean> {\n // Once we're here, we've completed Step 1.\n const challenge = options.response?.headers.get(\"WWW-Authenticate\");\n if (!challenge) {\n throw new Error(\"Failed to retrieve challenge from response headers\");\n }\n // Step 2: Parse challenge string to retrieve serviceName and scope, where scope is the ACR Scope\n const { service, scope } = parseWWWAuthenticate(challenge);\n\n if (!service) {\n throw new Error(\"Failed to retrieve 'service' from challenge\");\n }\n\n if (!scope) {\n throw new Error(\"Failed to retrieve 'scope' from challenge\");\n }\n\n // Step 3: Exchange AAD Access Token for ACR Refresh Token\n // For anonymous access, we send the request with grant_type=password and an empty ACR refresh token\n // For non-anonymous access, we get an AAD token then exchange it for an ACR fresh token\n let grantType: \"password\" | \"refresh_token\";\n let acrRefreshToken: string;\n if (this.credential.isAnonymousAccess) {\n grantType = \"password\";\n acrRefreshToken = \"\";\n } else {\n grantType = \"refresh_token\";\n acrRefreshToken = (await this.cycler.getToken(scope, { ...options, service })).token;\n }\n\n // Step 4: Send in acrRefreshToken and get back acrAccessToken\n const acrAccessToken = await this.credential.tokenService.ExchangeAcrRefreshTokenForAcrAccessTokenAsync(\n acrRefreshToken,\n service,\n scope,\n grantType,\n this.options\n );\n\n // Step 5 - Authorize Request. At this point we're done with AAD and using an ACR access token.\n options.request.headers.set(\"Authorization\", `Bearer ${acrAccessToken}`);\n\n return true;\n }\n}\n"]}
1
+ {"version":3,"file":"containerRegistryChallengeHandler.js","sourceRoot":"","sources":["../../src/containerRegistryChallengeHandler.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAQlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAKrE,OAAO,EAAwB,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE9E,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAEtC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,gBAAgB;IAE3B,YACU,UAAmD,EACnD,UAAiD,EAAE;QADnD,eAAU,GAAV,UAAU,CAAyC;QACnD,YAAO,GAAP,OAAO,CAA4C;QAE3D,IAAI,CAAC,MAAM,GAAG,iBAAiB,CAAC,UAAU,EAAE;YAC1C,iBAAiB,EAAE,eAAe;SACnC,CAAC,CAAC;IACL,CAAC;IAED,gBAAgB,CAAC,QAAiC;QAChD,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,2BAA2B,CAAC,OAA2C;;QAC3E,2CAA2C;QAC3C,MAAM,SAAS,GAAG,MAAA,OAAO,CAAC,QAAQ,0CAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QACpE,IAAI,CAAC,SAAS,EAAE;YACd,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;SACvE;QACD,iGAAiG;QACjG,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;QAE3D,IAAI,CAAC,OAAO,EAAE;YACZ,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;SAChE;QAED,IAAI,CAAC,KAAK,EAAE;YACV,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;SAC9D;QAED,0DAA0D;QAC1D,sGAAsG;QACtG,0FAA0F;QAC1F,IAAI,SAAuC,CAAC;QAC5C,IAAI,eAAuB,CAAC;QAC5B,IAAI,IAAI,CAAC,UAAU,CAAC,iBAAiB,EAAE;YACrC,SAAS,GAAG,UAAU,CAAC;YACvB,eAAe,GAAG,EAAE,CAAC;SACtB;aAAM;YACL,SAAS,GAAG,eAAe,CAAC;YAC5B,eAAe,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,kCAAO,OAAO,KAAE,OAAO,IAAG,CAAC,CAAC,KAAK,CAAC;SACtF;QAED,8DAA8D;QAC9D,MAAM,cAAc,GAClB,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,6CAA6C,CAC9E,eAAe,EACf,OAAO,EACP,KAAK,EACL,SAAS,EACT,IAAI,CAAC,OAAO,CACb,CAAC;QAEJ,gGAAgG;QAChG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,cAAc,EAAE,CAAC,CAAC;QAEzE,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { GetTokenOptions } from \"@azure/core-auth\";\nimport {\n AuthorizeRequestOnChallengeOptions,\n ChallengeCallbacks,\n AuthorizeRequestOptions,\n} from \"@azure/core-rest-pipeline\";\nimport { parseWWWAuthenticate } from \"./utils/wwwAuthenticateParser\";\nimport {\n ContainerRegistryGetTokenOptions,\n ContainerRegistryRefreshTokenCredential,\n} from \"./containerRegistryTokenCredential\";\nimport { AccessTokenRefresher, createTokenCycler } from \"./utils/tokenCycler\";\n\nconst fiveMinutesInMs = 5 * 60 * 1000;\n\n/**\n * Handles challenge based authentication for Container Registry Service.\n *```\n * The challenge-based authorization flow for ACR is illustrated in the following steps.\n * For example, GET /api/v1/acr/repositories translates into the following calls.\n * Step 1: GET /api/v1/acr/repositories\n * Return Header: 401: www-authenticate header - Bearer realm=\"{url}\",service=\"{serviceName}\",scope=\"{scope}\",error=\"invalid_token\"\n * Step 2: Retrieve the serviceName, scope from the WWW-Authenticate header. (Parse the string.)\n * Step 3: POST /api/oauth2/exchange\n * Request Body : { service, scope, grant-type, aadToken with ARM scope }\n * Response Body: { acrRefreshToken }\n * Step 4: POST /api/oauth2/token\n * Request Body: { acrRefreshToken, scope, grant-type }\n * Response Body: { acrAccessToken }\n * Step 5: GET /api/v1/acr/repositories\n * Request Header: { Bearer acrTokenAccess }\n *```\n */\nexport class ChallengeHandler implements ChallengeCallbacks {\n private readonly cycler: AccessTokenRefresher<ContainerRegistryGetTokenOptions>;\n constructor(\n private credential: ContainerRegistryRefreshTokenCredential,\n private options: GetTokenOptions & { claims?: string } = {}\n ) {\n this.cycler = createTokenCycler(credential, {\n refreshWindowInMs: fiveMinutesInMs,\n });\n }\n\n authorizeRequest(_options: AuthorizeRequestOptions): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Updates the authentication context based on the challenge.\n */\n async authorizeRequestOnChallenge(options: AuthorizeRequestOnChallengeOptions): Promise<boolean> {\n // Once we're here, we've completed Step 1.\n const challenge = options.response?.headers.get(\"WWW-Authenticate\");\n if (!challenge) {\n throw new Error(\"Failed to retrieve challenge from response headers\");\n }\n // Step 2: Parse challenge string to retrieve serviceName and scope, where scope is the ACR Scope\n const { service, scope } = parseWWWAuthenticate(challenge);\n\n if (!service) {\n throw new Error(\"Failed to retrieve 'service' from challenge\");\n }\n\n if (!scope) {\n throw new Error(\"Failed to retrieve 'scope' from challenge\");\n }\n\n // Step 3: Exchange AAD Access Token for ACR Refresh Token\n // For anonymous access, we send the request with grant_type=password and an empty ACR refresh token\n // For non-anonymous access, we get an AAD token then exchange it for an ACR fresh token\n let grantType: \"password\" | \"refresh_token\";\n let acrRefreshToken: string;\n if (this.credential.isAnonymousAccess) {\n grantType = \"password\";\n acrRefreshToken = \"\";\n } else {\n grantType = \"refresh_token\";\n acrRefreshToken = (await this.cycler.getToken(scope, { ...options, service })).token;\n }\n\n // Step 4: Send in acrRefreshToken and get back acrAccessToken\n const acrAccessToken =\n await this.credential.tokenService.ExchangeAcrRefreshTokenForAcrAccessTokenAsync(\n acrRefreshToken,\n service,\n scope,\n grantType,\n this.options\n );\n\n // Step 5 - Authorize Request. At this point we're done with AAD and using an ACR access token.\n options.request.headers.set(\"Authorization\", `Bearer ${acrAccessToken}`);\n\n return true;\n }\n}\n"]}
@@ -1,19 +1,19 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
- import { __asyncDelegator, __asyncGenerator, __asyncValues, __await, __awaiter } from "tslib";
3
+ import { __asyncDelegator, __asyncGenerator, __asyncValues, __await } from "tslib";
4
4
  /// <reference lib="esnext.asynciterable" />
5
5
  import { isTokenCredential } from "@azure/core-auth";
6
- import { bearerTokenAuthenticationPolicy } from "@azure/core-rest-pipeline";
6
+ import { bearerTokenAuthenticationPolicy, } from "@azure/core-rest-pipeline";
7
7
  import { SpanStatusCode } from "@azure/core-tracing";
8
8
  import "@azure/core-paging";
9
- import { SDK_VERSION } from "./constants";
10
9
  import { logger } from "./logger";
11
10
  import { GeneratedClient } from "./generated";
12
11
  import { createSpan } from "./tracing";
13
- import { extractNextLink } from "./utils";
12
+ import { extractNextLink } from "./utils/helpers";
14
13
  import { ChallengeHandler } from "./containerRegistryChallengeHandler";
15
- import { ContainerRepositoryImpl } from "./containerRepository";
14
+ import { ContainerRepositoryImpl, } from "./containerRepository";
16
15
  import { ContainerRegistryRefreshTokenCredential } from "./containerRegistryTokenCredential";
16
+ const LATEST_API_VERSION = "2021-07-01";
17
17
  /**
18
18
  * The client class used to interact with the Container Registry service.
19
19
  */
@@ -33,58 +33,50 @@ export class ContainerRegistryClient {
33
33
  else {
34
34
  options = credentialOrOptions !== null && credentialOrOptions !== void 0 ? credentialOrOptions : {};
35
35
  }
36
- // The below code helps us set a proper User-Agent header on all requests
37
- const libInfo = `azsdk-js-container-registry/${SDK_VERSION}`;
38
- if (!options.userAgentOptions) {
39
- options.userAgentOptions = {};
40
- }
41
- if (options.userAgentOptions.userAgentPrefix) {
42
- options.userAgentOptions.userAgentPrefix = `${options.userAgentOptions.userAgentPrefix} ${libInfo}`;
43
- }
44
- else {
45
- options.userAgentOptions.userAgentPrefix = libInfo;
46
- }
47
36
  const internalPipelineOptions = Object.assign(Object.assign({}, options), { loggingOptions: {
48
37
  logger: logger.info,
49
38
  // This array contains header names we want to log that are not already
50
39
  // included as safe. Unknown/unsafe headers are logged as "<REDACTED>".
51
- additionalAllowedQueryParameters: ["last", "n", "orderby", "digest"]
40
+ additionalAllowedQueryParameters: ["last", "n", "orderby", "digest"],
52
41
  } });
53
- const authScope = (_a = options.authenticationScope) !== null && _a !== void 0 ? _a : "https://management.azure.com/.default";
54
- const authClient = new GeneratedClient(endpoint, internalPipelineOptions);
55
- this.client = new GeneratedClient(endpoint, internalPipelineOptions);
42
+ // Require audience now until we have a default ACR audience from the service.
43
+ if (!options.audience) {
44
+ throw new Error("ContainerRegistryClientOptions.audience must be set to initialize ContainerRegistryClient.");
45
+ }
46
+ const defaultScope = `${options.audience}/.default`;
47
+ const serviceVersion = (_a = options.serviceVersion) !== null && _a !== void 0 ? _a : LATEST_API_VERSION;
48
+ const authClient = new GeneratedClient(endpoint, serviceVersion, internalPipelineOptions);
49
+ this.client = new GeneratedClient(endpoint, serviceVersion, internalPipelineOptions);
56
50
  this.client.pipeline.addPolicy(bearerTokenAuthenticationPolicy({
57
51
  credential,
58
- scopes: [authScope],
59
- challengeCallbacks: new ChallengeHandler(new ContainerRegistryRefreshTokenCredential(authClient, authScope, credential))
52
+ scopes: [defaultScope],
53
+ challengeCallbacks: new ChallengeHandler(new ContainerRegistryRefreshTokenCredential(authClient, defaultScope, credential)),
60
54
  }));
61
55
  }
62
56
  /**
63
- * Deletes the repository identified by the given name.
57
+ * Deletes the repository identified by the given name and all associated artifacts.
64
58
  *
65
59
  * @param repositoryName - the name of repository to delete
66
60
  * @param options - optional configuration for the operation
67
61
  */
68
- deleteRepository(repositoryName, options = {}) {
69
- return __awaiter(this, void 0, void 0, function* () {
70
- if (!repositoryName) {
71
- throw new Error("invalid repositoryName");
72
- }
73
- const { span, updatedOptions } = createSpan("ContainerRegistryClient-deleteRepository", options);
74
- try {
75
- yield this.client.containerRegistry.deleteRepository(repositoryName, updatedOptions);
76
- }
77
- catch (e) {
78
- span.setStatus({ code: SpanStatusCode.ERROR, message: e.message });
79
- throw e;
80
- }
81
- finally {
82
- span.end();
83
- }
84
- });
62
+ async deleteRepository(repositoryName, options = {}) {
63
+ if (!repositoryName) {
64
+ throw new Error("invalid repositoryName");
65
+ }
66
+ const { span, updatedOptions } = createSpan("ContainerRegistryClient-deleteRepository", options);
67
+ try {
68
+ await this.client.containerRegistry.deleteRepository(repositoryName, updatedOptions);
69
+ }
70
+ catch (e) {
71
+ span.setStatus({ code: SpanStatusCode.ERROR, message: e.message });
72
+ throw e;
73
+ }
74
+ finally {
75
+ span.end();
76
+ }
85
77
  }
86
78
  /**
87
- * Returns an artifact for given repository name, and a tag or digest.
79
+ * Returns an instance of {@link RegistryArtifact} for calling service methods related to the artifact specified by `repositoryName` and `tagOrDigest`.
88
80
  *
89
81
  * @param repositoryName - the name of repository
90
82
  * @param tagOrDigest - tag or digest of the artifact to retrieve
@@ -99,10 +91,9 @@ export class ContainerRegistryClient {
99
91
  return new ContainerRepositoryImpl(this.endpoint, repositoryName, this.client).getArtifact(tagOrDigest);
100
92
  }
101
93
  /**
102
- * Returns a ContainerRepositoryClient instance for the given repository.
94
+ * Returns an instance of {@link ContainerRepository} for calling service methods related to the repository specified by `repositoryName`.
103
95
  *
104
- * @param repositoryName - the name of repository to delete
105
- * @param options - optional configuration for the operation
96
+ * @param repositoryName - the name of repository
106
97
  */
107
98
  getRepository(repositoryName) {
108
99
  if (!repositoryName) {
@@ -111,15 +102,43 @@ export class ContainerRegistryClient {
111
102
  return new ContainerRepositoryImpl(this.endpoint, repositoryName, this.client);
112
103
  }
113
104
  /**
114
- * Iterates repositories.
105
+ * Returns an async iterable iterator to list names of repositories in this registry.
115
106
  *
116
107
  * Example usage:
117
- * ```ts
118
- * let client = new ContainerRegistryClient(url, credentials);
108
+ * ```javascript
109
+ * let client = new ContainerRegistryClient(url, credential);
119
110
  * for await (const repository of client.listRepositoryNames()) {
120
111
  * console.log("repository name: ", repository);
121
112
  * }
122
113
  * ```
114
+ *
115
+ * Example using `iter.next()`:
116
+ *
117
+ * ```javascript
118
+ * let iter = client.listRepositoryNames();
119
+ * let item = await iter.next();
120
+ * while (!item.done) {
121
+ * console.log(`repository name: ${item.value}`);
122
+ * item = await iter.next();
123
+ * }
124
+ * ```
125
+ *
126
+ * Example using `byPage()`:
127
+ *
128
+ * ```javascript
129
+ * const pages = client.listRepositoryNames().byPage({ maxPageSize: 2 });
130
+ * let page = await pages.next();
131
+ * let i = 1;
132
+ * while (!page.done) {
133
+ * if (page.value) {
134
+ * console.log(`-- page ${i++}`);
135
+ * for (const name of page.value) {
136
+ * console.log(` repository name: ${name}`);
137
+ * }
138
+ * }
139
+ * page = await pages.next();
140
+ * }
141
+ * ```
123
142
  * @param options -
124
143
  */
125
144
  listRepositoryNames(options = {}) {
@@ -131,7 +150,7 @@ export class ContainerRegistryClient {
131
150
  [Symbol.asyncIterator]() {
132
151
  return this;
133
152
  },
134
- byPage: (settings = {}) => this.listRepositoriesPage(settings, options)
153
+ byPage: (settings = {}) => this.listRepositoriesPage(settings, options),
135
154
  };
136
155
  }
137
156
  listRepositoryItems(options = {}) {
@@ -162,7 +181,7 @@ export class ContainerRegistryClient {
162
181
  const array = currentPage.repositories;
163
182
  yield yield __await(Object.defineProperty(array, "continuationToken", {
164
183
  value: continuationState.continuationToken,
165
- enumerable: true
184
+ enumerable: true,
166
185
  }));
167
186
  }
168
187
  }
@@ -173,7 +192,7 @@ export class ContainerRegistryClient {
173
192
  const array = currentPage.repositories;
174
193
  yield yield __await(Object.defineProperty(array, "continuationToken", {
175
194
  value: continuationState.continuationToken,
176
- enumerable: true
195
+ enumerable: true,
177
196
  }));
178
197
  }
179
198
  }
@@ -1 +1 @@
1
- {"version":3,"file":"containerRegistryClient.js","sourceRoot":"","sources":["../../src/containerRegistryClient.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/// <reference lib=\"esnext.asynciterable\" />\n\nimport { isTokenCredential, TokenCredential } from \"@azure/core-auth\";\nimport {\n InternalPipelineOptions,\n bearerTokenAuthenticationPolicy,\n PipelineOptions\n} from \"@azure/core-rest-pipeline\";\nimport { OperationOptions } from \"@azure/core-client\";\n\nimport { SpanStatusCode } from \"@azure/core-tracing\";\nimport \"@azure/core-paging\";\nimport { PageSettings, PagedAsyncIterableIterator } from \"@azure/core-paging\";\n\nimport { SDK_VERSION } from \"./constants\";\nimport { logger } from \"./logger\";\nimport { GeneratedClient } from \"./generated\";\nimport { createSpan } from \"./tracing\";\nimport { RepositoryPageResponse } from \"./models\";\nimport { extractNextLink } from \"./utils\";\nimport { ChallengeHandler } from \"./containerRegistryChallengeHandler\";\nimport {\n ContainerRepository,\n ContainerRepositoryImpl,\n DeleteRepositoryOptions\n} from \"./containerRepository\";\nimport { RegistryArtifact } from \"./registryArtifact\";\nimport { ContainerRegistryRefreshTokenCredential } from \"./containerRegistryTokenCredential\";\n\n/**\n * Client options used to configure Container Registry Repository API requests.\n */\nexport interface ContainerRegistryClientOptions extends PipelineOptions {\n /**\n * Gets or sets the authentication scope to use for authentication with AAD.\n * This defaults to the Azure Resource Manager \"Azure Global\" scope. To\n * connect to a different cloud, set this value to \"&lt;resource-id&gt;/.default\",\n * where &lt;resource-id&gt; is one of the Resource IDs listed at\n * https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/services-support-managed-identities#azure-resource-manager.\n * For example, to connect to the Azure Germany cloud, create a client with\n * this set to \"https://management.microsoftazure.de/.default\".\n */\n authenticationScope?: string;\n}\n\n/**\n * Options for the `listRepositories` method of `ContainerRegistryClient`.\n */\nexport interface ListRepositoriesOptions extends OperationOptions {}\n\n/**\n * The client class used to interact with the Container Registry service.\n */\nexport class ContainerRegistryClient {\n /**\n * The Azure Container Registry endpoint.\n */\n public readonly endpoint: string;\n\n private client: GeneratedClient;\n\n /**\n * Creates an instance of a ContainerRegistryClient.\n *\n * Example usage:\n * ```ts\n * import { ContainerRegistryClient } from \"@azure/container-registry\";\n * import { DefaultAzureCredential} from \"@azure/identity\";\n *\n * const client = new ContainerRegistryClient(\n * \"<container registry API endpoint>\",\n * new DefaultAzureCredential()\n * );\n * ```\n * @param endpoint - the URL to the Container Registry endpoint\n * @param credential - used to authenticate requests to the service\n * @param options - optional configuration used to send requests to the service\n */\n constructor(\n endpoint: string,\n credential: TokenCredential,\n options?: ContainerRegistryClientOptions\n );\n\n /**\n * Creates an instance of a ContainerRegistryClient to interact with\n * an Azure Container Registry that has anonymous pull access enabled.\n *\n * Example usage:\n * ```ts\n * import { ContainerRegistryClient } from \"@azure/container-registry\";\n *\n * const client = new ContainerRegistryClient(\n * \"<container registry API endpoint>\",\n * );\n * ```\n * @param endpoint - the URL to the Container Registry endpoint\n * @param options - optional configuration used to send requests to the service\n */\n constructor(endpoint: string, options?: ContainerRegistryClientOptions);\n\n constructor(\n endpoint: string,\n credentialOrOptions?: TokenCredential | ContainerRegistryClientOptions,\n clientOptions: ContainerRegistryClientOptions = {}\n ) {\n if (!endpoint) {\n throw new Error(\"invalid endpoint\");\n }\n\n this.endpoint = endpoint;\n\n let credential: TokenCredential | undefined;\n let options: ContainerRegistryClientOptions | undefined;\n if (isTokenCredential(credentialOrOptions)) {\n credential = credentialOrOptions;\n options = clientOptions;\n } else {\n options = credentialOrOptions ?? {};\n }\n\n // The below code helps us set a proper User-Agent header on all requests\n const libInfo = `azsdk-js-container-registry/${SDK_VERSION}`;\n if (!options.userAgentOptions) {\n options.userAgentOptions = {};\n }\n if (options.userAgentOptions.userAgentPrefix) {\n options.userAgentOptions.userAgentPrefix = `${options.userAgentOptions.userAgentPrefix} ${libInfo}`;\n } else {\n options.userAgentOptions.userAgentPrefix = libInfo;\n }\n\n const internalPipelineOptions: InternalPipelineOptions = {\n ...options,\n loggingOptions: {\n logger: logger.info,\n // This array contains header names we want to log that are not already\n // included as safe. Unknown/unsafe headers are logged as \"<REDACTED>\".\n additionalAllowedQueryParameters: [\"last\", \"n\", \"orderby\", \"digest\"]\n }\n };\n const authScope = options.authenticationScope ?? \"https://management.azure.com/.default\";\n const authClient = new GeneratedClient(endpoint, internalPipelineOptions);\n this.client = new GeneratedClient(endpoint, internalPipelineOptions);\n this.client.pipeline.addPolicy(\n bearerTokenAuthenticationPolicy({\n credential,\n scopes: [authScope],\n challengeCallbacks: new ChallengeHandler(\n new ContainerRegistryRefreshTokenCredential(authClient, authScope, credential)\n )\n })\n );\n }\n\n /**\n * Deletes the repository identified by the given name.\n *\n * @param repositoryName - the name of repository to delete\n * @param options - optional configuration for the operation\n */\n public async deleteRepository(\n repositoryName: string,\n options: DeleteRepositoryOptions = {}\n ): Promise<void> {\n if (!repositoryName) {\n throw new Error(\"invalid repositoryName\");\n }\n\n const { span, updatedOptions } = createSpan(\n \"ContainerRegistryClient-deleteRepository\",\n options\n );\n\n try {\n await this.client.containerRegistry.deleteRepository(repositoryName, updatedOptions);\n } catch (e) {\n span.setStatus({ code: SpanStatusCode.ERROR, message: e.message });\n throw e;\n } finally {\n span.end();\n }\n }\n\n /**\n * Returns an artifact for given repository name, and a tag or digest.\n *\n * @param repositoryName - the name of repository\n * @param tagOrDigest - tag or digest of the artifact to retrieve\n */\n public getArtifact(repositoryName: string, tagOrDigest: string): RegistryArtifact {\n if (!repositoryName) {\n throw new Error(\"invalid repositoryName\");\n }\n if (!tagOrDigest) {\n throw new Error(\"invalid tagOrDigest\");\n }\n\n return new ContainerRepositoryImpl(this.endpoint, repositoryName, this.client).getArtifact(\n tagOrDigest\n );\n }\n\n /**\n * Returns a ContainerRepositoryClient instance for the given repository.\n *\n * @param repositoryName - the name of repository to delete\n * @param options - optional configuration for the operation\n */\n public getRepository(repositoryName: string): ContainerRepository {\n if (!repositoryName) {\n throw new Error(\"invalid repositoryName\");\n }\n\n return new ContainerRepositoryImpl(this.endpoint, repositoryName, this.client);\n }\n\n /**\n * Iterates repositories.\n *\n * Example usage:\n * ```ts\n * let client = new ContainerRegistryClient(url, credentials);\n * for await (const repository of client.listRepositoryNames()) {\n * console.log(\"repository name: \", repository);\n * }\n * ```\n * @param options -\n */\n public listRepositoryNames(\n options: ListRepositoriesOptions = {}\n ): PagedAsyncIterableIterator<string, RepositoryPageResponse> {\n const iter = this.listRepositoryItems(options);\n\n return {\n next() {\n return iter.next();\n },\n [Symbol.asyncIterator]() {\n return this;\n },\n byPage: (settings: PageSettings = {}) => this.listRepositoriesPage(settings, options)\n };\n }\n\n private async *listRepositoryItems(\n options: ListRepositoriesOptions = {}\n ): AsyncIterableIterator<string> {\n for await (const page of this.listRepositoriesPage({}, options)) {\n yield* page;\n }\n }\n\n private async *listRepositoriesPage(\n continuationState: PageSettings,\n options: ListRepositoriesOptions = {}\n ): AsyncIterableIterator<RepositoryPageResponse> {\n if (!continuationState.continuationToken) {\n const optionsComplete = {\n ...options,\n n: continuationState.maxPageSize\n };\n const currentPage = await this.client.containerRegistry.getRepositories(optionsComplete);\n continuationState.continuationToken = extractNextLink(currentPage.link);\n if (currentPage.repositories) {\n const array = currentPage.repositories;\n yield Object.defineProperty(array, \"continuationToken\", {\n value: continuationState.continuationToken,\n enumerable: true\n });\n }\n }\n while (continuationState.continuationToken) {\n const currentPage = await this.client.containerRegistry.getRepositoriesNext(\n continuationState.continuationToken,\n options\n );\n continuationState.continuationToken = extractNextLink(currentPage.link);\n if (currentPage.repositories) {\n const array = currentPage.repositories;\n yield Object.defineProperty(array, \"continuationToken\", {\n value: continuationState.continuationToken,\n enumerable: true\n });\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"containerRegistryClient.js","sourceRoot":"","sources":["../../src/containerRegistryClient.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/// <reference lib=\"esnext.asynciterable\" />\n\nimport { isTokenCredential, TokenCredential } from \"@azure/core-auth\";\nimport {\n InternalPipelineOptions,\n bearerTokenAuthenticationPolicy,\n PipelineOptions,\n} from \"@azure/core-rest-pipeline\";\nimport { OperationOptions } from \"@azure/core-client\";\n\nimport { SpanStatusCode } from \"@azure/core-tracing\";\nimport \"@azure/core-paging\";\nimport { PageSettings, PagedAsyncIterableIterator } from \"@azure/core-paging\";\n\nimport { logger } from \"./logger\";\nimport { GeneratedClient } from \"./generated\";\nimport { createSpan } from \"./tracing\";\nimport { RepositoryPageResponse } from \"./models\";\nimport { extractNextLink } from \"./utils/helpers\";\nimport { ChallengeHandler } from \"./containerRegistryChallengeHandler\";\nimport {\n ContainerRepository,\n ContainerRepositoryImpl,\n DeleteRepositoryOptions,\n} from \"./containerRepository\";\nimport { RegistryArtifact } from \"./registryArtifact\";\nimport { ContainerRegistryRefreshTokenCredential } from \"./containerRegistryTokenCredential\";\n\nconst LATEST_API_VERSION = \"2021-07-01\";\n\n/**\n * Client options used to configure Container Registry Repository API requests.\n */\nexport interface ContainerRegistryClientOptions extends PipelineOptions {\n /**\n * Gets or sets the audience to use for authentication with Azure Active Directory.\n * The authentication scope will be set from this audience.\n * See {@link KnownContainerRegistryAudience} for known audience values.\n */\n audience?: string;\n /**\n * The version of service API to make calls against.\n */\n serviceVersion?: \"2021-07-01\";\n}\n\n/**\n * Options for the `listRepositories` method of `ContainerRegistryClient`.\n */\nexport interface ListRepositoriesOptions extends OperationOptions {}\n\n/**\n * The client class used to interact with the Container Registry service.\n */\nexport class ContainerRegistryClient {\n /**\n * The Azure Container Registry endpoint.\n */\n public readonly endpoint: string;\n\n private client: GeneratedClient;\n\n /**\n * Creates an instance of a ContainerRegistryClient.\n *\n * Example usage:\n * ```ts\n * import { ContainerRegistryClient } from \"@azure/container-registry\";\n * import { DefaultAzureCredential} from \"@azure/identity\";\n *\n * const client = new ContainerRegistryClient(\n * \"<container registry API endpoint>\",\n * new DefaultAzureCredential()\n * );\n * ```\n * @param endpoint - the URL endpoint of the container registry\n * @param credential - used to authenticate requests to the service\n * @param options - optional configuration used to send requests to the service\n */\n constructor(\n endpoint: string,\n credential: TokenCredential,\n options?: ContainerRegistryClientOptions\n );\n\n /**\n * Creates an instance of a ContainerRegistryClient to interact with\n * an Azure Container Registry that has anonymous pull access enabled.\n * Only operations that support anonymous access are enabled. Other service\n * methods will throw errors.\n *\n * Example usage:\n * ```ts\n * import { ContainerRegistryClient } from \"@azure/container-registry\";\n *\n * const client = new ContainerRegistryClient(\n * \"<container registry API endpoint>\",\n * );\n * ```\n * @param endpoint - the URL endpoint of the container registry\n * @param options - optional configuration used to send requests to the service\n */\n constructor(endpoint: string, options?: ContainerRegistryClientOptions);\n\n constructor(\n endpoint: string,\n credentialOrOptions?: TokenCredential | ContainerRegistryClientOptions,\n clientOptions: ContainerRegistryClientOptions = {}\n ) {\n if (!endpoint) {\n throw new Error(\"invalid endpoint\");\n }\n\n this.endpoint = endpoint;\n\n let credential: TokenCredential | undefined;\n let options: ContainerRegistryClientOptions | undefined;\n if (isTokenCredential(credentialOrOptions)) {\n credential = credentialOrOptions;\n options = clientOptions;\n } else {\n options = credentialOrOptions ?? {};\n }\n\n const internalPipelineOptions: InternalPipelineOptions = {\n ...options,\n loggingOptions: {\n logger: logger.info,\n // This array contains header names we want to log that are not already\n // included as safe. Unknown/unsafe headers are logged as \"<REDACTED>\".\n additionalAllowedQueryParameters: [\"last\", \"n\", \"orderby\", \"digest\"],\n },\n };\n // Require audience now until we have a default ACR audience from the service.\n if (!options.audience) {\n throw new Error(\n \"ContainerRegistryClientOptions.audience must be set to initialize ContainerRegistryClient.\"\n );\n }\n\n const defaultScope = `${options.audience}/.default`;\n const serviceVersion = options.serviceVersion ?? LATEST_API_VERSION;\n const authClient = new GeneratedClient(endpoint, serviceVersion, internalPipelineOptions);\n this.client = new GeneratedClient(endpoint, serviceVersion, internalPipelineOptions);\n this.client.pipeline.addPolicy(\n bearerTokenAuthenticationPolicy({\n credential,\n scopes: [defaultScope],\n challengeCallbacks: new ChallengeHandler(\n new ContainerRegistryRefreshTokenCredential(authClient, defaultScope, credential)\n ),\n })\n );\n }\n\n /**\n * Deletes the repository identified by the given name and all associated artifacts.\n *\n * @param repositoryName - the name of repository to delete\n * @param options - optional configuration for the operation\n */\n public async deleteRepository(\n repositoryName: string,\n options: DeleteRepositoryOptions = {}\n ): Promise<void> {\n if (!repositoryName) {\n throw new Error(\"invalid repositoryName\");\n }\n\n const { span, updatedOptions } = createSpan(\n \"ContainerRegistryClient-deleteRepository\",\n options\n );\n\n try {\n await this.client.containerRegistry.deleteRepository(repositoryName, updatedOptions);\n } catch (e) {\n span.setStatus({ code: SpanStatusCode.ERROR, message: e.message });\n throw e;\n } finally {\n span.end();\n }\n }\n\n /**\n * Returns an instance of {@link RegistryArtifact} for calling service methods related to the artifact specified by `repositoryName` and `tagOrDigest`.\n *\n * @param repositoryName - the name of repository\n * @param tagOrDigest - tag or digest of the artifact to retrieve\n */\n public getArtifact(repositoryName: string, tagOrDigest: string): RegistryArtifact {\n if (!repositoryName) {\n throw new Error(\"invalid repositoryName\");\n }\n if (!tagOrDigest) {\n throw new Error(\"invalid tagOrDigest\");\n }\n\n return new ContainerRepositoryImpl(this.endpoint, repositoryName, this.client).getArtifact(\n tagOrDigest\n );\n }\n\n /**\n * Returns an instance of {@link ContainerRepository} for calling service methods related to the repository specified by `repositoryName`.\n *\n * @param repositoryName - the name of repository\n */\n public getRepository(repositoryName: string): ContainerRepository {\n if (!repositoryName) {\n throw new Error(\"invalid repositoryName\");\n }\n\n return new ContainerRepositoryImpl(this.endpoint, repositoryName, this.client);\n }\n\n /**\n * Returns an async iterable iterator to list names of repositories in this registry.\n *\n * Example usage:\n * ```javascript\n * let client = new ContainerRegistryClient(url, credential);\n * for await (const repository of client.listRepositoryNames()) {\n * console.log(\"repository name: \", repository);\n * }\n * ```\n *\n * Example using `iter.next()`:\n *\n * ```javascript\n * let iter = client.listRepositoryNames();\n * let item = await iter.next();\n * while (!item.done) {\n * console.log(`repository name: ${item.value}`);\n * item = await iter.next();\n * }\n * ```\n *\n * Example using `byPage()`:\n *\n * ```javascript\n * const pages = client.listRepositoryNames().byPage({ maxPageSize: 2 });\n * let page = await pages.next();\n * let i = 1;\n * while (!page.done) {\n * if (page.value) {\n * console.log(`-- page ${i++}`);\n * for (const name of page.value) {\n * console.log(` repository name: ${name}`);\n * }\n * }\n * page = await pages.next();\n * }\n * ```\n * @param options -\n */\n public listRepositoryNames(\n options: ListRepositoriesOptions = {}\n ): PagedAsyncIterableIterator<string, RepositoryPageResponse> {\n const iter = this.listRepositoryItems(options);\n\n return {\n next() {\n return iter.next();\n },\n [Symbol.asyncIterator]() {\n return this;\n },\n byPage: (settings: PageSettings = {}) => this.listRepositoriesPage(settings, options),\n };\n }\n\n private async *listRepositoryItems(\n options: ListRepositoriesOptions = {}\n ): AsyncIterableIterator<string> {\n for await (const page of this.listRepositoriesPage({}, options)) {\n yield* page;\n }\n }\n\n private async *listRepositoriesPage(\n continuationState: PageSettings,\n options: ListRepositoriesOptions = {}\n ): AsyncIterableIterator<RepositoryPageResponse> {\n if (!continuationState.continuationToken) {\n const optionsComplete = {\n ...options,\n n: continuationState.maxPageSize,\n };\n const currentPage = await this.client.containerRegistry.getRepositories(optionsComplete);\n continuationState.continuationToken = extractNextLink(currentPage.link);\n if (currentPage.repositories) {\n const array = currentPage.repositories;\n yield Object.defineProperty(array, \"continuationToken\", {\n value: continuationState.continuationToken,\n enumerable: true,\n });\n }\n }\n while (continuationState.continuationToken) {\n const currentPage = await this.client.containerRegistry.getRepositoriesNext(\n continuationState.continuationToken,\n options\n );\n continuationState.continuationToken = extractNextLink(currentPage.link);\n if (currentPage.repositories) {\n const array = currentPage.repositories;\n yield Object.defineProperty(array, \"continuationToken\", {\n value: continuationState.continuationToken,\n enumerable: true,\n });\n }\n }\n }\n}\n"]}
@@ -1,10 +1,6 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
- import { __awaiter } from "tslib";
4
- import { createSerializer } from "@azure/core-client";
5
- import * as Mappers from "./generated/models/mappers";
6
- import * as Parameters from "./generated/models/parameters";
7
- import { base64decode } from "./base64";
3
+ import { base64decode } from "./utils/base64";
8
4
  export class ContainerRegistryRefreshTokenCredential {
9
5
  constructor(authClient, authenticationScope, credential) {
10
6
  this.authenticationScope = authenticationScope;
@@ -12,134 +8,51 @@ export class ContainerRegistryRefreshTokenCredential {
12
8
  this.tokenService = new ContainerRegistryTokenService(authClient);
13
9
  this.isAnonymousAccess = !this.credential;
14
10
  }
15
- getToken(_scopes, options) {
16
- return __awaiter(this, void 0, void 0, function* () {
17
- if (!this.credential) {
18
- return null;
19
- }
20
- const aadToken = yield this.credential.getToken(this.authenticationScope, options);
21
- if (!aadToken) {
22
- throw new Error("Failed to retrieve AAD token.");
23
- }
24
- return this.tokenService.ExchangeAadAccessTokenForAcrRefreshTokenAsync(aadToken.token, options.service, options);
25
- });
26
- }
27
- }
28
- const customExchangeAadTokenForAcrRefreshTokenOperationSpec = {
29
- path: "/oauth2/exchange",
30
- httpMethod: "POST",
31
- responses: {
32
- 200: {
33
- bodyMapper: Mappers.AcrRefreshToken
34
- },
35
- default: {
36
- bodyMapper: Mappers.AcrErrors
37
- }
38
- },
39
- // formDataParameters: [Parameters.aadAccesstoken],
40
- requestBody: {
41
- parameterPath: ["options", "payload"],
42
- mapper: {
43
- type: {
44
- name: "Stream"
45
- }
11
+ async getToken(_scopes, options) {
12
+ if (!this.credential) {
13
+ return null;
46
14
  }
47
- },
48
- urlParameters: [Parameters.url],
49
- headerParameters: [Parameters.contentType3, Parameters.accept4],
50
- serializer: createSerializer(Mappers, /* isXml */ false)
51
- };
52
- const customExchangeAcrRefreshTokenForAcrAccessTokenOperationSpec = {
53
- path: "/oauth2/token",
54
- httpMethod: "POST",
55
- responses: {
56
- 200: {
57
- bodyMapper: Mappers.AcrAccessToken
58
- },
59
- default: {
60
- bodyMapper: Mappers.AcrErrors
15
+ const aadToken = await this.credential.getToken(this.authenticationScope, options);
16
+ if (!aadToken) {
17
+ throw new Error("Failed to retrieve AAD token.");
61
18
  }
62
- },
63
- // formDataParameters: [Parameters.acrRefreshToken],
64
- requestBody: {
65
- parameterPath: ["options", "payload"],
66
- mapper: {
67
- type: {
68
- name: "Stream"
69
- }
70
- }
71
- },
72
- urlParameters: [Parameters.url],
73
- headerParameters: [Parameters.contentType3, Parameters.accept4],
74
- serializer: createSerializer(Mappers, /* isXml */ false)
75
- };
19
+ return this.tokenService.ExchangeAadAccessTokenForAcrRefreshTokenAsync(aadToken.token, options.service, options);
20
+ }
21
+ }
76
22
  export class ContainerRegistryTokenService {
77
23
  constructor(authClient) {
78
24
  this.authClient = authClient;
79
25
  }
80
- ExchangeAadAccessTokenForAcrRefreshTokenAsync(aadAccessToken, service, options) {
81
- return __awaiter(this, void 0, void 0, function* () {
82
- // const acrRefreshToken = await this.authClient.authentication.exchangeAadTokenForAcrRefreshToken(
83
- // {
84
- // aadAccesstoken: {
85
- // grantType: "access_token",
86
- // service,
87
- // aadAccesstoken: aadAccessToken,
88
- // }
89
- // }
90
- // );
91
- // TODO: (jeremymeng) revert custom sendOperationRequest call after FormData is working in core
92
- const payload = `grant_type=access_token&service=${encodeURIComponent(service)}&access_token=${encodeURIComponent(aadAccessToken)}`;
93
- const customOptions = {
94
- payload
95
- };
96
- const acrRefreshToken = yield this.authClient.sendOperationRequest({ options: Object.assign(Object.assign({}, options), customOptions) }, customExchangeAadTokenForAcrRefreshTokenOperationSpec);
97
- if (!acrRefreshToken.refreshToken) {
98
- throw new Error("Failed to exchange AAD access token for an ACR refresh token.");
99
- }
100
- // ACR refresh token expires after three hours
101
- const jwtParts = acrRefreshToken.refreshToken.split(".");
102
- if (jwtParts.length < 3) {
103
- throw new Error("Invalid JWT structure from ACR refresh token.");
104
- }
105
- if (!jwtParts[1]) {
106
- throw new Error("Invalid JWT payload.");
107
- }
108
- const jwtPayload = JSON.parse(base64decode(jwtParts[1]));
109
- if (!jwtPayload.exp) {
110
- throw new Error("Invalid JWT payload structure. No expiration.");
111
- }
112
- // JWT expiry is in seconds
113
- const expiry = Number.parseInt(jwtPayload.exp) * 1000;
114
- return {
115
- token: acrRefreshToken.refreshToken,
116
- expiresOnTimestamp: expiry
117
- };
118
- });
26
+ async ExchangeAadAccessTokenForAcrRefreshTokenAsync(aadAccessToken, service, options) {
27
+ const acrRefreshToken = await this.authClient.authentication.exchangeAadAccessTokenForAcrRefreshToken("access_token", service, Object.assign(Object.assign({}, options), { accessToken: aadAccessToken }));
28
+ if (!acrRefreshToken.refreshToken) {
29
+ throw new Error("Failed to exchange AAD access token for an ACR refresh token.");
30
+ }
31
+ // ACR refresh token expires after three hours
32
+ const jwtParts = acrRefreshToken.refreshToken.split(".");
33
+ if (jwtParts.length < 3) {
34
+ throw new Error("Invalid JWT structure from ACR refresh token.");
35
+ }
36
+ if (!jwtParts[1]) {
37
+ throw new Error("Invalid JWT payload.");
38
+ }
39
+ const jwtPayload = JSON.parse(base64decode(jwtParts[1]));
40
+ if (!jwtPayload.exp) {
41
+ throw new Error("Invalid JWT payload structure. No expiration.");
42
+ }
43
+ // JWT expiry is in seconds
44
+ const expiry = Number.parseInt(jwtPayload.exp) * 1000;
45
+ return {
46
+ token: acrRefreshToken.refreshToken,
47
+ expiresOnTimestamp: expiry,
48
+ };
119
49
  }
120
- ExchangeAcrRefreshTokenForAcrAccessTokenAsync(acrRefreshToken, service, scope, grantType, options) {
121
- return __awaiter(this, void 0, void 0, function* () {
122
- // const acrAccessToken = await this.authClient.authentication.exchangeAcrRefreshTokenForAcrAccessToken(
123
- // {
124
- // acrRefreshToken: {
125
- // grantType: "refresh_token",
126
- // acrRefreshToken,
127
- // service,
128
- // scope
129
- // }
130
- // }
131
- // );
132
- // TODO: (jeremymeng) revert custom sendOperationRequest call after FormData is working in core
133
- const payload = `grant_type=${grantType}&service=${encodeURIComponent(service)}&refresh_token=${acrRefreshToken ? encodeURIComponent(acrRefreshToken) : ""}&scope=${encodeURIComponent(scope)}`;
134
- const customOptions = {
135
- payload
136
- };
137
- const acrAccessToken = yield this.authClient.sendOperationRequest({ options: Object.assign(Object.assign({}, options), customOptions) }, customExchangeAcrRefreshTokenForAcrAccessTokenOperationSpec);
138
- if (!acrAccessToken.accessToken) {
139
- throw new Error("Failed to exchange ACR refresh token for an ACR access token");
140
- }
141
- return acrAccessToken.accessToken;
142
- });
50
+ async ExchangeAcrRefreshTokenForAcrAccessTokenAsync(acrRefreshToken, service, scope, grantType, options) {
51
+ const acrAccessToken = await this.authClient.authentication.exchangeAcrRefreshTokenForAcrAccessToken(service, scope, acrRefreshToken, grantType, options);
52
+ if (!acrAccessToken.accessToken) {
53
+ throw new Error("Failed to exchange ACR refresh token for an ACR access token");
54
+ }
55
+ return acrAccessToken.accessToken;
143
56
  }
144
57
  }
145
58
  //# sourceMappingURL=containerRegistryTokenCredential.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"containerRegistryTokenCredential.js","sourceRoot":"","sources":["../../src/containerRegistryTokenCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { createSerializer, OperationOptions, OperationSpec } from \"@azure/core-client\";\nimport { AccessToken, GetTokenOptions, TokenCredential } from \"@azure/core-auth\";\nimport { AcrAccessToken, AcrRefreshToken, GeneratedClient } from \"./generated\";\nimport * as Mappers from \"./generated/models/mappers\";\nimport * as Parameters from \"./generated/models/parameters\";\nimport { base64decode } from \"./base64\";\n\nexport interface ContainerRegistryGetTokenOptions extends GetTokenOptions {\n service: string;\n}\n\nexport class ContainerRegistryRefreshTokenCredential implements TokenCredential {\n readonly tokenService: ContainerRegistryTokenService;\n readonly isAnonymousAccess: boolean;\n constructor(\n authClient: GeneratedClient,\n private authenticationScope: string,\n private credential?: TokenCredential\n ) {\n this.tokenService = new ContainerRegistryTokenService(authClient);\n this.isAnonymousAccess = !this.credential;\n }\n\n async getToken(\n _scopes: string | string[],\n options: ContainerRegistryGetTokenOptions\n ): Promise<AccessToken | null> {\n if (!this.credential) {\n return null;\n }\n\n const aadToken = await this.credential.getToken(this.authenticationScope, options);\n if (!aadToken) {\n throw new Error(\"Failed to retrieve AAD token.\");\n }\n\n return this.tokenService.ExchangeAadAccessTokenForAcrRefreshTokenAsync(\n aadToken.token,\n options.service,\n options\n );\n }\n}\n\nconst customExchangeAadTokenForAcrRefreshTokenOperationSpec: OperationSpec = {\n path: \"/oauth2/exchange\",\n httpMethod: \"POST\",\n responses: {\n 200: {\n bodyMapper: Mappers.AcrRefreshToken\n },\n default: {\n bodyMapper: Mappers.AcrErrors\n }\n },\n // formDataParameters: [Parameters.aadAccesstoken],\n requestBody: {\n parameterPath: [\"options\", \"payload\"],\n mapper: {\n type: {\n name: \"Stream\"\n }\n }\n },\n urlParameters: [Parameters.url],\n headerParameters: [Parameters.contentType3, Parameters.accept4],\n serializer: createSerializer(Mappers, /* isXml */ false)\n};\n\ninterface CustomAuthOptions extends OperationOptions {\n payload: string;\n}\n\nconst customExchangeAcrRefreshTokenForAcrAccessTokenOperationSpec: OperationSpec = {\n path: \"/oauth2/token\",\n httpMethod: \"POST\",\n responses: {\n 200: {\n bodyMapper: Mappers.AcrAccessToken\n },\n default: {\n bodyMapper: Mappers.AcrErrors\n }\n },\n // formDataParameters: [Parameters.acrRefreshToken],\n requestBody: {\n parameterPath: [\"options\", \"payload\"],\n mapper: {\n type: {\n name: \"Stream\"\n }\n }\n },\n urlParameters: [Parameters.url],\n headerParameters: [Parameters.contentType3, Parameters.accept4],\n serializer: createSerializer(Mappers, /* isXml */ false)\n};\n\nexport class ContainerRegistryTokenService {\n constructor(private authClient: GeneratedClient) {}\n\n async ExchangeAadAccessTokenForAcrRefreshTokenAsync(\n aadAccessToken: string,\n service: string,\n options: GetTokenOptions\n ): Promise<AccessToken> {\n // const acrRefreshToken = await this.authClient.authentication.exchangeAadTokenForAcrRefreshToken(\n // {\n // aadAccesstoken: {\n // grantType: \"access_token\",\n // service,\n // aadAccesstoken: aadAccessToken,\n // }\n // }\n // );\n\n // TODO: (jeremymeng) revert custom sendOperationRequest call after FormData is working in core\n const payload = `grant_type=access_token&service=${encodeURIComponent(\n service\n )}&access_token=${encodeURIComponent(aadAccessToken)}`;\n const customOptions: CustomAuthOptions = {\n payload\n };\n const acrRefreshToken = await this.authClient.sendOperationRequest<AcrRefreshToken>(\n { options: { ...options, ...customOptions } },\n customExchangeAadTokenForAcrRefreshTokenOperationSpec\n );\n\n if (!acrRefreshToken.refreshToken) {\n throw new Error(\"Failed to exchange AAD access token for an ACR refresh token.\");\n }\n\n // ACR refresh token expires after three hours\n const jwtParts = acrRefreshToken.refreshToken.split(\".\");\n if (jwtParts.length < 3) {\n throw new Error(\"Invalid JWT structure from ACR refresh token.\");\n }\n if (!jwtParts[1]) {\n throw new Error(\"Invalid JWT payload.\");\n }\n\n const jwtPayload = JSON.parse(base64decode(jwtParts[1]));\n if (!jwtPayload.exp) {\n throw new Error(\"Invalid JWT payload structure. No expiration.\");\n }\n\n // JWT expiry is in seconds\n const expiry = Number.parseInt(jwtPayload.exp) * 1000;\n return {\n token: acrRefreshToken.refreshToken,\n expiresOnTimestamp: expiry\n };\n }\n\n async ExchangeAcrRefreshTokenForAcrAccessTokenAsync(\n acrRefreshToken: string,\n service: string,\n scope: string,\n grantType: \"refresh_token\" | \"password\",\n options: GetTokenOptions\n ): Promise<string> {\n // const acrAccessToken = await this.authClient.authentication.exchangeAcrRefreshTokenForAcrAccessToken(\n // {\n // acrRefreshToken: {\n // grantType: \"refresh_token\",\n // acrRefreshToken,\n // service,\n // scope\n // }\n // }\n // );\n\n // TODO: (jeremymeng) revert custom sendOperationRequest call after FormData is working in core\n const payload = `grant_type=${grantType}&service=${encodeURIComponent(service)}&refresh_token=${\n acrRefreshToken ? encodeURIComponent(acrRefreshToken) : \"\"\n }&scope=${encodeURIComponent(scope)}`;\n const customOptions: CustomAuthOptions = {\n payload\n };\n const acrAccessToken = await this.authClient.sendOperationRequest<AcrAccessToken>(\n { options: { ...options, ...customOptions } },\n customExchangeAcrRefreshTokenForAcrAccessTokenOperationSpec\n );\n\n if (!acrAccessToken.accessToken) {\n throw new Error(\"Failed to exchange ACR refresh token for an ACR access token\");\n }\n return acrAccessToken.accessToken;\n }\n}\n"]}
1
+ {"version":3,"file":"containerRegistryTokenCredential.js","sourceRoot":"","sources":["../../src/containerRegistryTokenCredential.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAM9C,MAAM,OAAO,uCAAuC;IAGlD,YACE,UAA2B,EACnB,mBAA2B,EAC3B,UAA4B;QAD5B,wBAAmB,GAAnB,mBAAmB,CAAQ;QAC3B,eAAU,GAAV,UAAU,CAAkB;QAEpC,IAAI,CAAC,YAAY,GAAG,IAAI,6BAA6B,CAAC,UAAU,CAAC,CAAC;QAClE,IAAI,CAAC,iBAAiB,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,QAAQ,CACZ,OAA0B,EAC1B,OAAyC;QAEzC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;YACpB,OAAO,IAAI,CAAC;SACb;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;QACnF,IAAI,CAAC,QAAQ,EAAE;YACb,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;SAClD;QAED,OAAO,IAAI,CAAC,YAAY,CAAC,6CAA6C,CACpE,QAAQ,CAAC,KAAK,EACd,OAAO,CAAC,OAAO,EACf,OAAO,CACR,CAAC;IACJ,CAAC;CACF;AAED,MAAM,OAAO,6BAA6B;IACxC,YAAoB,UAA2B;QAA3B,eAAU,GAAV,UAAU,CAAiB;IAAG,CAAC;IAEnD,KAAK,CAAC,6CAA6C,CACjD,cAAsB,EACtB,OAAe,EACf,OAAwB;QAExB,MAAM,eAAe,GACnB,MAAM,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,wCAAwC,CAC3E,cAAc,EACd,OAAO,kCAEF,OAAO,KACV,WAAW,EAAE,cAAc,IAE9B,CAAC;QACJ,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE;YACjC,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;SAClF;QAED,8CAA8C;QAC9C,MAAM,QAAQ,GAAG,eAAe,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACzD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;YACvB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;SAClE;QACD,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;YAChB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;SACzC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE;YACnB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;SAClE;QAED,2BAA2B;QAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;QACtD,OAAO;YACL,KAAK,EAAE,eAAe,CAAC,YAAY;YACnC,kBAAkB,EAAE,MAAM;SAC3B,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,6CAA6C,CACjD,eAAuB,EACvB,OAAe,EACf,KAAa,EACb,SAAuC,EACvC,OAAwB;QAExB,MAAM,cAAc,GAClB,MAAM,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,wCAAwC,CAC3E,OAAO,EACP,KAAK,EACL,eAAe,EACf,SAAS,EACT,OAAO,CACR,CAAC;QAEJ,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE;YAC/B,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;SACjF;QACD,OAAO,cAAc,CAAC,WAAW,CAAC;IACpC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, GetTokenOptions, TokenCredential } from \"@azure/core-auth\";\nimport { GeneratedClient } from \"./generated\";\nimport { base64decode } from \"./utils/base64\";\n\nexport interface ContainerRegistryGetTokenOptions extends GetTokenOptions {\n service: string;\n}\n\nexport class ContainerRegistryRefreshTokenCredential implements TokenCredential {\n readonly tokenService: ContainerRegistryTokenService;\n readonly isAnonymousAccess: boolean;\n constructor(\n authClient: GeneratedClient,\n private authenticationScope: string,\n private credential?: TokenCredential\n ) {\n this.tokenService = new ContainerRegistryTokenService(authClient);\n this.isAnonymousAccess = !this.credential;\n }\n\n async getToken(\n _scopes: string | string[],\n options: ContainerRegistryGetTokenOptions\n ): Promise<AccessToken | null> {\n if (!this.credential) {\n return null;\n }\n\n const aadToken = await this.credential.getToken(this.authenticationScope, options);\n if (!aadToken) {\n throw new Error(\"Failed to retrieve AAD token.\");\n }\n\n return this.tokenService.ExchangeAadAccessTokenForAcrRefreshTokenAsync(\n aadToken.token,\n options.service,\n options\n );\n }\n}\n\nexport class ContainerRegistryTokenService {\n constructor(private authClient: GeneratedClient) {}\n\n async ExchangeAadAccessTokenForAcrRefreshTokenAsync(\n aadAccessToken: string,\n service: string,\n options: GetTokenOptions\n ): Promise<AccessToken> {\n const acrRefreshToken =\n await this.authClient.authentication.exchangeAadAccessTokenForAcrRefreshToken(\n \"access_token\",\n service,\n {\n ...options,\n accessToken: aadAccessToken,\n }\n );\n if (!acrRefreshToken.refreshToken) {\n throw new Error(\"Failed to exchange AAD access token for an ACR refresh token.\");\n }\n\n // ACR refresh token expires after three hours\n const jwtParts = acrRefreshToken.refreshToken.split(\".\");\n if (jwtParts.length < 3) {\n throw new Error(\"Invalid JWT structure from ACR refresh token.\");\n }\n if (!jwtParts[1]) {\n throw new Error(\"Invalid JWT payload.\");\n }\n\n const jwtPayload = JSON.parse(base64decode(jwtParts[1]));\n if (!jwtPayload.exp) {\n throw new Error(\"Invalid JWT payload structure. No expiration.\");\n }\n\n // JWT expiry is in seconds\n const expiry = Number.parseInt(jwtPayload.exp) * 1000;\n return {\n token: acrRefreshToken.refreshToken,\n expiresOnTimestamp: expiry,\n };\n }\n\n async ExchangeAcrRefreshTokenForAcrAccessTokenAsync(\n acrRefreshToken: string,\n service: string,\n scope: string,\n grantType: \"refresh_token\" | \"password\",\n options: GetTokenOptions\n ): Promise<string> {\n const acrAccessToken =\n await this.authClient.authentication.exchangeAcrRefreshTokenForAcrAccessToken(\n service,\n scope,\n acrRefreshToken,\n grantType,\n options\n );\n\n if (!acrAccessToken.accessToken) {\n throw new Error(\"Failed to exchange ACR refresh token for an ACR access token\");\n }\n return acrAccessToken.accessToken;\n }\n}\n"]}