@azure/identity 2.0.0-beta.2 → 2.0.0-beta.6

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.

Potentially problematic release.


This version of @azure/identity might be problematic. Click here for more details.

Files changed (157) hide show
  1. package/CHANGELOG.md +127 -8
  2. package/README.md +88 -45
  3. package/dist/index.js +2237 -1675
  4. package/dist/index.js.map +1 -1
  5. package/dist-esm/src/client/errors.js +1 -1
  6. package/dist-esm/src/client/errors.js.map +1 -1
  7. package/dist-esm/src/client/identityClient.js +146 -132
  8. package/dist-esm/src/client/identityClient.js.map +1 -1
  9. package/dist-esm/src/constants.js +1 -1
  10. package/dist-esm/src/constants.js.map +1 -1
  11. package/dist-esm/src/credentials/applicationCredential.browser.js +29 -0
  12. package/dist-esm/src/credentials/applicationCredential.browser.js.map +1 -0
  13. package/dist-esm/src/credentials/applicationCredential.js +34 -0
  14. package/dist-esm/src/credentials/applicationCredential.js.map +1 -0
  15. package/dist-esm/src/credentials/authorizationCodeCredential.browser.js.map +1 -1
  16. package/dist-esm/src/credentials/authorizationCodeCredential.js +13 -76
  17. package/dist-esm/src/credentials/authorizationCodeCredential.js.map +1 -1
  18. package/dist-esm/src/credentials/azureCliCredential.browser.js.map +1 -1
  19. package/dist-esm/src/credentials/azureCliCredential.js +104 -81
  20. package/dist-esm/src/credentials/azureCliCredential.js.map +1 -1
  21. package/dist-esm/src/credentials/azureCliCredentialOptions.js +4 -0
  22. package/dist-esm/src/credentials/azureCliCredentialOptions.js.map +1 -0
  23. package/dist-esm/src/credentials/azurePowerShellCredential.browser.js +20 -0
  24. package/dist-esm/src/credentials/azurePowerShellCredential.browser.js.map +1 -0
  25. package/dist-esm/src/credentials/azurePowerShellCredential.js +173 -0
  26. package/dist-esm/src/credentials/azurePowerShellCredential.js.map +1 -0
  27. package/dist-esm/src/credentials/azurePowerShellCredentialOptions.js +4 -0
  28. package/dist-esm/src/credentials/azurePowerShellCredentialOptions.js.map +1 -0
  29. package/dist-esm/src/credentials/chainedTokenCredential.js +37 -34
  30. package/dist-esm/src/credentials/chainedTokenCredential.js.map +1 -1
  31. package/dist-esm/src/credentials/clientCertificateCredential.browser.js.map +1 -1
  32. package/dist-esm/src/credentials/clientCertificateCredential.js +9 -11
  33. package/dist-esm/src/credentials/clientCertificateCredential.js.map +1 -1
  34. package/dist-esm/src/credentials/clientCertificateCredentialOptions.js.map +1 -1
  35. package/dist-esm/src/credentials/clientSecretCredential.browser.js +87 -0
  36. package/dist-esm/src/credentials/clientSecretCredential.browser.js.map +1 -0
  37. package/dist-esm/src/credentials/clientSecretCredential.js +9 -11
  38. package/dist-esm/src/credentials/clientSecretCredential.js.map +1 -1
  39. package/dist-esm/src/credentials/clientSecretCredentialOptions.js.map +1 -1
  40. package/dist-esm/src/credentials/credentialPersistenceOptions.js +4 -0
  41. package/dist-esm/src/credentials/credentialPersistenceOptions.js.map +1 -0
  42. package/dist-esm/src/credentials/defaultAzureCredential.browser.js +1 -1
  43. package/dist-esm/src/credentials/defaultAzureCredential.browser.js.map +1 -1
  44. package/dist-esm/src/credentials/defaultAzureCredential.js +38 -19
  45. package/dist-esm/src/credentials/defaultAzureCredential.js.map +1 -1
  46. package/dist-esm/src/credentials/deviceCodeCredential.browser.js.map +1 -1
  47. package/dist-esm/src/credentials/deviceCodeCredential.js +13 -22
  48. package/dist-esm/src/credentials/deviceCodeCredential.js.map +1 -1
  49. package/dist-esm/src/credentials/deviceCodeCredentialOptions.js.map +1 -1
  50. package/dist-esm/src/credentials/environmentCredential.browser.js.map +1 -1
  51. package/dist-esm/src/credentials/environmentCredential.js +47 -30
  52. package/dist-esm/src/credentials/environmentCredential.js.map +1 -1
  53. package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js +14 -23
  54. package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js.map +1 -1
  55. package/dist-esm/src/credentials/interactiveBrowserCredential.js +20 -26
  56. package/dist-esm/src/credentials/interactiveBrowserCredential.js.map +1 -1
  57. package/dist-esm/src/credentials/interactiveBrowserCredentialOptions.js.map +1 -1
  58. package/dist-esm/src/credentials/interactiveCredentialOptions.js.map +1 -1
  59. package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js +36 -18
  60. package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js.map +1 -1
  61. package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js +61 -42
  62. package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js.map +1 -1
  63. package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js +33 -18
  64. package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js.map +1 -1
  65. package/dist-esm/src/credentials/managedIdentityCredential/constants.js +2 -1
  66. package/dist-esm/src/credentials/managedIdentityCredential/constants.js.map +1 -1
  67. package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js +42 -23
  68. package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js.map +1 -1
  69. package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js +108 -73
  70. package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js.map +1 -1
  71. package/dist-esm/src/credentials/managedIdentityCredential/index.browser.js +3 -6
  72. package/dist-esm/src/credentials/managedIdentityCredential/index.browser.js.map +1 -1
  73. package/dist-esm/src/credentials/managedIdentityCredential/index.js +119 -124
  74. package/dist-esm/src/credentials/managedIdentityCredential/index.js.map +1 -1
  75. package/dist-esm/src/credentials/managedIdentityCredential/models.js.map +1 -1
  76. package/dist-esm/src/credentials/managedIdentityCredential/tokenExchangeMsi.js +82 -0
  77. package/dist-esm/src/credentials/managedIdentityCredential/tokenExchangeMsi.js.map +1 -0
  78. package/dist-esm/src/credentials/managedIdentityCredential/utils.js +14 -8
  79. package/dist-esm/src/credentials/managedIdentityCredential/utils.js.map +1 -1
  80. package/dist-esm/src/credentials/onBehalfOfCredential.browser.js +17 -0
  81. package/dist-esm/src/credentials/onBehalfOfCredential.browser.js.map +1 -0
  82. package/dist-esm/src/credentials/onBehalfOfCredential.js +62 -0
  83. package/dist-esm/src/credentials/onBehalfOfCredential.js.map +1 -0
  84. package/dist-esm/src/credentials/onBehalfOfCredentialOptions.js +4 -0
  85. package/dist-esm/src/credentials/onBehalfOfCredentialOptions.js.map +1 -0
  86. package/dist-esm/src/credentials/usernamePasswordCredential.browser.js +87 -0
  87. package/dist-esm/src/credentials/usernamePasswordCredential.browser.js.map +1 -0
  88. package/dist-esm/src/credentials/usernamePasswordCredential.js +9 -33
  89. package/dist-esm/src/credentials/usernamePasswordCredential.js.map +1 -1
  90. package/dist-esm/src/credentials/usernamePasswordCredentialOptions.js.map +1 -1
  91. package/dist-esm/src/credentials/visualStudioCodeCredential.browser.js +5 -0
  92. package/dist-esm/src/credentials/visualStudioCodeCredential.browser.js.map +1 -1
  93. package/dist-esm/src/credentials/visualStudioCodeCredential.js +70 -68
  94. package/dist-esm/src/credentials/visualStudioCodeCredential.js.map +1 -1
  95. package/dist-esm/src/credentials/visualStudioCodeCredentialPlugin.js +4 -0
  96. package/dist-esm/src/credentials/visualStudioCodeCredentialPlugin.js.map +1 -0
  97. package/dist-esm/src/index.js +6 -1
  98. package/dist-esm/src/index.js.map +1 -1
  99. package/dist-esm/src/msal/browserFlows/browserCommon.js +30 -29
  100. package/dist-esm/src/msal/browserFlows/browserCommon.js.map +1 -1
  101. package/dist-esm/src/msal/browserFlows/msalAuthCode.js +103 -113
  102. package/dist-esm/src/msal/browserFlows/msalAuthCode.js.map +1 -1
  103. package/dist-esm/src/msal/credentials.js.map +1 -1
  104. package/dist-esm/src/msal/errors.js +1 -2
  105. package/dist-esm/src/msal/errors.js.map +1 -1
  106. package/dist-esm/src/msal/flows.js.map +1 -1
  107. package/dist-esm/src/msal/nodeFlows/msalAuthorizationCode.js +41 -0
  108. package/dist-esm/src/msal/nodeFlows/msalAuthorizationCode.js.map +1 -0
  109. package/dist-esm/src/msal/nodeFlows/msalClientCertificate.js +64 -46
  110. package/dist-esm/src/msal/nodeFlows/msalClientCertificate.js.map +1 -1
  111. package/dist-esm/src/msal/nodeFlows/msalClientSecret.js +15 -16
  112. package/dist-esm/src/msal/nodeFlows/msalClientSecret.js.map +1 -1
  113. package/dist-esm/src/msal/nodeFlows/msalDeviceCode.js +20 -22
  114. package/dist-esm/src/msal/nodeFlows/msalDeviceCode.js.map +1 -1
  115. package/dist-esm/src/msal/nodeFlows/msalOnBehalfOf.js +56 -0
  116. package/dist-esm/src/msal/nodeFlows/msalOnBehalfOf.js.map +1 -0
  117. package/dist-esm/src/msal/nodeFlows/msalOpenBrowser.js +43 -32
  118. package/dist-esm/src/msal/nodeFlows/msalOpenBrowser.js.map +1 -1
  119. package/dist-esm/src/msal/nodeFlows/msalUsernamePassword.js +15 -17
  120. package/dist-esm/src/msal/nodeFlows/msalUsernamePassword.js.map +1 -1
  121. package/dist-esm/src/msal/nodeFlows/nodeCommon.js +133 -110
  122. package/dist-esm/src/msal/nodeFlows/nodeCommon.js.map +1 -1
  123. package/dist-esm/src/msal/nodeFlows/tokenCachePersistenceOptions.js +4 -0
  124. package/dist-esm/src/msal/nodeFlows/tokenCachePersistenceOptions.js.map +1 -0
  125. package/dist-esm/src/msal/utils.js +31 -22
  126. package/dist-esm/src/msal/utils.js.map +1 -1
  127. package/dist-esm/src/plugins/consumer.browser.js +7 -0
  128. package/dist-esm/src/plugins/consumer.browser.js.map +1 -0
  129. package/dist-esm/src/plugins/consumer.js +44 -0
  130. package/dist-esm/src/plugins/consumer.js.map +1 -0
  131. package/dist-esm/src/{tokenCache/types.js → plugins/provider.js} +1 -1
  132. package/dist-esm/src/plugins/provider.js.map +1 -0
  133. package/dist-esm/src/regionalAuthority.js +115 -0
  134. package/dist-esm/src/regionalAuthority.js.map +1 -0
  135. package/dist-esm/src/util/logging.js +1 -1
  136. package/dist-esm/src/util/logging.js.map +1 -1
  137. package/dist-esm/src/util/processUtils.js +32 -0
  138. package/dist-esm/src/util/processUtils.js.map +1 -0
  139. package/dist-esm/src/util/scopeUtils.js +22 -0
  140. package/dist-esm/src/util/scopeUtils.js.map +1 -0
  141. package/dist-esm/src/util/tracing.js +23 -26
  142. package/dist-esm/src/util/tracing.js.map +1 -1
  143. package/dist-esm/src/util/validateMultiTenant.js +24 -0
  144. package/dist-esm/src/util/validateMultiTenant.js.map +1 -0
  145. package/package.json +43 -41
  146. package/types/identity.d.ts +500 -131
  147. package/dist-esm/src/tokenCache/TokenCachePersistence.browser.js +0 -23
  148. package/dist-esm/src/tokenCache/TokenCachePersistence.browser.js.map +0 -1
  149. package/dist-esm/src/tokenCache/TokenCachePersistence.js +0 -51
  150. package/dist-esm/src/tokenCache/TokenCachePersistence.js.map +0 -1
  151. package/dist-esm/src/tokenCache/nodeVersion.js +0 -10
  152. package/dist-esm/src/tokenCache/nodeVersion.js.map +0 -1
  153. package/dist-esm/src/tokenCache/persistencePlatforms.js +0 -150
  154. package/dist-esm/src/tokenCache/persistencePlatforms.js.map +0 -1
  155. package/dist-esm/src/tokenCache/types.js.map +0 -1
  156. package/dist-esm/src/util/authHostEnv.js +0 -13
  157. package/dist-esm/src/util/authHostEnv.js.map +0 -1
@@ -1,10 +1,44 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
- import { __awaiter } from "tslib";
4
- import { readFileSync } from "fs";
3
+ import { readFile } from "fs";
5
4
  import { createHash } from "crypto";
5
+ import { promisify } from "util";
6
6
  import { MsalNode } from "./nodeCommon";
7
7
  import { formatError } from "../../util/logging";
8
+ const readFileAsync = promisify(readFile);
9
+ /**
10
+ * Tries to asynchronously load a certificate from the given path.
11
+ *
12
+ * @param certificatePath - Path to the certificate.
13
+ * @param sendCertificateChain - Option to include x5c header for SubjectName and Issuer name authorization.
14
+ * @returns - The certificate parts, or `undefined` if the certificate could not be loaded.
15
+ * @internal
16
+ */
17
+ export async function parseCertificate(certificatePath, sendCertificateChain) {
18
+ const certificateParts = {};
19
+ certificateParts.certificateContents = await readFileAsync(certificatePath, "utf8");
20
+ if (sendCertificateChain) {
21
+ certificateParts.x5c = certificateParts.certificateContents;
22
+ }
23
+ const certificatePattern = /(-+BEGIN CERTIFICATE-+)(\n\r?|\r\n?)([A-Za-z0-9+/\n\r]+=*)(\n\r?|\r\n?)(-+END CERTIFICATE-+)/g;
24
+ const publicKeys = [];
25
+ // Match all possible certificates, in the order they are in the file. These will form the chain that is used for x5c
26
+ let match;
27
+ do {
28
+ match = certificatePattern.exec(certificateParts.certificateContents);
29
+ if (match) {
30
+ publicKeys.push(match[3]);
31
+ }
32
+ } while (match);
33
+ if (publicKeys.length === 0) {
34
+ throw new Error("The file at the specified path does not contain a PEM-encoded certificate.");
35
+ }
36
+ certificateParts.thumbprint = createHash("sha1")
37
+ .update(Buffer.from(publicKeys[0], "base64"))
38
+ .digest("hex")
39
+ .toUpperCase();
40
+ return certificateParts;
41
+ }
8
42
  /**
9
43
  * MSAL client certificate client. Calls to MSAL's confidential application's `acquireTokenByClientCredential` during `doGetToken`.
10
44
  * @internal
@@ -13,57 +47,41 @@ export class MsalClientCertificate extends MsalNode {
13
47
  constructor(options) {
14
48
  super(options);
15
49
  this.requiresConfidential = true;
50
+ this.certificatePath = options.certificatePath;
16
51
  this.sendCertificateChain = options.sendCertificateChain;
17
- const parts = this.parseCertificate(options.certificatePath);
18
- this.msalConfig.auth.clientCertificate = {
19
- thumbprint: parts.thumbprint,
20
- privateKey: parts.certificateContents,
21
- x5c: parts.x5c
22
- };
23
52
  }
24
- parseCertificate(certificatePath) {
25
- const certificateParts = {};
26
- certificateParts.certificateContents = readFileSync(certificatePath, "utf8");
27
- if (this.sendCertificateChain) {
28
- certificateParts.x5c = certificateParts.certificateContents;
53
+ // Changing the MSAL configuration asynchronously
54
+ async init(options) {
55
+ try {
56
+ const parts = await parseCertificate(this.certificatePath, this.sendCertificateChain);
57
+ this.msalConfig.auth.clientCertificate = {
58
+ thumbprint: parts.thumbprint,
59
+ privateKey: parts.certificateContents,
60
+ x5c: parts.x5c
61
+ };
29
62
  }
30
- const certificatePattern = /(-+BEGIN CERTIFICATE-+)(\n\r?|\r\n?)([A-Za-z0-9+/\n\r]+=*)(\n\r?|\r\n?)(-+END CERTIFICATE-+)/g;
31
- const publicKeys = [];
32
- // Match all possible certificates, in the order they are in the file. These will form the chain that is used for x5c
33
- let match;
34
- do {
35
- match = certificatePattern.exec(certificateParts.certificateContents);
36
- if (match) {
37
- publicKeys.push(match[3]);
38
- }
39
- } while (match);
40
- if (publicKeys.length === 0) {
41
- const error = new Error("The file at the specified path does not contain a PEM-encoded certificate.");
63
+ catch (error) {
42
64
  this.logger.info(formatError("", error));
43
65
  throw error;
44
66
  }
45
- certificateParts.thumbprint = createHash("sha1")
46
- .update(Buffer.from(publicKeys[0], "base64"))
47
- .digest("hex")
48
- .toUpperCase();
49
- return certificateParts;
67
+ return super.init(options);
50
68
  }
51
- doGetToken(scopes, options = {}) {
52
- return __awaiter(this, void 0, void 0, function* () {
53
- try {
54
- const result = yield this.confidentialApp.acquireTokenByClientCredential({
55
- scopes,
56
- correlationId: options.correlationId
57
- });
58
- // Even though we're providing the same default in memory persistence cache that we use for DeviceCodeCredential,
59
- // The Client Credential flow does not return the account information from the authentication service,
60
- // so each time getToken gets called, we will have to acquire a new token through the service.
61
- return this.handleResult(scopes, this.clientId, result || undefined);
62
- }
63
- catch (err) {
64
- throw this.handleError(scopes, err, options);
65
- }
66
- });
69
+ async doGetToken(scopes, options = {}) {
70
+ try {
71
+ const result = await this.confidentialApp.acquireTokenByClientCredential({
72
+ scopes,
73
+ correlationId: options.correlationId,
74
+ azureRegion: this.azureRegion,
75
+ authority: options.authority
76
+ });
77
+ // Even though we're providing the same default in memory persistence cache that we use for DeviceCodeCredential,
78
+ // The Client Credential flow does not return the account information from the authentication service,
79
+ // so each time getToken gets called, we will have to acquire a new token through the service.
80
+ return this.handleResult(scopes, this.clientId, result || undefined);
81
+ }
82
+ catch (err) {
83
+ throw this.handleError(scopes, err, options);
84
+ }
67
85
  }
68
86
  }
69
87
  //# sourceMappingURL=msalClientCertificate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"msalClientCertificate.js","sourceRoot":"","sources":["../../../../src/msal/nodeFlows/msalClientCertificate.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAElC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAmB,QAAQ,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAsCjD;;;GAGG;AACH,MAAM,OAAO,qBAAsB,SAAQ,QAAQ;IAGjD,YAAY,OAAqC;QAC/C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACjC,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;QAEzD,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAC7D,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,iBAAiB,GAAG;YACvC,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,UAAU,EAAE,KAAK,CAAC,mBAAmB;YACrC,GAAG,EAAE,KAAK,CAAC,GAAG;SACf,CAAC;IACJ,CAAC;IAEO,gBAAgB,CAAC,eAAuB;QAC9C,MAAM,gBAAgB,GAA8B,EAAE,CAAC;QAEvD,gBAAgB,CAAC,mBAAmB,GAAG,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;QAC7E,IAAI,IAAI,CAAC,oBAAoB,EAAE;YAC7B,gBAAgB,CAAC,GAAG,GAAG,gBAAgB,CAAC,mBAAmB,CAAC;SAC7D;QAED,MAAM,kBAAkB,GAAG,+FAA+F,CAAC;QAC3H,MAAM,UAAU,GAAa,EAAE,CAAC;QAEhC,qHAAqH;QACrH,IAAI,KAAK,CAAC;QACV,GAAG;YACD,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;YACtE,IAAI,KAAK,EAAE;gBACT,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;aAC3B;SACF,QAAQ,KAAK,EAAE;QAEhB,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;YAC3B,MAAM,KAAK,GAAG,IAAI,KAAK,CACrB,4EAA4E,CAC7E,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;YACzC,MAAM,KAAK,CAAC;SACb;QAED,gBAAgB,CAAC,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC;aAC7C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;aAC5C,MAAM,CAAC,KAAK,CAAC;aACb,WAAW,EAAE,CAAC;QAEjB,OAAO,gBAAoC,CAAC;IAC9C,CAAC;IAEe,UAAU,CACxB,MAAgB,EAChB,UAAyC,EAAE;;YAE3C,IAAI;gBACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAgB,CAAC,8BAA8B,CAAC;oBACxE,MAAM;oBACN,aAAa,EAAE,OAAO,CAAC,aAAa;iBACrC,CAAC,CAAC;gBACH,iHAAiH;gBACjH,sGAAsG;gBACtG,8FAA8F;gBAC9F,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,IAAI,SAAS,CAAC,CAAC;aACtE;YAAC,OAAO,GAAG,EAAE;gBACZ,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;aAC9C;QACH,CAAC;KAAA;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { readFileSync } from \"fs\";\nimport { createHash } from \"crypto\";\nimport { AccessToken } from \"@azure/core-http\";\nimport { MsalNodeOptions, MsalNode } from \"./nodeCommon\";\nimport { formatError } from \"../../util/logging\";\nimport { CredentialFlowGetTokenOptions } from \"../credentials\";\n\n/**\n * Options that can be passed to configure MSAL to handle client certificates.\n * @internal\n */\nexport interface MSALClientCertificateOptions extends MsalNodeOptions {\n /**\n * Location of the certificate.\n */\n certificatePath: string;\n /**\n * Option to include x5c header for SubjectName and Issuer name authorization.\n * Set this option to send base64 encoded public certificate in the client assertion header as an x5c claim\n */\n sendCertificateChain?: boolean;\n}\n\n/**\n * Parts of a certificate, as understood by MSAL.\n * @internal\n */\ninterface CertificateParts {\n /**\n * Hex encoded X.509 SHA-1 thumbprint of the certificate\n */\n thumbprint: string;\n /**\n * The PEM encoded private key (string should contain -----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY-----\n */\n certificateContents: string;\n /**\n * x5c header.\n */\n x5c: string;\n}\n\n/**\n * MSAL client certificate client. Calls to MSAL's confidential application's `acquireTokenByClientCredential` during `doGetToken`.\n * @internal\n */\nexport class MsalClientCertificate extends MsalNode {\n private sendCertificateChain?: boolean;\n\n constructor(options: MSALClientCertificateOptions) {\n super(options);\n this.requiresConfidential = true;\n this.sendCertificateChain = options.sendCertificateChain;\n\n const parts = this.parseCertificate(options.certificatePath);\n this.msalConfig.auth.clientCertificate = {\n thumbprint: parts.thumbprint,\n privateKey: parts.certificateContents,\n x5c: parts.x5c\n };\n }\n\n private parseCertificate(certificatePath: string): CertificateParts {\n const certificateParts: Partial<CertificateParts> = {};\n\n certificateParts.certificateContents = readFileSync(certificatePath, \"utf8\");\n if (this.sendCertificateChain) {\n certificateParts.x5c = certificateParts.certificateContents;\n }\n\n const certificatePattern = /(-+BEGIN CERTIFICATE-+)(\\n\\r?|\\r\\n?)([A-Za-z0-9+/\\n\\r]+=*)(\\n\\r?|\\r\\n?)(-+END CERTIFICATE-+)/g;\n const publicKeys: string[] = [];\n\n // Match all possible certificates, in the order they are in the file. These will form the chain that is used for x5c\n let match;\n do {\n match = certificatePattern.exec(certificateParts.certificateContents);\n if (match) {\n publicKeys.push(match[3]);\n }\n } while (match);\n\n if (publicKeys.length === 0) {\n const error = new Error(\n \"The file at the specified path does not contain a PEM-encoded certificate.\"\n );\n this.logger.info(formatError(\"\", error));\n throw error;\n }\n\n certificateParts.thumbprint = createHash(\"sha1\")\n .update(Buffer.from(publicKeys[0], \"base64\"))\n .digest(\"hex\")\n .toUpperCase();\n\n return certificateParts as CertificateParts;\n }\n\n protected async doGetToken(\n scopes: string[],\n options: CredentialFlowGetTokenOptions = {}\n ): Promise<AccessToken> {\n try {\n const result = await this.confidentialApp!.acquireTokenByClientCredential({\n scopes,\n correlationId: options.correlationId\n });\n // Even though we're providing the same default in memory persistence cache that we use for DeviceCodeCredential,\n // The Client Credential flow does not return the account information from the authentication service,\n // so each time getToken gets called, we will have to acquire a new token through the service.\n return this.handleResult(scopes, this.clientId, result || undefined);\n } catch (err) {\n throw this.handleError(scopes, err, options);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"msalClientCertificate.js","sourceRoot":"","sources":["../../../../src/msal/nodeFlows/msalClientCertificate.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { readFile } from \"fs\";\nimport { createHash } from \"crypto\";\nimport { promisify } from \"util\";\nimport { AccessToken } from \"@azure/core-auth\";\n\nimport { MsalNodeOptions, MsalNode } from \"./nodeCommon\";\nimport { formatError } from \"../../util/logging\";\nimport { CredentialFlowGetTokenOptions } from \"../credentials\";\n\nconst readFileAsync = promisify(readFile);\n\n/**\n * Options that can be passed to configure MSAL to handle client certificates.\n * @internal\n */\nexport interface MSALClientCertificateOptions extends MsalNodeOptions {\n /**\n * Location of the PEM certificate.\n */\n certificatePath: string;\n /**\n * Option to include x5c header for SubjectName and Issuer name authorization.\n * Set this option to send base64 encoded public certificate in the client assertion header as an x5c claim\n */\n sendCertificateChain?: boolean;\n}\n\n/**\n * Parts of a certificate, as understood by MSAL.\n * @internal\n */\ninterface CertificateParts {\n /**\n * Hex encoded X.509 SHA-1 thumbprint of the certificate\n */\n thumbprint: string;\n /**\n * The PEM encoded private key (string should contain -----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY-----\n */\n certificateContents: string;\n /**\n * x5c header.\n */\n x5c: string;\n}\n\n/**\n * Tries to asynchronously load a certificate from the given path.\n *\n * @param certificatePath - Path to the certificate.\n * @param sendCertificateChain - Option to include x5c header for SubjectName and Issuer name authorization.\n * @returns - The certificate parts, or `undefined` if the certificate could not be loaded.\n * @internal\n */\nexport async function parseCertificate(\n certificatePath: string,\n sendCertificateChain?: boolean\n): Promise<CertificateParts> {\n const certificateParts: Partial<CertificateParts> = {};\n\n certificateParts.certificateContents = await readFileAsync(certificatePath, \"utf8\");\n if (sendCertificateChain) {\n certificateParts.x5c = certificateParts.certificateContents;\n }\n\n const certificatePattern = /(-+BEGIN CERTIFICATE-+)(\\n\\r?|\\r\\n?)([A-Za-z0-9+/\\n\\r]+=*)(\\n\\r?|\\r\\n?)(-+END CERTIFICATE-+)/g;\n const publicKeys: string[] = [];\n\n // Match all possible certificates, in the order they are in the file. These will form the chain that is used for x5c\n let match;\n do {\n match = certificatePattern.exec(certificateParts.certificateContents);\n if (match) {\n publicKeys.push(match[3]);\n }\n } while (match);\n\n if (publicKeys.length === 0) {\n throw new Error(\"The file at the specified path does not contain a PEM-encoded certificate.\");\n }\n\n certificateParts.thumbprint = createHash(\"sha1\")\n .update(Buffer.from(publicKeys[0], \"base64\"))\n .digest(\"hex\")\n .toUpperCase();\n\n return certificateParts as CertificateParts;\n}\n\n/**\n * MSAL client certificate client. Calls to MSAL's confidential application's `acquireTokenByClientCredential` during `doGetToken`.\n * @internal\n */\nexport class MsalClientCertificate extends MsalNode {\n private certificatePath: string;\n private sendCertificateChain?: boolean;\n\n constructor(options: MSALClientCertificateOptions) {\n super(options);\n this.requiresConfidential = true;\n this.certificatePath = options.certificatePath;\n this.sendCertificateChain = options.sendCertificateChain;\n }\n\n // Changing the MSAL configuration asynchronously\n async init(options?: CredentialFlowGetTokenOptions): Promise<void> {\n try {\n const parts = await parseCertificate(this.certificatePath, this.sendCertificateChain);\n this.msalConfig.auth.clientCertificate = {\n thumbprint: parts.thumbprint,\n privateKey: parts.certificateContents,\n x5c: parts.x5c\n };\n } catch (error) {\n this.logger.info(formatError(\"\", error));\n throw error;\n }\n return super.init(options);\n }\n\n protected async doGetToken(\n scopes: string[],\n options: CredentialFlowGetTokenOptions = {}\n ): Promise<AccessToken> {\n try {\n const result = await this.confidentialApp!.acquireTokenByClientCredential({\n scopes,\n correlationId: options.correlationId,\n azureRegion: this.azureRegion,\n authority: options.authority\n });\n // Even though we're providing the same default in memory persistence cache that we use for DeviceCodeCredential,\n // The Client Credential flow does not return the account information from the authentication service,\n // so each time getToken gets called, we will have to acquire a new token through the service.\n return this.handleResult(scopes, this.clientId, result || undefined);\n } catch (err) {\n throw this.handleError(scopes, err, options);\n }\n }\n}\n"]}
@@ -1,6 +1,5 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
- import { __awaiter } from "tslib";
4
3
  import { MsalNode } from "./nodeCommon";
5
4
  /**
6
5
  * MSAL client secret client. Calls to MSAL's confidential application's `acquireTokenByClientCredential` during `doGetToken`.
@@ -12,21 +11,21 @@ export class MsalClientSecret extends MsalNode {
12
11
  this.requiresConfidential = true;
13
12
  this.msalConfig.auth.clientSecret = options.clientSecret;
14
13
  }
15
- doGetToken(scopes, options = {}) {
16
- return __awaiter(this, void 0, void 0, function* () {
17
- try {
18
- const result = yield this.confidentialApp.acquireTokenByClientCredential({
19
- scopes,
20
- correlationId: options.correlationId
21
- });
22
- // The Client Credential flow does not return an account,
23
- // so each time getToken gets called, we will have to acquire a new token through the service.
24
- return this.handleResult(scopes, this.clientId, result || undefined);
25
- }
26
- catch (err) {
27
- throw this.handleError(scopes, err, options);
28
- }
29
- });
14
+ async doGetToken(scopes, options = {}) {
15
+ try {
16
+ const result = await this.confidentialApp.acquireTokenByClientCredential({
17
+ scopes,
18
+ correlationId: options.correlationId,
19
+ azureRegion: this.azureRegion,
20
+ authority: options.authority
21
+ });
22
+ // The Client Credential flow does not return an account,
23
+ // so each time getToken gets called, we will have to acquire a new token through the service.
24
+ return this.handleResult(scopes, this.clientId, result || undefined);
25
+ }
26
+ catch (err) {
27
+ throw this.handleError(scopes, err, options);
28
+ }
30
29
  }
31
30
  }
32
31
  //# sourceMappingURL=msalClientSecret.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"msalClientSecret.js","sourceRoot":"","sources":["../../../../src/msal/nodeFlows/msalClientSecret.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAIlC,OAAO,EAAmB,QAAQ,EAAE,MAAM,cAAc,CAAC;AAUzD;;;GAGG;AACH,MAAM,OAAO,gBAAiB,SAAQ,QAAQ;IAC5C,YAAY,OAAgC;QAC1C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAC3D,CAAC;IAEe,UAAU,CACxB,MAAgB,EAChB,UAAyC,EAAE;;YAE3C,IAAI;gBACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAgB,CAAC,8BAA8B,CAAC;oBACxE,MAAM;oBACN,aAAa,EAAE,OAAO,CAAC,aAAa;iBACrC,CAAC,CAAC;gBACH,yDAAyD;gBACzD,8FAA8F;gBAC9F,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,IAAI,SAAS,CAAC,CAAC;aACtE;YAAC,OAAO,GAAG,EAAE;gBACZ,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;aAC9C;QACH,CAAC;KAAA;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken } from \"@azure/core-http\";\nimport { CredentialFlowGetTokenOptions } from \"../credentials\";\nimport { MsalNodeOptions, MsalNode } from \"./nodeCommon\";\n\n/**\n * Options that can be passed to configure MSAL to handle client secrets.\n * @internal\n */\nexport interface MSALClientSecretOptions extends MsalNodeOptions {\n clientSecret: string;\n}\n\n/**\n * MSAL client secret client. Calls to MSAL's confidential application's `acquireTokenByClientCredential` during `doGetToken`.\n * @internal\n */\nexport class MsalClientSecret extends MsalNode {\n constructor(options: MSALClientSecretOptions) {\n super(options);\n this.requiresConfidential = true;\n this.msalConfig.auth.clientSecret = options.clientSecret;\n }\n\n protected async doGetToken(\n scopes: string[],\n options: CredentialFlowGetTokenOptions = {}\n ): Promise<AccessToken> {\n try {\n const result = await this.confidentialApp!.acquireTokenByClientCredential({\n scopes,\n correlationId: options.correlationId\n });\n // The Client Credential flow does not return an account,\n // so each time getToken gets called, we will have to acquire a new token through the service.\n return this.handleResult(scopes, this.clientId, result || undefined);\n } catch (err) {\n throw this.handleError(scopes, err, options);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"msalClientSecret.js","sourceRoot":"","sources":["../../../../src/msal/nodeFlows/msalClientSecret.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAKlC,OAAO,EAAmB,QAAQ,EAAE,MAAM,cAAc,CAAC;AAazD;;;GAGG;AACH,MAAM,OAAO,gBAAiB,SAAQ,QAAQ;IAC5C,YAAY,OAAgC;QAC1C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAC3D,CAAC;IAES,KAAK,CAAC,UAAU,CACxB,MAAgB,EAChB,UAAyC,EAAE;QAE3C,IAAI;YACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAgB,CAAC,8BAA8B,CAAC;gBACxE,MAAM;gBACN,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,SAAS,EAAE,OAAO,CAAC,SAAS;aAC7B,CAAC,CAAC;YACH,yDAAyD;YACzD,8FAA8F;YAC9F,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,IAAI,SAAS,CAAC,CAAC;SACtE;QAAC,OAAO,GAAG,EAAE;YACZ,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;SAC9C;IACH,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken } from \"@azure/core-auth\";\n\nimport { CredentialFlowGetTokenOptions } from \"../credentials\";\nimport { MsalNodeOptions, MsalNode } from \"./nodeCommon\";\n\n/**\n * Options that can be passed to configure MSAL to handle client secrets.\n * @internal\n */\nexport interface MSALClientSecretOptions extends MsalNodeOptions {\n /**\n * A client secret that was generated for the App Registration.\n */\n clientSecret: string;\n}\n\n/**\n * MSAL client secret client. Calls to MSAL's confidential application's `acquireTokenByClientCredential` during `doGetToken`.\n * @internal\n */\nexport class MsalClientSecret extends MsalNode {\n constructor(options: MSALClientSecretOptions) {\n super(options);\n this.requiresConfidential = true;\n this.msalConfig.auth.clientSecret = options.clientSecret;\n }\n\n protected async doGetToken(\n scopes: string[],\n options: CredentialFlowGetTokenOptions = {}\n ): Promise<AccessToken> {\n try {\n const result = await this.confidentialApp!.acquireTokenByClientCredential({\n scopes,\n correlationId: options.correlationId,\n azureRegion: this.azureRegion,\n authority: options.authority\n });\n // The Client Credential flow does not return an account,\n // so each time getToken gets called, we will have to acquire a new token through the service.\n return this.handleResult(scopes, this.clientId, result || undefined);\n } catch (err) {\n throw this.handleError(scopes, err, options);\n }\n }\n}\n"]}
@@ -1,6 +1,5 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
- import { __awaiter } from "tslib";
4
3
  import { MsalNode } from "./nodeCommon";
5
4
  /**
6
5
  * MSAL device code client. Calls to the MSAL's public application's `acquireTokenByDeviceCode` during `doGetToken`.
@@ -11,27 +10,26 @@ export class MsalDeviceCode extends MsalNode {
11
10
  super(options);
12
11
  this.userPromptCallback = options.userPromptCallback;
13
12
  }
14
- doGetToken(scopes, options) {
15
- return __awaiter(this, void 0, void 0, function* () {
16
- try {
17
- const requestOptions = {
18
- deviceCodeCallback: this.userPromptCallback,
19
- scopes,
20
- cancel: false,
21
- correlationId: options === null || options === void 0 ? void 0 : options.correlationId
22
- };
23
- const promise = this.publicApp.acquireTokenByDeviceCode(requestOptions);
24
- // TODO:
25
- // This should work, but it currently doesn't. I'm waiting for an answer from the MSAL team.
26
- const deviceResponse = yield this.withCancellation(promise, options === null || options === void 0 ? void 0 : options.abortSignal, () => {
27
- requestOptions.cancel = true;
28
- });
29
- return this.handleResult(scopes, this.clientId, deviceResponse || undefined);
30
- }
31
- catch (error) {
32
- throw this.handleError(scopes, error, options);
33
- }
34
- });
13
+ async doGetToken(scopes, options) {
14
+ try {
15
+ const requestOptions = {
16
+ deviceCodeCallback: this.userPromptCallback,
17
+ scopes,
18
+ cancel: false,
19
+ correlationId: options === null || options === void 0 ? void 0 : options.correlationId,
20
+ authority: options === null || options === void 0 ? void 0 : options.authority
21
+ };
22
+ const promise = this.publicApp.acquireTokenByDeviceCode(requestOptions);
23
+ // TODO:
24
+ // This should work, but it currently doesn't. I'm waiting for an answer from the MSAL team.
25
+ const deviceResponse = await this.withCancellation(promise, options === null || options === void 0 ? void 0 : options.abortSignal, () => {
26
+ requestOptions.cancel = true;
27
+ });
28
+ return this.handleResult(scopes, this.clientId, deviceResponse || undefined);
29
+ }
30
+ catch (error) {
31
+ throw this.handleError(scopes, error, options);
32
+ }
35
33
  }
36
34
  }
37
35
  //# sourceMappingURL=msalDeviceCode.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"msalDeviceCode.js","sourceRoot":"","sources":["../../../../src/msal/nodeFlows/msalDeviceCode.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAMlC,OAAO,EAAmB,QAAQ,EAAE,MAAM,cAAc,CAAC;AAUzD;;;GAGG;AACH,MAAM,OAAO,cAAe,SAAQ,QAAQ;IAG1C,YAAY,OAA8B;QACxC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IACvD,CAAC;IAEe,UAAU,CACxB,MAAgB,EAChB,OAAuC;;YAEvC,IAAI;gBACF,MAAM,cAAc,GAA+B;oBACjD,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;oBAC3C,MAAM;oBACN,MAAM,EAAE,KAAK;oBACb,aAAa,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,aAAa;iBACtC,CAAC;gBACF,MAAM,OAAO,GAAG,IAAI,CAAC,SAAU,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC;gBACzE,QAAQ;gBACR,4FAA4F;gBAC5F,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW,EAAE,GAAG,EAAE;oBACrF,cAAc,CAAC,MAAM,GAAG,IAAI,CAAC;gBAC/B,CAAC,CAAC,CAAC;gBACH,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,cAAc,IAAI,SAAS,CAAC,CAAC;aAC9E;YAAC,OAAO,KAAK,EAAE;gBACd,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;aAChD;QACH,CAAC;KAAA;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport * as msalNode from \"@azure/msal-node\";\nimport { AccessToken } from \"@azure/core-http\";\nimport { DeviceCodePromptCallback } from \"../../credentials/deviceCodeCredentialOptions\";\nimport { CredentialFlowGetTokenOptions } from \"../credentials\";\nimport { MsalNodeOptions, MsalNode } from \"./nodeCommon\";\n\n/**\n * Options that can be passed to configure MSAL to handle authentication through device codes.\n * @internal\n */\nexport interface MSALDeviceCodeOptions extends MsalNodeOptions {\n userPromptCallback: DeviceCodePromptCallback;\n}\n\n/**\n * MSAL device code client. Calls to the MSAL's public application's `acquireTokenByDeviceCode` during `doGetToken`.\n * @internal\n */\nexport class MsalDeviceCode extends MsalNode {\n private userPromptCallback: DeviceCodePromptCallback;\n\n constructor(options: MSALDeviceCodeOptions) {\n super(options);\n this.userPromptCallback = options.userPromptCallback;\n }\n\n protected async doGetToken(\n scopes: string[],\n options?: CredentialFlowGetTokenOptions\n ): Promise<AccessToken> {\n try {\n const requestOptions: msalNode.DeviceCodeRequest = {\n deviceCodeCallback: this.userPromptCallback,\n scopes,\n cancel: false,\n correlationId: options?.correlationId\n };\n const promise = this.publicApp!.acquireTokenByDeviceCode(requestOptions);\n // TODO:\n // This should work, but it currently doesn't. I'm waiting for an answer from the MSAL team.\n const deviceResponse = await this.withCancellation(promise, options?.abortSignal, () => {\n requestOptions.cancel = true;\n });\n return this.handleResult(scopes, this.clientId, deviceResponse || undefined);\n } catch (error) {\n throw this.handleError(scopes, error, options);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"msalDeviceCode.js","sourceRoot":"","sources":["../../../../src/msal/nodeFlows/msalDeviceCode.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAQlC,OAAO,EAAmB,QAAQ,EAAE,MAAM,cAAc,CAAC;AAUzD;;;GAGG;AACH,MAAM,OAAO,cAAe,SAAQ,QAAQ;IAG1C,YAAY,OAA8B;QACxC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IACvD,CAAC;IAES,KAAK,CAAC,UAAU,CACxB,MAAgB,EAChB,OAAuC;QAEvC,IAAI;YACF,MAAM,cAAc,GAA+B;gBACjD,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;gBAC3C,MAAM;gBACN,MAAM,EAAE,KAAK;gBACb,aAAa,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,aAAa;gBACrC,SAAS,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS;aAC9B,CAAC;YACF,MAAM,OAAO,GAAG,IAAI,CAAC,SAAU,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC;YACzE,QAAQ;YACR,4FAA4F;YAC5F,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW,EAAE,GAAG,EAAE;gBACrF,cAAc,CAAC,MAAM,GAAG,IAAI,CAAC;YAC/B,CAAC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,cAAc,IAAI,SAAS,CAAC,CAAC;SAC9E;QAAC,OAAO,KAAK,EAAE;YACd,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;SAChD;IACH,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport * as msalNode from \"@azure/msal-node\";\n\nimport { AccessToken } from \"@azure/core-auth\";\n\nimport { DeviceCodePromptCallback } from \"../../credentials/deviceCodeCredentialOptions\";\nimport { CredentialFlowGetTokenOptions } from \"../credentials\";\nimport { MsalNodeOptions, MsalNode } from \"./nodeCommon\";\n\n/**\n * Options that can be passed to configure MSAL to handle authentication through device codes.\n * @internal\n */\nexport interface MSALDeviceCodeOptions extends MsalNodeOptions {\n userPromptCallback: DeviceCodePromptCallback;\n}\n\n/**\n * MSAL device code client. Calls to the MSAL's public application's `acquireTokenByDeviceCode` during `doGetToken`.\n * @internal\n */\nexport class MsalDeviceCode extends MsalNode {\n private userPromptCallback: DeviceCodePromptCallback;\n\n constructor(options: MSALDeviceCodeOptions) {\n super(options);\n this.userPromptCallback = options.userPromptCallback;\n }\n\n protected async doGetToken(\n scopes: string[],\n options?: CredentialFlowGetTokenOptions\n ): Promise<AccessToken> {\n try {\n const requestOptions: msalNode.DeviceCodeRequest = {\n deviceCodeCallback: this.userPromptCallback,\n scopes,\n cancel: false,\n correlationId: options?.correlationId,\n authority: options?.authority\n };\n const promise = this.publicApp!.acquireTokenByDeviceCode(requestOptions);\n // TODO:\n // This should work, but it currently doesn't. I'm waiting for an answer from the MSAL team.\n const deviceResponse = await this.withCancellation(promise, options?.abortSignal, () => {\n requestOptions.cancel = true;\n });\n return this.handleResult(scopes, this.clientId, deviceResponse || undefined);\n } catch (error) {\n throw this.handleError(scopes, error, options);\n }\n }\n}\n"]}
@@ -0,0 +1,56 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT license.
3
+ import { formatError } from "../../util/logging";
4
+ import { parseCertificate } from "./msalClientCertificate";
5
+ import { MsalNode } from "./nodeCommon";
6
+ /**
7
+ * MSAL on behalf of flow. Calls to MSAL's confidential application's `acquireTokenOnBehalfOf` during `doGetToken`.
8
+ * @internal
9
+ */
10
+ export class MsalOnBehalfOf extends MsalNode {
11
+ constructor(options) {
12
+ super(options);
13
+ this.logger.info("Initialized MSAL's On-Behalf-Of flow");
14
+ this.requiresConfidential = true;
15
+ this.userAssertionToken = options.userAssertionToken;
16
+ this.certificatePath = options.certificatePath;
17
+ this.sendCertificateChain = options.sendCertificateChain;
18
+ this.clientSecret = options.clientSecret;
19
+ }
20
+ // Changing the MSAL configuration asynchronously
21
+ async init(options) {
22
+ if (this.certificatePath) {
23
+ try {
24
+ const parts = await parseCertificate(this.certificatePath, this.sendCertificateChain);
25
+ this.msalConfig.auth.clientCertificate = {
26
+ thumbprint: parts.thumbprint,
27
+ privateKey: parts.certificateContents,
28
+ x5c: parts.x5c
29
+ };
30
+ }
31
+ catch (error) {
32
+ this.logger.info(formatError("", error));
33
+ throw error;
34
+ }
35
+ }
36
+ else {
37
+ this.msalConfig.auth.clientSecret = this.clientSecret;
38
+ }
39
+ return super.init(options);
40
+ }
41
+ async doGetToken(scopes, options = {}) {
42
+ try {
43
+ const result = await this.confidentialApp.acquireTokenOnBehalfOf({
44
+ scopes,
45
+ correlationId: options.correlationId,
46
+ authority: options.authority,
47
+ oboAssertion: this.userAssertionToken
48
+ });
49
+ return this.handleResult(scopes, this.clientId, result || undefined);
50
+ }
51
+ catch (err) {
52
+ throw this.handleError(scopes, err, options);
53
+ }
54
+ }
55
+ }
56
+ //# sourceMappingURL=msalOnBehalfOf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"msalOnBehalfOf.js","sourceRoot":"","sources":["../../../../src/msal/nodeFlows/msalOnBehalfOf.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAmB,QAAQ,EAAE,MAAM,cAAc,CAAC;AA0BzD;;;GAGG;AACH,MAAM,OAAO,cAAe,SAAQ,QAAQ;IAM1C,YAAY,OAA8B;QACxC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;QACzD,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACjC,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;QACrD,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;QAC/C,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;QACzD,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAC3C,CAAC;IAED,iDAAiD;IACjD,KAAK,CAAC,IAAI,CAAC,OAAuC;QAChD,IAAI,IAAI,CAAC,eAAe,EAAE;YACxB,IAAI;gBACF,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC;gBACtF,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,iBAAiB,GAAG;oBACvC,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,UAAU,EAAE,KAAK,CAAC,mBAAmB;oBACrC,GAAG,EAAE,KAAK,CAAC,GAAG;iBACf,CAAC;aACH;YAAC,OAAO,KAAK,EAAE;gBACd,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;gBACzC,MAAM,KAAK,CAAC;aACb;SACF;aAAM;YACL,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;SACvD;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAES,KAAK,CAAC,UAAU,CACxB,MAAgB,EAChB,UAAyC,EAAE;QAE3C,IAAI;YACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAgB,CAAC,sBAAsB,CAAC;gBAChE,MAAM;gBACN,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,YAAY,EAAE,IAAI,CAAC,kBAAkB;aACtC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,IAAI,SAAS,CAAC,CAAC;SACtE;QAAC,OAAO,GAAG,EAAE;YACZ,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;SAC9C;IACH,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken } from \"@azure/core-auth\";\nimport { formatError } from \"../../util/logging\";\nimport { CredentialFlowGetTokenOptions } from \"../credentials\";\nimport { parseCertificate } from \"./msalClientCertificate\";\nimport { MsalNodeOptions, MsalNode } from \"./nodeCommon\";\n\n/**\n * Options that can be passed to configure MSAL to handle On-Behalf-Of authentication requests.\n * @internal\n */\nexport interface MSALOnBehalfOfOptions extends MsalNodeOptions {\n /**\n * A client secret that was generated for the App Registration.\n */\n clientSecret?: string;\n /**\n * Location of the PEM certificate.\n */\n certificatePath?: string;\n /**\n * Option to include x5c header for SubjectName and Issuer name authorization.\n * Set this option to send base64 encoded public certificate in the client assertion header as an x5c claim\n */\n sendCertificateChain?: boolean;\n /**\n * The user assertion for the On-Behalf-Of flow.\n */\n userAssertionToken: string;\n}\n\n/**\n * MSAL on behalf of flow. Calls to MSAL's confidential application's `acquireTokenOnBehalfOf` during `doGetToken`.\n * @internal\n */\nexport class MsalOnBehalfOf extends MsalNode {\n private userAssertionToken: string;\n private certificatePath?: string;\n private sendCertificateChain?: boolean;\n private clientSecret?: string;\n\n constructor(options: MSALOnBehalfOfOptions) {\n super(options);\n this.logger.info(\"Initialized MSAL's On-Behalf-Of flow\");\n this.requiresConfidential = true;\n this.userAssertionToken = options.userAssertionToken;\n this.certificatePath = options.certificatePath;\n this.sendCertificateChain = options.sendCertificateChain;\n this.clientSecret = options.clientSecret;\n }\n\n // Changing the MSAL configuration asynchronously\n async init(options?: CredentialFlowGetTokenOptions): Promise<void> {\n if (this.certificatePath) {\n try {\n const parts = await parseCertificate(this.certificatePath, this.sendCertificateChain);\n this.msalConfig.auth.clientCertificate = {\n thumbprint: parts.thumbprint,\n privateKey: parts.certificateContents,\n x5c: parts.x5c\n };\n } catch (error) {\n this.logger.info(formatError(\"\", error));\n throw error;\n }\n } else {\n this.msalConfig.auth.clientSecret = this.clientSecret;\n }\n return super.init(options);\n }\n\n protected async doGetToken(\n scopes: string[],\n options: CredentialFlowGetTokenOptions = {}\n ): Promise<AccessToken> {\n try {\n const result = await this.confidentialApp!.acquireTokenOnBehalfOf({\n scopes,\n correlationId: options.correlationId,\n authority: options.authority,\n oboAssertion: this.userAssertionToken\n });\n return this.handleResult(scopes, this.clientId, result || undefined);\n } catch (err) {\n throw this.handleError(scopes, err, options);\n }\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
- import { __awaiter } from "tslib";
3
+ import * as msalNode from "@azure/msal-node";
4
4
  import http from "http";
5
5
  import open from "open";
6
6
  import stoppable from "stoppable";
@@ -23,8 +23,9 @@ export const interactiveBrowserMockable = {
23
23
  export class MsalOpenBrowser extends MsalNode {
24
24
  constructor(options) {
25
25
  super(options);
26
- this.logger = credentialLogger("NodeJS MSAL Open Browser");
26
+ this.logger = credentialLogger("Node.js MSAL Open Browser");
27
27
  this.redirectUri = options.redirectUri;
28
+ this.loginHint = options.loginHint;
28
29
  const url = new URL(this.redirectUri);
29
30
  this.port = parseInt(url.port);
30
31
  if (isNaN(this.port)) {
@@ -32,15 +33,14 @@ export class MsalOpenBrowser extends MsalNode {
32
33
  }
33
34
  this.hostname = url.hostname;
34
35
  }
35
- acquireTokenByCode(request) {
36
- return __awaiter(this, void 0, void 0, function* () {
37
- return this.publicApp.acquireTokenByCode(request);
38
- });
36
+ async acquireTokenByCode(request) {
37
+ return this.publicApp.acquireTokenByCode(request);
39
38
  }
40
39
  doGetToken(scopes, options) {
41
40
  return new Promise((resolve, reject) => {
42
41
  const socketToDestroy = [];
43
42
  const requestListener = (req, res) => {
43
+ var _a;
44
44
  if (!req.url) {
45
45
  reject(new Error(`Interactive Browser Authentication Error "Did not receive token with a valid expiration"`));
46
46
  return;
@@ -56,7 +56,9 @@ export class MsalOpenBrowser extends MsalNode {
56
56
  const tokenRequest = {
57
57
  code: url.searchParams.get("code"),
58
58
  redirectUri: this.redirectUri,
59
- scopes: scopes
59
+ scopes: scopes,
60
+ authority: options === null || options === void 0 ? void 0 : options.authority,
61
+ codeVerifier: (_a = this.pkceCodes) === null || _a === void 0 ? void 0 : _a.verifier
60
62
  };
61
63
  this.acquireTokenByCode(tokenRequest)
62
64
  .then((authResponse) => {
@@ -94,13 +96,8 @@ export class MsalOpenBrowser extends MsalNode {
94
96
  });
95
97
  };
96
98
  const app = http.createServer(requestListener);
97
- const listen = app.listen(this.port, this.hostname, () => this.logger.info(`InteractiveBrowserCredential listening on port ${this.port}!`));
98
- app.on("connection", (socket) => socketToDestroy.push(socket));
99
99
  const server = stoppable(app);
100
- this.openAuthCodeUrl(scopes).catch((e) => {
101
- cleanup();
102
- reject(e);
103
- });
100
+ const listen = app.listen(this.port, this.hostname, () => this.logger.info(`InteractiveBrowserCredential listening on port ${this.port}!`));
104
101
  function cleanup() {
105
102
  if (listen) {
106
103
  listen.close();
@@ -113,29 +110,43 @@ export class MsalOpenBrowser extends MsalNode {
113
110
  server.stop();
114
111
  }
115
112
  }
116
- const abortSignal = options === null || options === void 0 ? void 0 : options.abortSignal;
117
- if (abortSignal) {
118
- abortSignal.addEventListener("abort", () => {
113
+ app.on("connection", (socket) => socketToDestroy.push(socket));
114
+ app.on("listening", () => {
115
+ const openPromise = this.openAuthCodeUrl(scopes, options);
116
+ const abortSignal = options === null || options === void 0 ? void 0 : options.abortSignal;
117
+ if (abortSignal) {
118
+ abortSignal.addEventListener("abort", () => {
119
+ cleanup();
120
+ reject(new Error("Aborted"));
121
+ });
122
+ }
123
+ openPromise.then().catch((e) => {
119
124
  cleanup();
120
- reject(new Error("Aborted"));
125
+ reject(e);
121
126
  });
122
- }
127
+ });
123
128
  });
124
129
  }
125
- openAuthCodeUrl(scopeArray) {
126
- return __awaiter(this, void 0, void 0, function* () {
127
- const authCodeUrlParameters = {
128
- scopes: scopeArray,
129
- redirectUri: this.redirectUri
130
- };
131
- const response = yield this.publicApp.getAuthCodeUrl(authCodeUrlParameters);
132
- try {
133
- yield interactiveBrowserMockable.open(response, { wait: true });
134
- }
135
- catch (e) {
136
- throw new CredentialUnavailableError(`Could not open a browser window. Error: ${e.message}`);
137
- }
138
- });
130
+ async openAuthCodeUrl(scopeArray, options) {
131
+ // Initialize CryptoProvider instance
132
+ const cryptoProvider = new msalNode.CryptoProvider();
133
+ // Generate PKCE Codes before starting the authorization flow
134
+ this.pkceCodes = await cryptoProvider.generatePkceCodes();
135
+ const authCodeUrlParameters = {
136
+ scopes: scopeArray,
137
+ redirectUri: this.redirectUri,
138
+ authority: options === null || options === void 0 ? void 0 : options.authority,
139
+ loginHint: this.loginHint,
140
+ codeChallenge: this.pkceCodes.challenge,
141
+ codeChallengeMethod: "S256" // Use SHA256 Algorithm
142
+ };
143
+ const response = await this.publicApp.getAuthCodeUrl(authCodeUrlParameters);
144
+ try {
145
+ await interactiveBrowserMockable.open(response, { wait: true });
146
+ }
147
+ catch (e) {
148
+ throw new CredentialUnavailableError(`Could not open a browser window. Error: ${e.message}`);
149
+ }
139
150
  }
140
151
  }
141
152
  //# sourceMappingURL=msalOpenBrowser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"msalOpenBrowser.js","sourceRoot":"","sources":["../../../../src/msal/nodeFlows/msalOpenBrowser.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport * as msalNode from \"@azure/msal-node\";\nimport { Socket } from \"net\";\nimport http from \"http\";\nimport open from \"open\";\nimport stoppable from \"stoppable\";\nimport { AccessToken, GetTokenOptions } from \"@azure/core-http\";\nimport { credentialLogger, formatError, formatSuccess } from \"../../util/logging\";\nimport { MsalNodeOptions, MsalNode } from \"./nodeCommon\";\nimport { msalToPublic } from \"../utils\";\nimport { CredentialUnavailableError } from \"../../client/errors\";\n\n/**\n * Options that can be passed to configure MSAL to handle authentication through opening a browser window.\n * @internal\n */\nexport interface MSALOpenBrowserOptions extends MsalNodeOptions {\n redirectUri: string;\n}\n\n/**\n * A call to open(), but mockable\n * @internal\n */\nexport const interactiveBrowserMockable = {\n open\n};\n\n/**\n * This MSAL client sets up a web server to listen for redirect callbacks, then calls to the MSAL's public application's `acquireTokenByDeviceCode` during `doGetToken`\n * to trigger the authentication flow, and then respond based on the values obtained from the redirect callback\n * @internal\n */\nexport class MsalOpenBrowser extends MsalNode {\n private redirectUri: string;\n private port: number;\n private hostname: string;\n\n constructor(options: MSALOpenBrowserOptions) {\n super(options);\n this.logger = credentialLogger(\"NodeJS MSAL Open Browser\");\n this.redirectUri = options.redirectUri;\n\n const url = new URL(this.redirectUri);\n this.port = parseInt(url.port);\n if (isNaN(this.port)) {\n this.port = 80;\n }\n this.hostname = url.hostname;\n }\n\n private async acquireTokenByCode(\n request: msalNode.AuthorizationCodeRequest\n ): Promise<msalNode.AuthenticationResult | null> {\n return this.publicApp!.acquireTokenByCode(request);\n }\n\n protected doGetToken(scopes: string[], options?: GetTokenOptions): Promise<AccessToken> {\n return new Promise<AccessToken>((resolve, reject) => {\n const socketToDestroy: Socket[] = [];\n\n const requestListener = (req: http.IncomingMessage, res: http.ServerResponse): void => {\n if (!req.url) {\n reject(\n new Error(\n `Interactive Browser Authentication Error \"Did not receive token with a valid expiration\"`\n )\n );\n return;\n }\n let url: URL;\n try {\n url = new URL(req.url, this.redirectUri);\n } catch (e) {\n reject(\n new Error(\n `Interactive Browser Authentication Error \"Did not receive token with a valid expiration\"`\n )\n );\n return;\n }\n const tokenRequest: msalNode.AuthorizationCodeRequest = {\n code: url.searchParams.get(\"code\")!,\n redirectUri: this.redirectUri,\n scopes: scopes\n };\n\n this.acquireTokenByCode(tokenRequest)\n .then((authResponse) => {\n if (authResponse?.account) {\n this.account = msalToPublic(this.clientId, authResponse.account);\n }\n const successMessage = `Authentication Complete. You can close the browser and return to the application.`;\n if (authResponse && authResponse.expiresOn) {\n const expiresOnTimestamp = authResponse?.expiresOn.valueOf();\n res.writeHead(200);\n res.end(successMessage);\n this.logger.getToken.info(formatSuccess(scopes));\n\n resolve({\n expiresOnTimestamp,\n token: authResponse.accessToken\n });\n } else {\n const errorMessage = formatError(\n scopes,\n `${url.searchParams.get(\"error\")}. ${url.searchParams.get(\"error_description\")}`\n );\n res.writeHead(500);\n res.end(errorMessage);\n this.logger.getToken.info(errorMessage);\n\n reject(\n new Error(\n `Interactive Browser Authentication Error \"Did not receive token with a valid expiration\"`\n )\n );\n }\n cleanup();\n return;\n })\n .catch(() => {\n const errorMessage = formatError(\n scopes,\n `${url.searchParams.get(\"error\")}. ${url.searchParams.get(\"error_description\")}`\n );\n res.writeHead(500);\n res.end(errorMessage);\n this.logger.getToken.info(errorMessage);\n\n reject(\n new Error(\n `Interactive Browser Authentication Error \"Did not receive token with a valid expiration\"`\n )\n );\n cleanup();\n });\n };\n const app = http.createServer(requestListener);\n\n const listen = app.listen(this.port, this.hostname, () =>\n this.logger.info(`InteractiveBrowserCredential listening on port ${this.port}!`)\n );\n app.on(\"connection\", (socket) => socketToDestroy.push(socket));\n const server = stoppable(app);\n\n this.openAuthCodeUrl(scopes).catch((e) => {\n cleanup();\n reject(e);\n });\n\n function cleanup(): void {\n if (listen) {\n listen.close();\n }\n\n for (const socket of socketToDestroy) {\n socket.destroy();\n }\n\n if (server) {\n server.close();\n server.stop();\n }\n }\n\n const abortSignal = options?.abortSignal;\n if (abortSignal) {\n abortSignal.addEventListener(\"abort\", () => {\n cleanup();\n reject(new Error(\"Aborted\"));\n });\n }\n });\n }\n\n private async openAuthCodeUrl(scopeArray: string[]): Promise<void> {\n const authCodeUrlParameters: msalNode.AuthorizationUrlRequest = {\n scopes: scopeArray,\n redirectUri: this.redirectUri\n };\n\n const response = await this.publicApp!.getAuthCodeUrl(authCodeUrlParameters);\n\n try {\n await interactiveBrowserMockable.open(response, { wait: true });\n } catch (e) {\n throw new CredentialUnavailableError(`Could not open a browser window. Error: ${e.message}`);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"msalOpenBrowser.js","sourceRoot":"","sources":["../../../../src/msal/nodeFlows/msalOpenBrowser.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport * as msalNode from \"@azure/msal-node\";\n\nimport { AccessToken } from \"@azure/core-auth\";\n\nimport { Socket } from \"net\";\nimport http from \"http\";\nimport open from \"open\";\nimport stoppable from \"stoppable\";\n\nimport { credentialLogger, formatError, formatSuccess } from \"../../util/logging\";\nimport { MsalNodeOptions, MsalNode } from \"./nodeCommon\";\nimport { msalToPublic } from \"../utils\";\nimport { CredentialUnavailableError } from \"../../client/errors\";\nimport { CredentialFlowGetTokenOptions } from \"../credentials\";\n\n/**\n * Options that can be passed to configure MSAL to handle authentication through opening a browser window.\n * @internal\n */\nexport interface MSALOpenBrowserOptions extends MsalNodeOptions {\n redirectUri: string;\n loginHint?: string;\n}\n\n/**\n * A call to open(), but mockable\n * @internal\n */\nexport const interactiveBrowserMockable = {\n open\n};\n\n/**\n * This MSAL client sets up a web server to listen for redirect callbacks, then calls to the MSAL's public application's `acquireTokenByDeviceCode` during `doGetToken`\n * to trigger the authentication flow, and then respond based on the values obtained from the redirect callback\n * @internal\n */\nexport class MsalOpenBrowser extends MsalNode {\n private redirectUri: string;\n private port: number;\n private hostname: string;\n private loginHint?: string;\n\n constructor(options: MSALOpenBrowserOptions) {\n super(options);\n this.logger = credentialLogger(\"Node.js MSAL Open Browser\");\n this.redirectUri = options.redirectUri;\n this.loginHint = options.loginHint;\n\n const url = new URL(this.redirectUri);\n this.port = parseInt(url.port);\n if (isNaN(this.port)) {\n this.port = 80;\n }\n this.hostname = url.hostname;\n }\n\n private async acquireTokenByCode(\n request: msalNode.AuthorizationCodeRequest\n ): Promise<msalNode.AuthenticationResult | null> {\n return this.publicApp!.acquireTokenByCode(request);\n }\n\n protected doGetToken(\n scopes: string[],\n options?: CredentialFlowGetTokenOptions\n ): Promise<AccessToken> {\n return new Promise<AccessToken>((resolve, reject) => {\n const socketToDestroy: Socket[] = [];\n\n const requestListener = (req: http.IncomingMessage, res: http.ServerResponse): void => {\n if (!req.url) {\n reject(\n new Error(\n `Interactive Browser Authentication Error \"Did not receive token with a valid expiration\"`\n )\n );\n return;\n }\n let url: URL;\n try {\n url = new URL(req.url, this.redirectUri);\n } catch (e) {\n reject(\n new Error(\n `Interactive Browser Authentication Error \"Did not receive token with a valid expiration\"`\n )\n );\n return;\n }\n const tokenRequest: msalNode.AuthorizationCodeRequest = {\n code: url.searchParams.get(\"code\")!,\n redirectUri: this.redirectUri,\n scopes: scopes,\n authority: options?.authority,\n codeVerifier: this.pkceCodes?.verifier\n };\n\n this.acquireTokenByCode(tokenRequest)\n .then((authResponse) => {\n if (authResponse?.account) {\n this.account = msalToPublic(this.clientId, authResponse.account);\n }\n const successMessage = `Authentication Complete. You can close the browser and return to the application.`;\n if (authResponse && authResponse.expiresOn) {\n const expiresOnTimestamp = authResponse?.expiresOn.valueOf();\n res.writeHead(200);\n res.end(successMessage);\n this.logger.getToken.info(formatSuccess(scopes));\n\n resolve({\n expiresOnTimestamp,\n token: authResponse.accessToken\n });\n } else {\n const errorMessage = formatError(\n scopes,\n `${url.searchParams.get(\"error\")}. ${url.searchParams.get(\"error_description\")}`\n );\n res.writeHead(500);\n res.end(errorMessage);\n this.logger.getToken.info(errorMessage);\n\n reject(\n new Error(\n `Interactive Browser Authentication Error \"Did not receive token with a valid expiration\"`\n )\n );\n }\n cleanup();\n return;\n })\n .catch(() => {\n const errorMessage = formatError(\n scopes,\n `${url.searchParams.get(\"error\")}. ${url.searchParams.get(\"error_description\")}`\n );\n res.writeHead(500);\n res.end(errorMessage);\n this.logger.getToken.info(errorMessage);\n\n reject(\n new Error(\n `Interactive Browser Authentication Error \"Did not receive token with a valid expiration\"`\n )\n );\n cleanup();\n });\n };\n\n const app = http.createServer(requestListener);\n const server = stoppable(app);\n\n const listen = app.listen(this.port, this.hostname, () =>\n this.logger.info(`InteractiveBrowserCredential listening on port ${this.port}!`)\n );\n\n function cleanup(): void {\n if (listen) {\n listen.close();\n }\n\n for (const socket of socketToDestroy) {\n socket.destroy();\n }\n\n if (server) {\n server.close();\n server.stop();\n }\n }\n\n app.on(\"connection\", (socket) => socketToDestroy.push(socket));\n\n app.on(\"listening\", () => {\n const openPromise = this.openAuthCodeUrl(scopes, options);\n\n const abortSignal = options?.abortSignal;\n if (abortSignal) {\n abortSignal.addEventListener(\"abort\", () => {\n cleanup();\n reject(new Error(\"Aborted\"));\n });\n }\n\n openPromise.then().catch((e) => {\n cleanup();\n reject(e);\n });\n });\n });\n }\n\n private pkceCodes?: {\n verifier: string;\n challenge: string;\n };\n\n private async openAuthCodeUrl(\n scopeArray: string[],\n options?: CredentialFlowGetTokenOptions\n ): Promise<void> {\n // Initialize CryptoProvider instance\n const cryptoProvider = new msalNode.CryptoProvider();\n // Generate PKCE Codes before starting the authorization flow\n this.pkceCodes = await cryptoProvider.generatePkceCodes();\n\n const authCodeUrlParameters: msalNode.AuthorizationUrlRequest = {\n scopes: scopeArray,\n redirectUri: this.redirectUri,\n authority: options?.authority,\n loginHint: this.loginHint,\n codeChallenge: this.pkceCodes.challenge,\n codeChallengeMethod: \"S256\" // Use SHA256 Algorithm\n };\n\n const response = await this.publicApp!.getAuthCodeUrl(authCodeUrlParameters);\n\n try {\n await interactiveBrowserMockable.open(response, { wait: true });\n } catch (e) {\n throw new CredentialUnavailableError(`Could not open a browser window. Error: ${e.message}`);\n }\n }\n}\n"]}
@@ -1,6 +1,5 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
- import { __awaiter } from "tslib";
4
3
  import { MsalNode } from "./nodeCommon";
5
4
  /**
6
5
  * MSAL username and password client. Calls to the MSAL's public application's `acquireTokenByUsernamePassword` during `doGetToken`.
@@ -12,22 +11,21 @@ export class MsalUsernamePassword extends MsalNode {
12
11
  this.username = options.username;
13
12
  this.password = options.password;
14
13
  }
15
- doGetToken(scopes, options) {
16
- return __awaiter(this, void 0, void 0, function* () {
17
- try {
18
- const requestOptions = {
19
- scopes,
20
- username: this.username,
21
- password: this.password,
22
- correlationId: options === null || options === void 0 ? void 0 : options.correlationId
23
- };
24
- const result = yield this.publicApp.acquireTokenByUsernamePassword(requestOptions);
25
- return this.handleResult(scopes, this.clientId, result || undefined);
26
- }
27
- catch (error) {
28
- throw this.handleError(scopes, error, options);
29
- }
30
- });
14
+ async doGetToken(scopes, options) {
15
+ try {
16
+ const requestOptions = {
17
+ scopes,
18
+ username: this.username,
19
+ password: this.password,
20
+ correlationId: options === null || options === void 0 ? void 0 : options.correlationId,
21
+ authority: options === null || options === void 0 ? void 0 : options.authority
22
+ };
23
+ const result = await this.publicApp.acquireTokenByUsernamePassword(requestOptions);
24
+ return this.handleResult(scopes, this.clientId, result || undefined);
25
+ }
26
+ catch (error) {
27
+ throw this.handleError(scopes, error, options);
28
+ }
31
29
  }
32
30
  }
33
31
  //# sourceMappingURL=msalUsernamePassword.js.map