@azure/identity 1.2.0-beta.2 → 1.2.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.
Potentially problematic release.
This version of @azure/identity might be problematic. Click here for more details.
- package/CHANGELOG.md +24 -2
- package/README.md +75 -55
- package/dist/index.js +533 -396
- package/dist/index.js.map +1 -1
- package/dist-esm/src/client/msalClient.js +138 -0
- package/dist-esm/src/client/msalClient.js.map +1 -0
- package/dist-esm/src/credentials/authorizationCodeCredential.browser.js +2 -2
- package/dist-esm/src/credentials/authorizationCodeCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/authorizationCodeCredential.js +3 -1
- package/dist-esm/src/credentials/authorizationCodeCredential.js.map +1 -1
- package/dist-esm/src/credentials/azureCliCredential.browser.js +2 -2
- package/dist-esm/src/credentials/azureCliCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/azureCliCredential.js +5 -5
- package/dist-esm/src/credentials/azureCliCredential.js.map +1 -1
- package/dist-esm/src/credentials/chainedTokenCredential.js +2 -2
- package/dist-esm/src/credentials/chainedTokenCredential.js.map +1 -1
- package/dist-esm/src/credentials/clientCertificateCredential.browser.js +2 -2
- package/dist-esm/src/credentials/clientCertificateCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/clientCertificateCredential.js +5 -3
- package/dist-esm/src/credentials/clientCertificateCredential.js.map +1 -1
- package/dist-esm/src/credentials/clientCertificateCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/clientSecretCredential.js +2 -2
- package/dist-esm/src/credentials/clientSecretCredential.js.map +1 -1
- package/dist-esm/src/credentials/deviceCodeCredential.browser.js +2 -2
- package/dist-esm/src/credentials/deviceCodeCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/deviceCodeCredential.js +53 -47
- package/dist-esm/src/credentials/deviceCodeCredential.js.map +1 -1
- package/dist-esm/src/credentials/environmentCredential.browser.js +2 -2
- package/dist-esm/src/credentials/environmentCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/environmentCredential.js +6 -2
- package/dist-esm/src/credentials/environmentCredential.js.map +1 -1
- package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js +7 -5
- package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/interactiveBrowserCredential.js +30 -69
- package/dist-esm/src/credentials/interactiveBrowserCredential.js.map +1 -1
- package/dist-esm/src/credentials/interactiveBrowserCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js +44 -0
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js +74 -0
- package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js +41 -0
- package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/constants.js +8 -0
- package/dist-esm/src/credentials/managedIdentityCredential/constants.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js +59 -0
- package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js +109 -0
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js.map +1 -0
- package/dist-esm/src/credentials/{managedIdentityCredential.browser.js → managedIdentityCredential/index.browser.js} +4 -4
- package/dist-esm/src/credentials/managedIdentityCredential/index.browser.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/index.js +165 -0
- package/dist-esm/src/credentials/managedIdentityCredential/index.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/models.js +3 -0
- package/dist-esm/src/credentials/managedIdentityCredential/models.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/utils.js +28 -0
- package/dist-esm/src/credentials/managedIdentityCredential/utils.js.map +1 -0
- package/dist-esm/src/credentials/usernamePasswordCredential.js +3 -1
- package/dist-esm/src/credentials/usernamePasswordCredential.js.map +1 -1
- package/dist-esm/src/credentials/visualStudioCodeCredential.browser.js +2 -2
- package/dist-esm/src/credentials/visualStudioCodeCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/visualStudioCodeCredential.js +19 -8
- package/dist-esm/src/credentials/visualStudioCodeCredential.js.map +1 -1
- package/dist-esm/src/index.js.map +1 -1
- package/dist-esm/src/util/checkTenantId.js +11 -0
- package/dist-esm/src/util/checkTenantId.js.map +1 -0
- package/dist-esm/src/util/logging.js +7 -3
- package/dist-esm/src/util/logging.js.map +1 -1
- package/package.json +7 -5
- package/types/identity.d.ts +9 -33
- package/dist-esm/src/credentials/managedIdentityCredential.browser.js.map +0 -1
- package/dist-esm/src/credentials/managedIdentityCredential.js +0 -376
- package/dist-esm/src/credentials/managedIdentityCredential.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imdsMsi.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/imdsMsi.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, GetTokenOptions, RequestPrepareOptions, RestError } from \"@azure/core-http\";\nimport { CanonicalCode } from \"@opentelemetry/api\";\nimport { IdentityClient } from \"../../client/identityClient\";\nimport { credentialLogger } from \"../../util/logging\";\nimport { createSpan } from \"../../util/tracing\";\nimport { imdsApiVersion, imdsEndpoint } from \"./constants\";\nimport { MSI } from \"./models\";\nimport { msiGenericGetToken } from \"./utils\";\n\nconst logger = credentialLogger(\"ManagedIdentityCredential - IMDS\");\n\nfunction expiresInParser(requestBody: any): number {\n if (requestBody.expires_on) {\n // Use the expires_on timestamp if it's available\n const expires = +requestBody.expires_on * 1000;\n logger.info(`IMDS using expires_on: ${expires} (original value: ${requestBody.expires_on})`);\n return expires;\n } else {\n // If these aren't possible, use expires_in and calculate a timestamp\n const expires = Date.now() + requestBody.expires_in * 1000;\n logger.info(`IMDS using expires_in: ${expires} (original value: ${requestBody.expires_in})`);\n return expires;\n }\n}\n\nfunction prepareRequestOptions(resource?: string, clientId?: string): RequestPrepareOptions {\n const queryParameters: any = {\n resource,\n \"api-version\": imdsApiVersion\n };\n\n if (clientId) {\n queryParameters.client_id = clientId;\n }\n\n return {\n url: imdsEndpoint,\n method: \"GET\",\n queryParameters,\n headers: {\n Accept: \"application/json\",\n Metadata: true\n }\n };\n}\n\nexport const imdsMsi: MSI = {\n async isAvailable(\n identityClient: IdentityClient,\n resource: string,\n clientId?: string,\n getTokenOptions?: GetTokenOptions\n ): Promise<boolean> {\n const { span, options } = createSpan(\n \"ManagedIdentityCredential-pingImdsEndpoint\",\n getTokenOptions\n );\n\n const request = prepareRequestOptions(resource, clientId);\n\n // This will always be populated, but let's make TypeScript happy\n if (request.headers) {\n // Remove the Metadata header to invoke a request error from\n // IMDS endpoint\n delete request.headers.Metadata;\n }\n\n request.spanOptions = options.tracingOptions && options.tracingOptions.spanOptions;\n\n try {\n // Create a request with a timeout since we expect that\n // not having a \"Metadata\" header should cause an error to be\n // returned quickly from the endpoint, proving its availability.\n const webResource = identityClient.createWebResource(request);\n webResource.timeout = (options.requestOptions && options.requestOptions.timeout) || 500;\n\n try {\n logger.info(`Pinging IMDS endpoint`);\n await identityClient.sendRequest(webResource);\n } catch (err) {\n if (\n (err instanceof RestError && err.code === RestError.REQUEST_SEND_ERROR) ||\n err.name === \"AbortError\" ||\n err.code === \"ECONNREFUSED\" || // connection refused\n err.code === \"EHOSTDOWN\" // host is down\n ) {\n // If the request failed, or NodeJS was unable to establish a connection,\n // or the host was down, we'll assume the IMDS endpoint isn't available.\n logger.info(`IMDS endpoint unavailable`);\n span.setStatus({\n code: CanonicalCode.UNAVAILABLE,\n message: err.message\n });\n\n // IMDS MSI unavailable.\n return false;\n }\n }\n\n // If we received any response, the endpoint is available\n logger.info(`IMDS endpoint is available`);\n\n // IMDS MSI available!\n return true;\n } catch (err) {\n // createWebResource failed.\n // This error should bubble up to the user.\n logger.info(`Error when creating the WebResource for the IMDS endpoint: ${err.message}`);\n span.setStatus({\n code: CanonicalCode.UNKNOWN,\n message: err.message\n });\n throw err;\n } finally {\n span.end();\n }\n },\n async getToken(\n identityClient: IdentityClient,\n resource: string,\n clientId?: string,\n getTokenOptions: GetTokenOptions = {}\n ): Promise<AccessToken | null> {\n logger.info(\n `Using the IMDS endpoint coming form the environment variable MSI_ENDPOINT=${process.env.MSI_ENDPOINT}, and using the cloud shell to proceed with the authentication.`\n );\n\n return msiGenericGetToken(\n identityClient,\n prepareRequestOptions(resource, clientId),\n expiresInParser,\n getTokenOptions\n );\n }\n};\n"]}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
// Copyright (c) Microsoft Corporation.
|
|
2
2
|
// Licensed under the MIT license.
|
|
3
3
|
import { __awaiter } from "tslib";
|
|
4
|
-
import { credentialLogger, formatError } from "
|
|
4
|
+
import { credentialLogger, formatError } from "../../util/logging";
|
|
5
5
|
const BrowserNotSupportedError = new Error("ManagedIdentityCredential is not supported in the browser.");
|
|
6
6
|
const logger = credentialLogger("ManagedIdentityCredential");
|
|
7
7
|
export class ManagedIdentityCredential {
|
|
8
8
|
constructor() {
|
|
9
|
-
logger.info(formatError(BrowserNotSupportedError));
|
|
9
|
+
logger.info(formatError("", BrowserNotSupportedError));
|
|
10
10
|
throw BrowserNotSupportedError;
|
|
11
11
|
}
|
|
12
12
|
getToken() {
|
|
13
13
|
return __awaiter(this, void 0, void 0, function* () {
|
|
14
|
-
logger.getToken.info(formatError(BrowserNotSupportedError));
|
|
14
|
+
logger.getToken.info(formatError("", BrowserNotSupportedError));
|
|
15
15
|
throw BrowserNotSupportedError;
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
//# sourceMappingURL=
|
|
19
|
+
//# sourceMappingURL=index.browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.browser.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/index.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAIlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEnE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,4DAA4D,CAC7D,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,2BAA2B,CAAC,CAAC;AAE7D,MAAM,OAAO,yBAAyB;IAGpC;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEY,QAAQ;;YACnB,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;YAChE,MAAM,wBAAwB,CAAC;QACjC,CAAC;KAAA;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-http\";\nimport { TokenCredentialOptions } from \"../../client/identityClient\";\nimport { credentialLogger, formatError } from \"../../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\n \"ManagedIdentityCredential is not supported in the browser.\"\n);\nconst logger = credentialLogger(\"ManagedIdentityCredential\");\n\nexport class ManagedIdentityCredential implements TokenCredential {\n constructor(clientId: string, options?: TokenCredentialOptions);\n constructor(options?: TokenCredentialOptions);\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public async getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
import { __awaiter } from "tslib";
|
|
4
|
+
import { IdentityClient } from "../../client/identityClient";
|
|
5
|
+
import { createSpan } from "../../util/tracing";
|
|
6
|
+
import { AuthenticationErrorName, AuthenticationError, CredentialUnavailable } from "../../client/errors";
|
|
7
|
+
import { CanonicalCode } from "@opentelemetry/api";
|
|
8
|
+
import { credentialLogger, formatSuccess, formatError } from "../../util/logging";
|
|
9
|
+
import { mapScopesToResource } from "./utils";
|
|
10
|
+
import { cloudShellMsi } from "./cloudShellMsi";
|
|
11
|
+
import { imdsMsi } from "./imdsMsi";
|
|
12
|
+
import { appServiceMsi2017 } from "./appServiceMsi2017";
|
|
13
|
+
import { arcMsi } from "./arcMsi";
|
|
14
|
+
const logger = credentialLogger("ManagedIdentityCredential");
|
|
15
|
+
/**
|
|
16
|
+
* Attempts authentication using a managed identity that has been assigned
|
|
17
|
+
* to the deployment environment. This authentication type works in Azure VMs,
|
|
18
|
+
* App Service and Azure Functions applications, and inside of Azure Cloud Shell.
|
|
19
|
+
*
|
|
20
|
+
* More information about configuring managed identities can be found here:
|
|
21
|
+
*
|
|
22
|
+
* https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview
|
|
23
|
+
*/
|
|
24
|
+
export class ManagedIdentityCredential {
|
|
25
|
+
/**
|
|
26
|
+
* @internal
|
|
27
|
+
* @ignore
|
|
28
|
+
*/
|
|
29
|
+
constructor(clientIdOrOptions, options) {
|
|
30
|
+
this.isEndpointUnavailable = null;
|
|
31
|
+
if (typeof clientIdOrOptions === "string") {
|
|
32
|
+
// clientId, options constructor
|
|
33
|
+
this.clientId = clientIdOrOptions;
|
|
34
|
+
this.identityClient = new IdentityClient(options);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// options only constructor
|
|
38
|
+
this.identityClient = new IdentityClient(clientIdOrOptions);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
cachedAvailableMSI(resource, clientId, getTokenOptions) {
|
|
42
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
if (this.cachedMSI) {
|
|
44
|
+
return this.cachedMSI;
|
|
45
|
+
}
|
|
46
|
+
// "fabricMsi" can't be added yet because our HTTPs pipeline doesn't allow skipping the SSL verification step,
|
|
47
|
+
// which is necessary since Service Fabric only provides self-signed certificates on their Identity Endpoint.
|
|
48
|
+
const MSIs = [appServiceMsi2017, cloudShellMsi, arcMsi, imdsMsi];
|
|
49
|
+
for (const msi of MSIs) {
|
|
50
|
+
if (yield msi.isAvailable(this.identityClient, resource, clientId, getTokenOptions)) {
|
|
51
|
+
this.cachedMSI = msi;
|
|
52
|
+
return msi;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
throw new CredentialUnavailable("ManagedIdentityCredential - No MSI credential available");
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
authenticateManagedIdentity(scopes, clientId, getTokenOptions) {
|
|
59
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
+
const resource = mapScopesToResource(scopes);
|
|
61
|
+
const { span, options } = createSpan("ManagedIdentityCredential-authenticateManagedIdentity", getTokenOptions);
|
|
62
|
+
try {
|
|
63
|
+
// Determining the available MSI, and avoiding checking for other MSIs while the program is running.
|
|
64
|
+
const availableMSI = yield this.cachedAvailableMSI(resource, clientId, options);
|
|
65
|
+
return availableMSI.getToken(this.identityClient, resource, clientId, options);
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
const code = err.name === AuthenticationErrorName
|
|
69
|
+
? CanonicalCode.UNAUTHENTICATED
|
|
70
|
+
: CanonicalCode.UNKNOWN;
|
|
71
|
+
span.setStatus({
|
|
72
|
+
code,
|
|
73
|
+
message: err.message
|
|
74
|
+
});
|
|
75
|
+
throw err;
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
span.end();
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Authenticates with Azure Active Directory and returns an access token if
|
|
84
|
+
* successful. If authentication cannot be performed at this time, this method may
|
|
85
|
+
* return null. If an error occurs during authentication, an {@link AuthenticationError}
|
|
86
|
+
* containing failure details will be thrown.
|
|
87
|
+
*
|
|
88
|
+
* @param scopes The list of scopes for which the token will have access.
|
|
89
|
+
* @param options The options used to configure any requests this
|
|
90
|
+
* TokenCredential implementation might make.
|
|
91
|
+
*/
|
|
92
|
+
getToken(scopes, options) {
|
|
93
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
94
|
+
let result = null;
|
|
95
|
+
const { span, options: newOptions } = createSpan("ManagedIdentityCredential-getToken", options);
|
|
96
|
+
try {
|
|
97
|
+
// isEndpointAvailable can be true, false, or null,
|
|
98
|
+
// If it's null, it means we don't yet know whether
|
|
99
|
+
// the endpoint is available and need to check for it.
|
|
100
|
+
if (this.isEndpointUnavailable !== true) {
|
|
101
|
+
result = yield this.authenticateManagedIdentity(scopes, this.clientId, newOptions);
|
|
102
|
+
if (result === null) {
|
|
103
|
+
// If authenticateManagedIdentity returns null,
|
|
104
|
+
// it means no MSI endpoints are available.
|
|
105
|
+
// If so, we avoid trying to reach to them in future requests.
|
|
106
|
+
this.isEndpointUnavailable = true;
|
|
107
|
+
// It also means that the endpoint answered with either 200 or 201 (see the sendTokenRequest method),
|
|
108
|
+
// yet we had no access token. For this reason, we'll throw once with a specific message:
|
|
109
|
+
const error = new CredentialUnavailable("The managed identity endpoint was reached, yet no tokens were received.");
|
|
110
|
+
logger.getToken.info(formatError(scopes, error));
|
|
111
|
+
throw error;
|
|
112
|
+
}
|
|
113
|
+
// Since `authenticateManagedIdentity` didn't throw, and the result was not null,
|
|
114
|
+
// We will assume that this endpoint is reachable from this point forward,
|
|
115
|
+
// and avoid pinging again to it.
|
|
116
|
+
this.isEndpointUnavailable = false;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// We've previously determined that the endpoint was unavailable,
|
|
120
|
+
// either because it was unreachable or permanently unable to authenticate.
|
|
121
|
+
const error = new CredentialUnavailable("The managed identity endpoint is not currently available");
|
|
122
|
+
logger.getToken.info(formatError(scopes, error));
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
logger.getToken.info(formatSuccess(scopes));
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
// CredentialUnavailable errors are expected to reach here.
|
|
130
|
+
// We intend them to bubble up, so that DefaultAzureCredential can catch them.
|
|
131
|
+
if (err instanceof CredentialUnavailable) {
|
|
132
|
+
throw err;
|
|
133
|
+
}
|
|
134
|
+
// Expected errors to reach this point:
|
|
135
|
+
// - Errors coming from a method unexpectedly breaking.
|
|
136
|
+
// - When identityClient.sendTokenRequest throws, in which case
|
|
137
|
+
// if the status code was 400, it means that the endpoint is working,
|
|
138
|
+
// but no identity is available.
|
|
139
|
+
span.setStatus({
|
|
140
|
+
code: CanonicalCode.UNKNOWN,
|
|
141
|
+
message: err.message
|
|
142
|
+
});
|
|
143
|
+
if (err.code === "ENETUNREACH") {
|
|
144
|
+
const error = new CredentialUnavailable("ManagedIdentityCredential is unavailable. No managed identity endpoint found.");
|
|
145
|
+
logger.getToken.info(formatError(scopes, error));
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
// If err.statusCode has a value of 400, it comes from sendTokenRequest,
|
|
149
|
+
// and it means that the endpoint is working, but that no identity is available.
|
|
150
|
+
if (err.statusCode === 400) {
|
|
151
|
+
throw new CredentialUnavailable("The managed identity endpoint is indicating there's no available identity");
|
|
152
|
+
}
|
|
153
|
+
throw new AuthenticationError(err.statusCode, {
|
|
154
|
+
error: "ManagedIdentityCredential authentication failed.",
|
|
155
|
+
error_description: err.message
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
// Finally is always called, both if we return and if we throw in the above try/catch.
|
|
160
|
+
span.end();
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, GetTokenOptions, TokenCredential } from \"@azure/core-http\";\nimport { IdentityClient, TokenCredentialOptions } from \"../../client/identityClient\";\nimport { createSpan } from \"../../util/tracing\";\nimport {\n AuthenticationErrorName,\n AuthenticationError,\n CredentialUnavailable\n} from \"../../client/errors\";\nimport { CanonicalCode } from \"@opentelemetry/api\";\nimport { credentialLogger, formatSuccess, formatError } from \"../../util/logging\";\nimport { mapScopesToResource } from \"./utils\";\nimport { cloudShellMsi } from \"./cloudShellMsi\";\nimport { imdsMsi } from \"./imdsMsi\";\nimport { MSI } from \"./models\";\nimport { appServiceMsi2017 } from \"./appServiceMsi2017\";\nimport { arcMsi } from \"./arcMsi\";\n\nconst logger = credentialLogger(\"ManagedIdentityCredential\");\n\n/**\n * Attempts authentication using a managed identity that has been assigned\n * to the deployment environment. This authentication type works in Azure VMs,\n * App Service and Azure Functions applications, and inside of Azure Cloud Shell.\n *\n * More information about configuring managed identities can be found here:\n *\n * https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview\n */\nexport class ManagedIdentityCredential implements TokenCredential {\n private identityClient: IdentityClient;\n private clientId: string | undefined;\n private isEndpointUnavailable: boolean | null = null;\n\n /**\n * Creates an instance of ManagedIdentityCredential with the client ID of a\n * user-assigned identity.\n *\n * @param clientId The client ID of the user-assigned identity.\n * @param options Options for configuring the client which makes the access token request.\n */\n constructor(clientId: string, options?: TokenCredentialOptions);\n /**\n * Creates an instance of ManagedIdentityCredential\n *\n * @param options Options for configuring the client which makes the access token request.\n */\n constructor(options?: TokenCredentialOptions);\n /**\n * @internal\n * @ignore\n */\n constructor(\n clientIdOrOptions: string | TokenCredentialOptions | undefined,\n options?: TokenCredentialOptions\n ) {\n if (typeof clientIdOrOptions === \"string\") {\n // clientId, options constructor\n this.clientId = clientIdOrOptions;\n this.identityClient = new IdentityClient(options);\n } else {\n // options only constructor\n this.identityClient = new IdentityClient(clientIdOrOptions);\n }\n }\n\n private cachedMSI: MSI | undefined;\n\n private async cachedAvailableMSI(\n resource: string,\n clientId?: string,\n getTokenOptions?: GetTokenOptions\n ): Promise<MSI> {\n if (this.cachedMSI) {\n return this.cachedMSI;\n }\n\n // \"fabricMsi\" can't be added yet because our HTTPs pipeline doesn't allow skipping the SSL verification step,\n // which is necessary since Service Fabric only provides self-signed certificates on their Identity Endpoint.\n const MSIs = [appServiceMsi2017, cloudShellMsi, arcMsi, imdsMsi];\n\n for (const msi of MSIs) {\n if (await msi.isAvailable(this.identityClient, resource, clientId, getTokenOptions)) {\n this.cachedMSI = msi;\n return msi;\n }\n }\n\n throw new CredentialUnavailable(\"ManagedIdentityCredential - No MSI credential available\");\n }\n\n private async authenticateManagedIdentity(\n scopes: string | string[],\n clientId?: string,\n getTokenOptions?: GetTokenOptions\n ): Promise<AccessToken | null> {\n const resource = mapScopesToResource(scopes);\n const { span, options } = createSpan(\n \"ManagedIdentityCredential-authenticateManagedIdentity\",\n getTokenOptions\n );\n\n try {\n // Determining the available MSI, and avoiding checking for other MSIs while the program is running.\n const availableMSI = await this.cachedAvailableMSI(resource, clientId, options);\n\n return availableMSI.getToken(this.identityClient, resource, clientId, options);\n } catch (err) {\n const code =\n err.name === AuthenticationErrorName\n ? CanonicalCode.UNAUTHENTICATED\n : CanonicalCode.UNKNOWN;\n span.setStatus({\n code,\n message: err.message\n });\n throw err;\n } finally {\n span.end();\n }\n }\n\n /**\n * Authenticates with Azure Active Directory and returns an access token if\n * successful. If authentication cannot be performed at this time, this method may\n * return null. If an error occurs during authentication, an {@link AuthenticationError}\n * containing failure details will be thrown.\n *\n * @param scopes The list of scopes for which the token will have access.\n * @param options The options used to configure any requests this\n * TokenCredential implementation might make.\n */\n public async getToken(\n scopes: string | string[],\n options?: GetTokenOptions\n ): Promise<AccessToken | null> {\n let result: AccessToken | null = null;\n\n const { span, options: newOptions } = createSpan(\"ManagedIdentityCredential-getToken\", options);\n\n try {\n // isEndpointAvailable can be true, false, or null,\n // If it's null, it means we don't yet know whether\n // the endpoint is available and need to check for it.\n if (this.isEndpointUnavailable !== true) {\n result = await this.authenticateManagedIdentity(scopes, this.clientId, newOptions);\n\n if (result === null) {\n // If authenticateManagedIdentity returns null,\n // it means no MSI endpoints are available.\n // If so, we avoid trying to reach to them in future requests.\n this.isEndpointUnavailable = true;\n\n // It also means that the endpoint answered with either 200 or 201 (see the sendTokenRequest method),\n // yet we had no access token. For this reason, we'll throw once with a specific message:\n const error = new CredentialUnavailable(\n \"The managed identity endpoint was reached, yet no tokens were received.\"\n );\n logger.getToken.info(formatError(scopes, error));\n throw error;\n }\n\n // Since `authenticateManagedIdentity` didn't throw, and the result was not null,\n // We will assume that this endpoint is reachable from this point forward,\n // and avoid pinging again to it.\n this.isEndpointUnavailable = false;\n } else {\n // We've previously determined that the endpoint was unavailable,\n // either because it was unreachable or permanently unable to authenticate.\n const error = new CredentialUnavailable(\n \"The managed identity endpoint is not currently available\"\n );\n logger.getToken.info(formatError(scopes, error));\n throw error;\n }\n\n logger.getToken.info(formatSuccess(scopes));\n return result;\n } catch (err) {\n // CredentialUnavailable errors are expected to reach here.\n // We intend them to bubble up, so that DefaultAzureCredential can catch them.\n if (err instanceof CredentialUnavailable) {\n throw err;\n }\n\n // Expected errors to reach this point:\n // - Errors coming from a method unexpectedly breaking.\n // - When identityClient.sendTokenRequest throws, in which case\n // if the status code was 400, it means that the endpoint is working,\n // but no identity is available.\n\n span.setStatus({\n code: CanonicalCode.UNKNOWN,\n message: err.message\n });\n\n if (err.code === \"ENETUNREACH\") {\n const error = new CredentialUnavailable(\n \"ManagedIdentityCredential is unavailable. No managed identity endpoint found.\"\n );\n\n logger.getToken.info(formatError(scopes, error));\n throw error;\n }\n\n // If err.statusCode has a value of 400, it comes from sendTokenRequest,\n // and it means that the endpoint is working, but that no identity is available.\n if (err.statusCode === 400) {\n throw new CredentialUnavailable(\n \"The managed identity endpoint is indicating there's no available identity\"\n );\n }\n\n throw new AuthenticationError(err.statusCode, {\n error: \"ManagedIdentityCredential authentication failed.\",\n error_description: err.message\n });\n } finally {\n // Finally is always called, both if we return and if we throw in the above try/catch.\n span.end();\n }\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/models.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, GetTokenOptions } from \"@azure/core-http\";\nimport { IdentityClient } from \"../../client/identityClient\";\n\nexport type MSIExpiresInParser = (requestBody: any) => number;\n\nexport interface MSI {\n isAvailable(\n identityClient?: IdentityClient,\n resource?: string,\n clientId?: string,\n getTokenOptions?: GetTokenOptions\n ): Promise<boolean>;\n getToken(\n identityClient: IdentityClient,\n resource: string,\n clientId?: string,\n getTokenOptions?: GetTokenOptions\n ): Promise<AccessToken | null>;\n}\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
import { __awaiter } from "tslib";
|
|
4
|
+
import { DefaultScopeSuffix } from "./constants";
|
|
5
|
+
export function mapScopesToResource(scopes) {
|
|
6
|
+
let scope = "";
|
|
7
|
+
if (Array.isArray(scopes)) {
|
|
8
|
+
if (scopes.length !== 1) {
|
|
9
|
+
throw new Error("To convert to a resource string the specified array must be exactly length 1");
|
|
10
|
+
}
|
|
11
|
+
scope = scopes[0];
|
|
12
|
+
}
|
|
13
|
+
else if (typeof scopes === "string") {
|
|
14
|
+
scope = scopes;
|
|
15
|
+
}
|
|
16
|
+
if (!scope.endsWith(DefaultScopeSuffix)) {
|
|
17
|
+
return scope;
|
|
18
|
+
}
|
|
19
|
+
return scope.substr(0, scope.lastIndexOf(DefaultScopeSuffix));
|
|
20
|
+
}
|
|
21
|
+
export function msiGenericGetToken(identityClient, requestOptions, expiresInParser, getTokenOptions = {}) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
const webResource = identityClient.createWebResource(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal, spanOptions: getTokenOptions.tracingOptions && getTokenOptions.tracingOptions.spanOptions }, requestOptions));
|
|
24
|
+
const tokenResponse = yield identityClient.sendTokenRequest(webResource, expiresInParser);
|
|
25
|
+
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/utils.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAIlC,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGjD,MAAM,UAAU,mBAAmB,CAAC,MAAyB;IAC3D,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACzB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;YACvB,MAAM,IAAI,KAAK,CACb,8EAA8E,CAC/E,CAAC;SACH;QAED,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;KACnB;SAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;QACrC,KAAK,GAAG,MAAM,CAAC;KAChB;IAED,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE;QACvC,OAAO,KAAK,CAAC;KACd;IAED,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAgB,kBAAkB,CACtC,cAA8B,EAC9B,cAAqC,EACrC,eAA+C,EAC/C,kBAAmC,EAAE;;QAErC,MAAM,WAAW,GAAG,cAAc,CAAC,iBAAiB,iBAClD,0BAA0B,EAAE,IAAI,EAChC,qBAAqB,EAAE,SAAS,EAChC,WAAW,EAAE,eAAe,CAAC,WAAW,EACxC,WAAW,EAAE,eAAe,CAAC,cAAc,IAAI,eAAe,CAAC,cAAc,CAAC,WAAW,IACtF,cAAc,EACjB,CAAC;QAEH,MAAM,aAAa,GAAG,MAAM,cAAc,CAAC,gBAAgB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;QAE1F,OAAO,CAAC,aAAa,IAAI,aAAa,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC;IAC9D,CAAC;CAAA","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, GetTokenOptions, RequestPrepareOptions } from \"@azure/core-http\";\nimport { IdentityClient } from \"../../client/identityClient\";\nimport { DefaultScopeSuffix } from \"./constants\";\nimport { MSIExpiresInParser } from \"./models\";\n\nexport function mapScopesToResource(scopes: string | string[]): string {\n let scope = \"\";\n if (Array.isArray(scopes)) {\n if (scopes.length !== 1) {\n throw new Error(\n \"To convert to a resource string the specified array must be exactly length 1\"\n );\n }\n\n scope = scopes[0];\n } else if (typeof scopes === \"string\") {\n scope = scopes;\n }\n\n if (!scope.endsWith(DefaultScopeSuffix)) {\n return scope;\n }\n\n return scope.substr(0, scope.lastIndexOf(DefaultScopeSuffix));\n}\n\nexport async function msiGenericGetToken(\n identityClient: IdentityClient,\n requestOptions: RequestPrepareOptions,\n expiresInParser: MSIExpiresInParser | undefined,\n getTokenOptions: GetTokenOptions = {}\n): Promise<AccessToken | null> {\n const webResource = identityClient.createWebResource({\n disableJsonStringifyOnBody: true,\n deserializationMapper: undefined,\n abortSignal: getTokenOptions.abortSignal,\n spanOptions: getTokenOptions.tracingOptions && getTokenOptions.tracingOptions.spanOptions,\n ...requestOptions\n });\n\n const tokenResponse = await identityClient.sendTokenRequest(webResource, expiresInParser);\n\n return (tokenResponse && tokenResponse.accessToken) || null;\n}\n"]}
|
|
@@ -8,6 +8,7 @@ import { AuthenticationErrorName } from "../client/errors";
|
|
|
8
8
|
import { CanonicalCode } from "@opentelemetry/api";
|
|
9
9
|
import { credentialLogger, formatSuccess, formatError } from "../util/logging";
|
|
10
10
|
import { getIdentityTokenEndpointSuffix } from "../util/identityTokenEndpoint";
|
|
11
|
+
import { checkTenantId } from "../util/checkTenantId";
|
|
11
12
|
const logger = credentialLogger("UsernamePasswordCredential");
|
|
12
13
|
/**
|
|
13
14
|
* Enables authentication to Azure Active Directory with a user's
|
|
@@ -28,6 +29,7 @@ export class UsernamePasswordCredential {
|
|
|
28
29
|
* @param options Options for configuring the client which makes the authentication request.
|
|
29
30
|
*/
|
|
30
31
|
constructor(tenantIdOrName, clientId, username, password, options) {
|
|
32
|
+
checkTenantId(logger, tenantIdOrName);
|
|
31
33
|
this.identityClient = new IdentityClient(options);
|
|
32
34
|
this.tenantId = tenantIdOrName;
|
|
33
35
|
this.clientId = clientId;
|
|
@@ -81,7 +83,7 @@ export class UsernamePasswordCredential {
|
|
|
81
83
|
code,
|
|
82
84
|
message: err.message
|
|
83
85
|
});
|
|
84
|
-
logger.getToken.info(formatError(err));
|
|
86
|
+
logger.getToken.info(formatError(scopes, err));
|
|
85
87
|
throw err;
|
|
86
88
|
}
|
|
87
89
|
finally {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usernamePasswordCredential.js","sourceRoot":"","sources":["../../../src/credentials/usernamePasswordCredential.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAElC,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,OAAO,EAA0B,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EAAE,8BAA8B,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"usernamePasswordCredential.js","sourceRoot":"","sources":["../../../src/credentials/usernamePasswordCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport qs from \"qs\";\nimport { TokenCredential, GetTokenOptions, AccessToken } from \"@azure/core-http\";\nimport { TokenCredentialOptions, IdentityClient } from \"../client/identityClient\";\nimport { createSpan } from \"../util/tracing\";\nimport { AuthenticationErrorName } from \"../client/errors\";\nimport { CanonicalCode } from \"@opentelemetry/api\";\nimport { credentialLogger, formatSuccess, formatError } from \"../util/logging\";\nimport { getIdentityTokenEndpointSuffix } from \"../util/identityTokenEndpoint\";\nimport { checkTenantId } from \"../util/checkTenantId\";\n\nconst logger = credentialLogger(\"UsernamePasswordCredential\");\n\n/**\n * Enables authentication to Azure Active Directory with a user's\n * username and password. This credential requires a high degree of\n * trust so you should only use it when other, more secure credential\n * types can't be used.\n */\nexport class UsernamePasswordCredential implements TokenCredential {\n private identityClient: IdentityClient;\n private tenantId: string;\n private clientId: string;\n private username: string;\n private password: string;\n\n /**\n * Creates an instance of the UsernamePasswordCredential with the details\n * needed to authenticate against Azure Active Directory with a username\n * and password.\n *\n * @param tenantIdOrName The Azure Active Directory tenant (directory) ID or name.\n * @param clientId The client (application) ID of an App Registration in the tenant.\n * @param username The user account's e-mail address (user name).\n * @param password The user account's account password\n * @param options Options for configuring the client which makes the authentication request.\n */\n constructor(\n tenantIdOrName: string,\n clientId: string,\n username: string,\n password: string,\n options?: TokenCredentialOptions\n ) {\n checkTenantId(logger, tenantIdOrName);\n\n this.identityClient = new IdentityClient(options);\n this.tenantId = tenantIdOrName;\n this.clientId = clientId;\n this.username = username;\n this.password = password;\n }\n\n /**\n * Authenticates with Azure Active Directory and returns an access token if\n * successful. If authentication cannot be performed at this time, this method may\n * return null. If an error occurs during authentication, an {@link AuthenticationError}\n * containing failure details will be thrown.\n *\n * @param scopes The list of scopes for which the token will have access.\n * @param options The options used to configure any requests this\n * TokenCredential implementation might make.\n */\n public async getToken(\n scopes: string | string[],\n options?: GetTokenOptions\n ): Promise<AccessToken | null> {\n const { span, options: newOptions } = createSpan(\n \"UsernamePasswordCredential-getToken\",\n options\n );\n try {\n const urlSuffix = getIdentityTokenEndpointSuffix(this.tenantId);\n const webResource = this.identityClient.createWebResource({\n url: `${this.identityClient.authorityHost}/${this.tenantId}/${urlSuffix}`,\n method: \"POST\",\n disableJsonStringifyOnBody: true,\n deserializationMapper: undefined,\n body: qs.stringify({\n response_type: \"token\",\n grant_type: \"password\",\n client_id: this.clientId,\n username: this.username,\n password: this.password,\n scope: typeof scopes === \"string\" ? scopes : scopes.join(\" \")\n }),\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\"\n },\n abortSignal: options && options.abortSignal,\n spanOptions: newOptions.tracingOptions && newOptions.tracingOptions.spanOptions\n });\n\n const tokenResponse = await this.identityClient.sendTokenRequest(webResource);\n logger.getToken.info(formatSuccess(scopes));\n return (tokenResponse && tokenResponse.accessToken) || null;\n } catch (err) {\n const code =\n err.name === AuthenticationErrorName\n ? CanonicalCode.UNAUTHENTICATED\n : CanonicalCode.UNKNOWN;\n span.setStatus({\n code,\n message: err.message\n });\n logger.getToken.info(formatError(scopes, err));\n throw err;\n } finally {\n span.end();\n }\n }\n}\n"]}
|
|
@@ -5,11 +5,11 @@ const BrowserNotSupportedError = new Error("VisualStudioCodeCredential is not su
|
|
|
5
5
|
const logger = credentialLogger("VisualStudioCodeCredential");
|
|
6
6
|
export class VisualStudioCodeCredential {
|
|
7
7
|
constructor() {
|
|
8
|
-
logger.info(formatError(BrowserNotSupportedError));
|
|
8
|
+
logger.info(formatError("", BrowserNotSupportedError));
|
|
9
9
|
throw BrowserNotSupportedError;
|
|
10
10
|
}
|
|
11
11
|
getToken() {
|
|
12
|
-
logger.getToken.info(formatError(BrowserNotSupportedError));
|
|
12
|
+
logger.getToken.info(formatError("", BrowserNotSupportedError));
|
|
13
13
|
throw BrowserNotSupportedError;
|
|
14
14
|
}
|
|
15
15
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"visualStudioCodeCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/visualStudioCodeCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,6DAA6D,CAC9D,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,4BAA4B,CAAC,CAAC;AAE9D,MAAM,OAAO,0BAA0B;IACrC;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"visualStudioCodeCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/visualStudioCodeCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,6DAA6D,CAC9D,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,4BAA4B,CAAC,CAAC;AAE9D,MAAM,OAAO,0BAA0B;IACrC;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,QAAQ;QACb,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredential, AccessToken } from \"@azure/core-http\";\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\n \"VisualStudioCodeCredential is not supported in the browser.\"\n);\nconst logger = credentialLogger(\"VisualStudioCodeCredential\");\n\nexport class VisualStudioCodeCredential implements TokenCredential {\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
|
|
@@ -14,6 +14,8 @@ catch (er) {
|
|
|
14
14
|
}
|
|
15
15
|
import { CredentialUnavailable } from "../client/errors";
|
|
16
16
|
import { credentialLogger, formatSuccess, formatError } from "../util/logging";
|
|
17
|
+
import { AzureAuthorityHosts } from "../constants";
|
|
18
|
+
import { checkTenantId } from "../util/checkTenantId";
|
|
17
19
|
const CommonTenantId = "common";
|
|
18
20
|
const AzureAccountClientId = "aebc6443-996d-45c2-90f0-388ff96faa56"; // VSC: 'aebc6443-996d-45c2-90f0-388ff96faa56'
|
|
19
21
|
const VSCodeUserName = "VS Code Azure";
|
|
@@ -29,6 +31,12 @@ function checkUnsupportedTenant(tenantId) {
|
|
|
29
31
|
throw new CredentialUnavailable(unsupportedTenantError);
|
|
30
32
|
}
|
|
31
33
|
}
|
|
34
|
+
const mapVSCodeAuthorityHosts = {
|
|
35
|
+
AzureCloud: AzureAuthorityHosts.AzurePublicCloud,
|
|
36
|
+
AzureChina: AzureAuthorityHosts.AzureChina,
|
|
37
|
+
AzureGermanCloud: AzureAuthorityHosts.AzureGermany,
|
|
38
|
+
AzureUSGovernment: AzureAuthorityHosts.AzureGovernment
|
|
39
|
+
};
|
|
32
40
|
/**
|
|
33
41
|
* Attempts to load a specific property from the VSCode configurations of the current OS.
|
|
34
42
|
* If it fails at any point, returns undefined.
|
|
@@ -74,8 +82,14 @@ export class VisualStudioCodeCredential {
|
|
|
74
82
|
* @param options Options for configuring the client which makes the authentication request.
|
|
75
83
|
*/
|
|
76
84
|
constructor(options) {
|
|
77
|
-
|
|
85
|
+
// We want to make sure we use the one assigned by the user on the VSCode settings.
|
|
86
|
+
// Or just `AzureCloud` by default.
|
|
87
|
+
this.cloudName = (getPropertyFromVSCode("azure.cloud") || "AzureCloud");
|
|
88
|
+
// Picking an authority host based on the cloud name.
|
|
89
|
+
const authorityHost = mapVSCodeAuthorityHosts[this.cloudName];
|
|
90
|
+
this.identityClient = new IdentityClient(Object.assign({ authorityHost }, options));
|
|
78
91
|
if (options && options.tenantId) {
|
|
92
|
+
checkTenantId(logger, options.tenantId);
|
|
79
93
|
this.tenantId = options.tenantId;
|
|
80
94
|
}
|
|
81
95
|
else {
|
|
@@ -124,7 +138,7 @@ export class VisualStudioCodeCredential {
|
|
|
124
138
|
// Check to make sure the scope we get back is a valid scope
|
|
125
139
|
if (!scopeString.match(/^[0-9a-zA-Z-.:/]+$/)) {
|
|
126
140
|
const error = new Error("Invalid scope was specified by the user or calling client");
|
|
127
|
-
logger.getToken.info(formatError(error));
|
|
141
|
+
logger.getToken.info(formatError(scopes, error));
|
|
128
142
|
throw error;
|
|
129
143
|
}
|
|
130
144
|
if (scopeString.indexOf("offline_access") < 0) {
|
|
@@ -139,11 +153,8 @@ export class VisualStudioCodeCredential {
|
|
|
139
153
|
// /* ... */
|
|
140
154
|
// ]
|
|
141
155
|
const credentials = yield keytar.findCredentials(VSCodeUserName);
|
|
142
|
-
// We want to make sure we use the one assigned by the user on the VSCode settings.
|
|
143
|
-
// Or just `Azure` by default.
|
|
144
|
-
const cloudName = getPropertyFromVSCode("azure.cloud") || "Azure";
|
|
145
156
|
// If we can't find the credential based on the name, we'll pick the first one available.
|
|
146
|
-
const { password } = credentials.find((cred) => cred.account === cloudName) ||
|
|
157
|
+
const { password } = credentials.find((cred) => cred.account === this.cloudName) ||
|
|
147
158
|
credentials[0] ||
|
|
148
159
|
{};
|
|
149
160
|
// Assuming we found something, the refresh token is the "password" property.
|
|
@@ -156,13 +167,13 @@ export class VisualStudioCodeCredential {
|
|
|
156
167
|
}
|
|
157
168
|
else {
|
|
158
169
|
const error = new CredentialUnavailable("Could not retrieve the token associated with Visual Studio Code. Have you connected using the 'Azure Account' extension recently?");
|
|
159
|
-
logger.getToken.info(formatError(error));
|
|
170
|
+
logger.getToken.info(formatError(scopes, error));
|
|
160
171
|
throw error;
|
|
161
172
|
}
|
|
162
173
|
}
|
|
163
174
|
else {
|
|
164
175
|
const error = new CredentialUnavailable("Could not retrieve the token associated with Visual Studio Code. Did you connect using the 'Azure Account' extension?");
|
|
165
|
-
logger.getToken.info(formatError(error));
|
|
176
|
+
logger.getToken.info(formatError(scopes, error));
|
|
166
177
|
throw error;
|
|
167
178
|
}
|
|
168
179
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"visualStudioCodeCredential.js","sourceRoot":"","sources":["../../../src/credentials/visualStudioCodeCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredential, AccessToken, GetTokenOptions } from \"@azure/core-http\";\nimport { TokenCredentialOptions, IdentityClient } from \"../client/identityClient\";\nimport fs from \"fs\";\nimport os from \"os\";\nimport path from \"path\";\n\nlet keytar: any;\ntry {\n keytar = require(\"keytar\");\n} catch (er) {\n keytar = null;\n}\n\nimport { CredentialUnavailable } from \"../client/errors\";\nimport { credentialLogger, formatSuccess, formatError } from \"../util/logging\";\n\nconst CommonTenantId = \"common\";\nconst AzureAccountClientId = \"aebc6443-996d-45c2-90f0-388ff96faa56\"; // VSC: 'aebc6443-996d-45c2-90f0-388ff96faa56'\nconst VSCodeUserName = \"VS Code Azure\";\nconst logger = credentialLogger(\"VisualStudioCodeCredential\");\n\n// Map of unsupported Tenant IDs and the errors we will be throwing.\nconst unsupportedTenantIds: Record<string, string> = {\n adfs: \"The VisualStudioCodeCredential does not support authentication with ADFS tenants.\"\n};\n\nfunction checkUnsupportedTenant(tenantId: string): void {\n // If the Tenant ID isn't supported, we throw.\n const unsupportedTenantError = unsupportedTenantIds[tenantId];\n if (unsupportedTenantError) {\n throw new CredentialUnavailable(unsupportedTenantError);\n }\n}\n\n/**\n * Attempts to load a specific property from the VSCode configurations of the current OS.\n * If it fails at any point, returns undefined.\n */\nexport function getPropertyFromVSCode(property: string): string | undefined {\n const settingsPath = [\"User\", \"settings.json\"];\n // Eventually we can add more folders for more versions of VSCode.\n const vsCodeFolder = \"Code\";\n const homedir = os.homedir();\n\n function loadProperty(...pathSegments: string[]): string | undefined {\n const fullPath = path.join(...pathSegments, vsCodeFolder, ...settingsPath);\n const settings = JSON.parse(fs.readFileSync(fullPath, { encoding: \"utf8\" }));\n return settings[property];\n }\n\n try {\n let appData: string;\n switch (process.platform) {\n case \"win32\":\n appData = process.env.APPDATA!;\n return appData ? loadProperty(appData) : undefined;\n case \"darwin\":\n return loadProperty(homedir, \"Library\", \"Application Support\");\n case \"linux\":\n return loadProperty(homedir, \".config\");\n default:\n return;\n }\n } catch (e) {\n logger.info(`Failed to load the Visual Studio Code configuration file. Error: ${e.message}`);\n return;\n }\n}\n\n/**\n * Provides options to configure the Visual Studio Code credential.\n */\nexport interface VisualStudioCodeCredentialOptions extends TokenCredentialOptions {\n /**\n * Optionally pass in a Tenant ID to be used as part of the credential\n */\n tenantId?: string;\n}\n\n/**\n * Connect to Azure using the credential provided by the VSCode extension 'Azure Account'.\n * Once the user has logged in via the extension, this credential can share the same refresh token\n * that is cached by the extension.\n */\nexport class VisualStudioCodeCredential implements TokenCredential {\n private identityClient: IdentityClient;\n private tenantId: string;\n\n /**\n * Creates an instance of VisualStudioCodeCredential to use for automatically authenticating via VSCode.\n *\n * @param options Options for configuring the client which makes the authentication request.\n */\n constructor(options?: VisualStudioCodeCredentialOptions) {\n this.identityClient = new IdentityClient(options);\n if (options && options.tenantId) {\n this.tenantId = options.tenantId;\n } else {\n this.tenantId = CommonTenantId;\n }\n checkUnsupportedTenant(this.tenantId);\n }\n\n /**\n * Runs preparations for any further getToken request.\n */\n private async prepare(): Promise<void> {\n // Attempts to load the tenant from the VSCode configuration file.\n const settingsTenant = getPropertyFromVSCode(\"azure.tenant\");\n if (settingsTenant) {\n this.tenantId = settingsTenant;\n }\n checkUnsupportedTenant(this.tenantId);\n }\n\n /**\n * The promise of the single preparation that will be executed at the first getToken request for an instance of this class.\n */\n private preparePromise: Promise<void> | undefined;\n\n /**\n * Runs preparations for any further getToken, but only once.\n */\n private prepareOnce(): Promise<void> | undefined {\n if (this.preparePromise) {\n return this.preparePromise;\n }\n this.preparePromise = this.prepare();\n return this.preparePromise;\n }\n\n /**\n * Returns the token found by searching VSCode's authentication cache or\n * returns null if no token could be found.\n *\n * @param scopes The list of scopes for which the token will have access.\n * @param options The options used to configure any requests this\n * `TokenCredential` implementation might make.\n */\n public async getToken(\n scopes: string | string[],\n _options?: GetTokenOptions\n ): Promise<AccessToken | null> {\n await this.prepareOnce();\n if (!keytar) {\n throw new CredentialUnavailable(\n \"Visual Studio Code credential requires the optional dependency 'keytar' to work correctly\"\n );\n }\n\n let scopeString = typeof scopes === \"string\" ? scopes : scopes.join(\" \");\n\n // Check to make sure the scope we get back is a valid scope\n if (!scopeString.match(/^[0-9a-zA-Z-.:/]+$/)) {\n const error = new Error(\"Invalid scope was specified by the user or calling client\");\n logger.getToken.info(formatError(error));\n throw error;\n }\n\n if (scopeString.indexOf(\"offline_access\") < 0) {\n scopeString += \" offline_access\";\n }\n\n // findCredentials returns an array similar to:\n // [\n // {\n // account: \"\",\n // password: \"\",\n // },\n // /* ... */\n // ]\n const credentials = await keytar.findCredentials(VSCodeUserName);\n\n // We want to make sure we use the one assigned by the user on the VSCode settings.\n // Or just `Azure` by default.\n const cloudName = getPropertyFromVSCode(\"azure.cloud\") || \"Azure\";\n\n // If we can't find the credential based on the name, we'll pick the first one available.\n const { password } =\n credentials.find((cred: { account: string }) => cred.account === cloudName) ||\n credentials[0] ||\n {};\n\n // Assuming we found something, the refresh token is the \"password\" property.\n const refreshToken = password;\n\n if (refreshToken) {\n const tokenResponse = await this.identityClient.refreshAccessToken(\n this.tenantId,\n AzureAccountClientId,\n scopeString,\n refreshToken,\n undefined\n );\n\n if (tokenResponse) {\n logger.getToken.info(formatSuccess(scopes));\n return tokenResponse.accessToken;\n } else {\n const error = new CredentialUnavailable(\n \"Could not retrieve the token associated with Visual Studio Code. Have you connected using the 'Azure Account' extension recently?\"\n );\n logger.getToken.info(formatError(error));\n throw error;\n }\n } else {\n const error = new CredentialUnavailable(\n \"Could not retrieve the token associated with Visual Studio Code. Did you connect using the 'Azure Account' extension?\"\n );\n logger.getToken.info(formatError(error));\n throw error;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"visualStudioCodeCredential.js","sourceRoot":"","sources":["../../../src/credentials/visualStudioCodeCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredential, AccessToken, GetTokenOptions } from \"@azure/core-http\";\nimport { TokenCredentialOptions, IdentityClient } from \"../client/identityClient\";\nimport fs from \"fs\";\nimport os from \"os\";\nimport path from \"path\";\n\nlet keytar: any;\ntry {\n keytar = require(\"keytar\");\n} catch (er) {\n keytar = null;\n}\n\nimport { CredentialUnavailable } from \"../client/errors\";\nimport { credentialLogger, formatSuccess, formatError } from \"../util/logging\";\nimport { AzureAuthorityHosts } from \"../constants\";\nimport { checkTenantId } from \"../util/checkTenantId\";\n\nconst CommonTenantId = \"common\";\nconst AzureAccountClientId = \"aebc6443-996d-45c2-90f0-388ff96faa56\"; // VSC: 'aebc6443-996d-45c2-90f0-388ff96faa56'\nconst VSCodeUserName = \"VS Code Azure\";\nconst logger = credentialLogger(\"VisualStudioCodeCredential\");\n\n// Map of unsupported Tenant IDs and the errors we will be throwing.\nconst unsupportedTenantIds: Record<string, string> = {\n adfs: \"The VisualStudioCodeCredential does not support authentication with ADFS tenants.\"\n};\n\nfunction checkUnsupportedTenant(tenantId: string): void {\n // If the Tenant ID isn't supported, we throw.\n const unsupportedTenantError = unsupportedTenantIds[tenantId];\n if (unsupportedTenantError) {\n throw new CredentialUnavailable(unsupportedTenantError);\n }\n}\n\ntype VSCodeCloudNames = \"AzureCloud\" | \"AzureChina\" | \"AzureGermanCloud\" | \"AzureUSGovernment\";\n\nconst mapVSCodeAuthorityHosts: Record<VSCodeCloudNames, string> = {\n AzureCloud: AzureAuthorityHosts.AzurePublicCloud,\n AzureChina: AzureAuthorityHosts.AzureChina,\n AzureGermanCloud: AzureAuthorityHosts.AzureGermany,\n AzureUSGovernment: AzureAuthorityHosts.AzureGovernment\n};\n\n/**\n * Attempts to load a specific property from the VSCode configurations of the current OS.\n * If it fails at any point, returns undefined.\n */\nexport function getPropertyFromVSCode(property: string): string | undefined {\n const settingsPath = [\"User\", \"settings.json\"];\n // Eventually we can add more folders for more versions of VSCode.\n const vsCodeFolder = \"Code\";\n const homedir = os.homedir();\n\n function loadProperty(...pathSegments: string[]): string | undefined {\n const fullPath = path.join(...pathSegments, vsCodeFolder, ...settingsPath);\n const settings = JSON.parse(fs.readFileSync(fullPath, { encoding: \"utf8\" }));\n return settings[property];\n }\n\n try {\n let appData: string;\n switch (process.platform) {\n case \"win32\":\n appData = process.env.APPDATA!;\n return appData ? loadProperty(appData) : undefined;\n case \"darwin\":\n return loadProperty(homedir, \"Library\", \"Application Support\");\n case \"linux\":\n return loadProperty(homedir, \".config\");\n default:\n return;\n }\n } catch (e) {\n logger.info(`Failed to load the Visual Studio Code configuration file. Error: ${e.message}`);\n return;\n }\n}\n\n/**\n * Provides options to configure the Visual Studio Code credential.\n */\nexport interface VisualStudioCodeCredentialOptions extends TokenCredentialOptions {\n /**\n * Optionally pass in a Tenant ID to be used as part of the credential\n */\n tenantId?: string;\n}\n\n/**\n * Connect to Azure using the credential provided by the VSCode extension 'Azure Account'.\n * Once the user has logged in via the extension, this credential can share the same refresh token\n * that is cached by the extension.\n */\nexport class VisualStudioCodeCredential implements TokenCredential {\n private identityClient: IdentityClient;\n private tenantId: string;\n private cloudName: VSCodeCloudNames;\n\n /**\n * Creates an instance of VisualStudioCodeCredential to use for automatically authenticating via VSCode.\n *\n * @param options Options for configuring the client which makes the authentication request.\n */\n constructor(options?: VisualStudioCodeCredentialOptions) {\n // We want to make sure we use the one assigned by the user on the VSCode settings.\n // Or just `AzureCloud` by default.\n this.cloudName = (getPropertyFromVSCode(\"azure.cloud\") || \"AzureCloud\") as VSCodeCloudNames;\n\n // Picking an authority host based on the cloud name.\n const authorityHost = mapVSCodeAuthorityHosts[this.cloudName];\n\n this.identityClient = new IdentityClient({\n authorityHost,\n ...options\n });\n\n if (options && options.tenantId) {\n checkTenantId(logger, options.tenantId);\n\n this.tenantId = options.tenantId;\n } else {\n this.tenantId = CommonTenantId;\n }\n checkUnsupportedTenant(this.tenantId);\n }\n\n /**\n * Runs preparations for any further getToken request.\n */\n private async prepare(): Promise<void> {\n // Attempts to load the tenant from the VSCode configuration file.\n const settingsTenant = getPropertyFromVSCode(\"azure.tenant\");\n if (settingsTenant) {\n this.tenantId = settingsTenant;\n }\n checkUnsupportedTenant(this.tenantId);\n }\n\n /**\n * The promise of the single preparation that will be executed at the first getToken request for an instance of this class.\n */\n private preparePromise: Promise<void> | undefined;\n\n /**\n * Runs preparations for any further getToken, but only once.\n */\n private prepareOnce(): Promise<void> | undefined {\n if (this.preparePromise) {\n return this.preparePromise;\n }\n this.preparePromise = this.prepare();\n return this.preparePromise;\n }\n\n /**\n * Returns the token found by searching VSCode's authentication cache or\n * returns null if no token could be found.\n *\n * @param scopes The list of scopes for which the token will have access.\n * @param options The options used to configure any requests this\n * `TokenCredential` implementation might make.\n */\n public async getToken(\n scopes: string | string[],\n _options?: GetTokenOptions\n ): Promise<AccessToken | null> {\n await this.prepareOnce();\n if (!keytar) {\n throw new CredentialUnavailable(\n \"Visual Studio Code credential requires the optional dependency 'keytar' to work correctly\"\n );\n }\n\n let scopeString = typeof scopes === \"string\" ? scopes : scopes.join(\" \");\n\n // Check to make sure the scope we get back is a valid scope\n if (!scopeString.match(/^[0-9a-zA-Z-.:/]+$/)) {\n const error = new Error(\"Invalid scope was specified by the user or calling client\");\n logger.getToken.info(formatError(scopes, error));\n throw error;\n }\n\n if (scopeString.indexOf(\"offline_access\") < 0) {\n scopeString += \" offline_access\";\n }\n\n // findCredentials returns an array similar to:\n // [\n // {\n // account: \"\",\n // password: \"\",\n // },\n // /* ... */\n // ]\n const credentials = await keytar.findCredentials(VSCodeUserName);\n\n // If we can't find the credential based on the name, we'll pick the first one available.\n const { password } =\n credentials.find((cred: { account: string }) => cred.account === this.cloudName) ||\n credentials[0] ||\n {};\n\n // Assuming we found something, the refresh token is the \"password\" property.\n const refreshToken = password;\n\n if (refreshToken) {\n const tokenResponse = await this.identityClient.refreshAccessToken(\n this.tenantId,\n AzureAccountClientId,\n scopeString,\n refreshToken,\n undefined\n );\n\n if (tokenResponse) {\n logger.getToken.info(formatSuccess(scopes));\n return tokenResponse.accessToken;\n } else {\n const error = new CredentialUnavailable(\n \"Could not retrieve the token associated with Visual Studio Code. Have you connected using the 'Azure Account' extension recently?\"\n );\n logger.getToken.info(formatError(scopes, error));\n throw error;\n }\n } else {\n const error = new CredentialUnavailable(\n \"Could not retrieve the token associated with Visual Studio Code. Did you connect using the 'Azure Account' extension?\"\n );\n logger.getToken.info(formatError(scopes, error));\n throw error;\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAE9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAE9E,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAC;AAExF,OAAO,EAAE,4BAA4B,EAAE,MAAM,4CAA4C,CAAC;AAC1F,OAAO,EACL,0BAA0B,EAE3B,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAOtE,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,EACL,oBAAoB,EAGrB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACL,sBAAsB,EAEvB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,0BAA0B,EAAE,MAAM,0CAA0C,CAAC;AACtF,OAAO,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAC;AACxF,OAAO,EACL,mBAAmB,EAEnB,4BAA4B,EAC5B,uBAAuB,EACvB,gCAAgC,EAChC,qBAAqB,EACtB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD;;GAEG;AACH,MAAM,UAAU,yBAAyB;IACvC,OAAO,IAAI,sBAAsB,EAAE,CAAC;AACtC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredential } from \"@azure/core-http\";\nimport { DefaultAzureCredential } from \"./credentials/defaultAzureCredential\";\n\nexport { ChainedTokenCredential } from \"./credentials/chainedTokenCredential\";\nexport { TokenCredentialOptions } from \"./client/identityClient\";\nexport { EnvironmentCredential } from \"./credentials/environmentCredential\";\nexport { ClientSecretCredential } from \"./credentials/clientSecretCredential\";\nexport { ClientCertificateCredential } from \"./credentials/clientCertificateCredential\";\nexport { ClientCertificateCredentialOptions } from \"./credentials/clientCertificateCredentialOptions\";\nexport { InteractiveBrowserCredential } from \"./credentials/interactiveBrowserCredential\";\nexport {\n VisualStudioCodeCredential,\n VisualStudioCodeCredentialOptions\n} from \"./credentials/visualStudioCodeCredential\";\nexport { AzureCliCredential } from \"./credentials/azureCliCredential\";\n\nexport {\n InteractiveBrowserCredentialOptions,\n BrowserLoginStyle
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAE9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAE9E,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAC;AAExF,OAAO,EAAE,4BAA4B,EAAE,MAAM,4CAA4C,CAAC;AAC1F,OAAO,EACL,0BAA0B,EAE3B,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAOtE,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,EACL,oBAAoB,EAGrB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACL,sBAAsB,EAEvB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,0BAA0B,EAAE,MAAM,0CAA0C,CAAC;AACtF,OAAO,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAC;AACxF,OAAO,EACL,mBAAmB,EAEnB,4BAA4B,EAC5B,uBAAuB,EACvB,gCAAgC,EAChC,qBAAqB,EACtB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD;;GAEG;AACH,MAAM,UAAU,yBAAyB;IACvC,OAAO,IAAI,sBAAsB,EAAE,CAAC;AACtC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredential } from \"@azure/core-http\";\nimport { DefaultAzureCredential } from \"./credentials/defaultAzureCredential\";\n\nexport { ChainedTokenCredential } from \"./credentials/chainedTokenCredential\";\nexport { TokenCredentialOptions } from \"./client/identityClient\";\nexport { EnvironmentCredential } from \"./credentials/environmentCredential\";\nexport { ClientSecretCredential } from \"./credentials/clientSecretCredential\";\nexport { ClientCertificateCredential } from \"./credentials/clientCertificateCredential\";\nexport { ClientCertificateCredentialOptions } from \"./credentials/clientCertificateCredentialOptions\";\nexport { InteractiveBrowserCredential } from \"./credentials/interactiveBrowserCredential\";\nexport {\n VisualStudioCodeCredential,\n VisualStudioCodeCredentialOptions\n} from \"./credentials/visualStudioCodeCredential\";\nexport { AzureCliCredential } from \"./credentials/azureCliCredential\";\n\nexport { AuthenticationRecord } from \"./client/msalClient\";\nexport {\n InteractiveBrowserCredentialOptions,\n BrowserLoginStyle\n} from \"./credentials/interactiveBrowserCredentialOptions\";\nexport { ManagedIdentityCredential } from \"./credentials/managedIdentityCredential\";\nexport {\n DeviceCodeCredential,\n DeviceCodePromptCallback,\n DeviceCodeInfo\n} from \"./credentials/deviceCodeCredential\";\n\nexport {\n DefaultAzureCredential,\n DefaultAzureCredentialOptions\n} from \"./credentials/defaultAzureCredential\";\nexport { UsernamePasswordCredential } from \"./credentials/usernamePasswordCredential\";\nexport { AuthorizationCodeCredential } from \"./credentials/authorizationCodeCredential\";\nexport {\n AuthenticationError,\n ErrorResponse,\n AggregateAuthenticationError,\n AuthenticationErrorName,\n AggregateAuthenticationErrorName,\n CredentialUnavailable\n} from \"./client/errors\";\n\nexport { TokenCredential, GetTokenOptions, AccessToken } from \"@azure/core-http\";\nexport { logger } from \"./util/logging\";\n\nexport { AzureAuthorityHosts } from \"./constants\";\n\n/**\n * Returns a new instance of the {@link DefaultAzureCredential}.\n */\nexport function getDefaultAzureCredential(): TokenCredential {\n return new DefaultAzureCredential();\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
import { formatError } from "../util/logging";
|
|
4
|
+
export function checkTenantId(logger, tenantId) {
|
|
5
|
+
if (!tenantId.match(/^[0-9a-zA-Z-.:/]+$/)) {
|
|
6
|
+
const error = new Error("Invalid tenant id provided. You can locate your tenant id by following the instructions listed here: https://docs.microsoft.com/partner-center/find-ids-and-domain-names.");
|
|
7
|
+
logger.info(formatError("", error));
|
|
8
|
+
throw error;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=checkTenantId.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkTenantId.js","sourceRoot":"","sources":["../../../src/util/checkTenantId.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAoB,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,UAAU,aAAa,CAAC,MAAwB,EAAE,QAAgB;IACtE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE;QACzC,MAAM,KAAK,GAAG,IAAI,KAAK,CACrB,2KAA2K,CAC5K,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;QACpC,MAAM,KAAK,CAAC;KACb;AACH,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { CredentialLogger, formatError } from \"../util/logging\";\n\nexport function checkTenantId(logger: CredentialLogger, tenantId: string) {\n if (!tenantId.match(/^[0-9a-zA-Z-.:/]+$/)) {\n const error = new Error(\n \"Invalid tenant id provided. You can locate your tenant id by following the instructions listed here: https://docs.microsoft.com/partner-center/find-ids-and-domain-names.\"\n );\n logger.info(formatError(\"\", error));\n throw error;\n }\n}\n"]}
|
|
@@ -34,13 +34,17 @@ export function logEnvVars(credentialName, supportedEnvVars) {
|
|
|
34
34
|
* Formatting the success event on the credentials
|
|
35
35
|
*/
|
|
36
36
|
export function formatSuccess(scope) {
|
|
37
|
-
return `SUCCESS: ${Array.isArray(scope) ? scope.join(", ") : scope}
|
|
37
|
+
return `SUCCESS. Scopes: ${Array.isArray(scope) ? scope.join(", ") : scope}.`;
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
40
|
* Formatting the success event on the credentials
|
|
41
41
|
*/
|
|
42
|
-
export function formatError(error) {
|
|
43
|
-
|
|
42
|
+
export function formatError(scope, error) {
|
|
43
|
+
let message = "ERROR.";
|
|
44
|
+
if (scope === null || scope === void 0 ? void 0 : scope.length) {
|
|
45
|
+
message += ` Scopes: ${Array.isArray(scope) ? scope.join(", ") : scope}.`;
|
|
46
|
+
}
|
|
47
|
+
return `${message} Error message: ${typeof error === "string" ? error : error.message}.`;
|
|
44
48
|
}
|
|
45
49
|
/**
|
|
46
50
|
* Generates a CredentialLoggerInstance.
|