@microsoft/vscode-azext-azureauth 4.2.2 → 5.1.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.
- package/CHANGELOG.md +10 -0
- package/dist/cjs/src/AzureDevOpsSubscriptionProvider.js +215 -0
- package/dist/cjs/src/NotSignedInError.js +63 -0
- package/dist/cjs/src/VSCodeAzureSubscriptionProvider.js +385 -0
- package/dist/cjs/src/getSessionFromVSCode.js +108 -0
- package/{out → dist/cjs}/src/index.js +2 -1
- package/dist/cjs/src/signInToTenant.js +79 -0
- package/dist/cjs/src/utils/configuredAzureEnv.js +128 -0
- package/dist/cjs/src/utils/getUnauthenticatedTenants.js +23 -0
- package/dist/cjs/src/utils/isGetSubscriptionsFilter.js +27 -0
- package/{out → dist/esm}/src/AzureAuthentication.d.ts +2 -2
- package/dist/esm/src/AzureAuthentication.js +6 -0
- package/{out → dist/esm}/src/AzureDevOpsSubscriptionProvider.d.ts +6 -6
- package/dist/esm/src/AzureDevOpsSubscriptionProvider.js +210 -0
- package/{out → dist/esm}/src/AzureSubscription.d.ts +2 -2
- package/dist/esm/src/AzureSubscription.js +6 -0
- package/dist/esm/src/AzureSubscriptionProvider.js +6 -0
- package/{out → dist/esm}/src/AzureTenant.d.ts +2 -2
- package/dist/esm/src/AzureTenant.js +6 -0
- package/{out → dist/esm}/src/NotSignedInError.js +4 -9
- package/{out → dist/esm}/src/VSCodeAzureSubscriptionProvider.d.ts +8 -13
- package/dist/esm/src/VSCodeAzureSubscriptionProvider.js +348 -0
- package/{out → dist/esm}/src/getSessionFromVSCode.d.ts +3 -3
- package/dist/esm/src/getSessionFromVSCode.js +72 -0
- package/{out → dist/esm}/src/index.d.ts +2 -1
- package/dist/esm/src/index.js +16 -0
- package/dist/esm/src/signInToTenant.js +43 -0
- package/dist/esm/src/utils/configuredAzureEnv.js +90 -0
- package/dist/esm/src/utils/getUnauthenticatedTenants.d.ts +9 -0
- package/dist/esm/src/utils/getUnauthenticatedTenants.js +20 -0
- package/dist/esm/src/utils/isAuthenticationWwwAuthenticateRequest.js +12 -0
- package/dist/esm/src/utils/isGetSubscriptionsFilter.d.ts +14 -0
- package/dist/esm/src/utils/isGetSubscriptionsFilter.js +23 -0
- package/package.json +13 -12
- package/out/src/AzureDevOpsSubscriptionProvider.js +0 -252
- package/out/src/VSCodeAzureSubscriptionProvider.js +0 -384
- package/out/src/getSessionFromVSCode.js +0 -76
- package/out/src/signInToTenant.js +0 -64
- package/out/src/utils/configuredAzureEnv.js +0 -94
- package/out/src/utils/getUnauthenticatedTenants.d.ts +0 -6
- package/out/src/utils/getUnauthenticatedTenants.js +0 -52
- /package/{out → dist/cjs}/src/AzureAuthentication.js +0 -0
- /package/{out → dist/cjs}/src/AzureSubscription.js +0 -0
- /package/{out → dist/cjs}/src/AzureSubscriptionProvider.js +0 -0
- /package/{out → dist/cjs}/src/AzureTenant.js +0 -0
- /package/{out → dist/cjs}/src/utils/isAuthenticationWwwAuthenticateRequest.js +0 -0
- /package/{out → dist/esm}/src/AzureSubscriptionProvider.d.ts +0 -0
- /package/{out → dist/esm}/src/NotSignedInError.d.ts +0 -0
- /package/{out → dist/esm}/src/signInToTenant.d.ts +0 -0
- /package/{out → dist/esm}/src/utils/configuredAzureEnv.d.ts +0 -0
- /package/{out → dist/esm}/src/utils/isAuthenticationWwwAuthenticateRequest.d.ts +0 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.getSessionFromVSCode = getSessionFromVSCode;
|
|
41
|
+
const vscode = __importStar(require("vscode"));
|
|
42
|
+
const configuredAzureEnv_1 = require("./utils/configuredAzureEnv");
|
|
43
|
+
const isAuthenticationWwwAuthenticateRequest_1 = require("./utils/isAuthenticationWwwAuthenticateRequest");
|
|
44
|
+
function ensureEndingSlash(value) {
|
|
45
|
+
return value.endsWith('/') ? value : `${value}/`;
|
|
46
|
+
}
|
|
47
|
+
function getResourceScopes(scopes) {
|
|
48
|
+
if (scopes === undefined || scopes === "" || scopes.length === 0) {
|
|
49
|
+
scopes = ensureEndingSlash((0, configuredAzureEnv_1.getConfiguredAzureEnv)().managementEndpointUrl);
|
|
50
|
+
}
|
|
51
|
+
const arrScopes = (Array.isArray(scopes) ? scopes : [scopes])
|
|
52
|
+
.map((scope) => {
|
|
53
|
+
if (scope.endsWith('.default')) {
|
|
54
|
+
return scope;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
return `${scope}.default`;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
return Array.from(new Set(arrScopes));
|
|
61
|
+
}
|
|
62
|
+
function addTenantIdScope(scopes, tenantId) {
|
|
63
|
+
const scopeSet = new Set(scopes);
|
|
64
|
+
scopeSet.add(`VSCODE_TENANT:${tenantId}`);
|
|
65
|
+
return Array.from(scopeSet);
|
|
66
|
+
}
|
|
67
|
+
function getModifiedScopes(scopes, tenantId) {
|
|
68
|
+
let scopeArr = getResourceScopes(scopes);
|
|
69
|
+
if (tenantId) {
|
|
70
|
+
scopeArr = addTenantIdScope(scopeArr, tenantId);
|
|
71
|
+
}
|
|
72
|
+
return scopeArr;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Deconstructs and rebuilds the scopes arg in order to use the above utils to modify the scopes array.
|
|
76
|
+
* And then returns the proper type to pass directly to vscode.authentication.getSession
|
|
77
|
+
*/
|
|
78
|
+
function formScopesArg(scopeOrListOrRequest, tenantId) {
|
|
79
|
+
const isChallenge = (0, isAuthenticationWwwAuthenticateRequest_1.isAuthenticationWwwAuthenticateRequest)(scopeOrListOrRequest);
|
|
80
|
+
let initialScopeList = undefined;
|
|
81
|
+
if (typeof scopeOrListOrRequest === 'string' && !!scopeOrListOrRequest) {
|
|
82
|
+
initialScopeList = [scopeOrListOrRequest];
|
|
83
|
+
}
|
|
84
|
+
else if (Array.isArray(scopeOrListOrRequest)) {
|
|
85
|
+
initialScopeList = scopeOrListOrRequest;
|
|
86
|
+
}
|
|
87
|
+
else if (isChallenge) {
|
|
88
|
+
// `scopeOrListOrRequest.fallbackScopes` being readonly forces us to rebuild the array
|
|
89
|
+
initialScopeList = scopeOrListOrRequest.fallbackScopes ? Array.from(scopeOrListOrRequest.fallbackScopes) : undefined;
|
|
90
|
+
}
|
|
91
|
+
const modifiedScopeList = getModifiedScopes(initialScopeList, tenantId);
|
|
92
|
+
return isChallenge ? { fallbackScopes: modifiedScopeList, wwwAuthenticate: scopeOrListOrRequest.wwwAuthenticate } : modifiedScopeList;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Wraps {@link vscode.authentication.getSession} and handles:
|
|
96
|
+
* * Passing the configured auth provider id
|
|
97
|
+
* * Getting the list of scopes, adding the tenant id to the scope list if needed
|
|
98
|
+
*
|
|
99
|
+
* @param scopeOrListOrRequest - top-level resource scopes (e.g. http://management.azure.com, http://storage.azure.com) or .default scopes. All resources/scopes will be normalized to the `.default` scope for each resource.
|
|
100
|
+
* Use `vscode.AuthenticationWwwAuthenticateRequest` if you need to pass in a challenge (WWW-Authenticate header). Note: Use of `vscode.AuthenticationWwwAuthenticateRequest` requires VS Code 1.105.0 or newer.
|
|
101
|
+
* @param tenantId - (Optional) The tenant ID, will be added to the scopes
|
|
102
|
+
* @param options - see {@link vscode.AuthenticationGetSessionOptions}
|
|
103
|
+
* @returns An authentication session if available, or undefined if there are no sessions
|
|
104
|
+
*/
|
|
105
|
+
async function getSessionFromVSCode(scopeOrListOrRequest, tenantId, options) {
|
|
106
|
+
return await vscode.authentication.getSession((0, configuredAzureEnv_1.getConfiguredAuthProviderId)(), formScopesArg(scopeOrListOrRequest, tenantId), options);
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=getSessionFromVSCode.js.map
|
|
@@ -20,9 +20,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
21
|
__exportStar(require("./AzureAuthentication"), exports);
|
|
22
22
|
__exportStar(require("./AzureDevOpsSubscriptionProvider"), exports);
|
|
23
|
-
__exportStar(require("./AzureTenant"), exports);
|
|
24
23
|
__exportStar(require("./AzureSubscription"), exports);
|
|
25
24
|
__exportStar(require("./AzureSubscriptionProvider"), exports);
|
|
25
|
+
__exportStar(require("./AzureTenant"), exports);
|
|
26
|
+
__exportStar(require("./getSessionFromVSCode"), exports);
|
|
26
27
|
__exportStar(require("./NotSignedInError"), exports);
|
|
27
28
|
__exportStar(require("./signInToTenant"), exports);
|
|
28
29
|
__exportStar(require("./utils/configuredAzureEnv"), exports);
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.signInToTenant = signInToTenant;
|
|
41
|
+
const vscode = __importStar(require("vscode"));
|
|
42
|
+
const getUnauthenticatedTenants_1 = require("./utils/getUnauthenticatedTenants");
|
|
43
|
+
/**
|
|
44
|
+
* Prompts user to select from a list of unauthenticated tenants.
|
|
45
|
+
* Once selected, requests a new session from VS Code specifially for this tenant.
|
|
46
|
+
*/
|
|
47
|
+
async function signInToTenant(subscriptionProvider) {
|
|
48
|
+
const tenantId = await pickTenant(subscriptionProvider);
|
|
49
|
+
if (tenantId) {
|
|
50
|
+
await subscriptionProvider.signIn(tenantId);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async function pickTenant(subscriptionProvider) {
|
|
54
|
+
const pick = await vscode.window.showQuickPick(getPicks(subscriptionProvider), {
|
|
55
|
+
placeHolder: 'Select a Tenant (Directory) to Sign In To', // TODO: localize
|
|
56
|
+
matchOnDescription: true, // allow searching by tenantId
|
|
57
|
+
ignoreFocusOut: true,
|
|
58
|
+
});
|
|
59
|
+
return pick?.tenant.tenantId;
|
|
60
|
+
}
|
|
61
|
+
async function getPicks(subscriptionProvider) {
|
|
62
|
+
const unauthenticatedTenants = await (0, getUnauthenticatedTenants_1.getUnauthenticatedTenants)(subscriptionProvider);
|
|
63
|
+
const duplicateTenants = new Set(unauthenticatedTenants
|
|
64
|
+
.filter((tenant, index, self) => index !== self.findIndex(t => t.tenantId === tenant.tenantId))
|
|
65
|
+
.map(tenant => tenant.tenantId));
|
|
66
|
+
const isDuplicate = (tenantId) => duplicateTenants.has(tenantId);
|
|
67
|
+
const picks = unauthenticatedTenants
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
69
|
+
.sort((a, b) => (a.displayName).localeCompare(b.displayName))
|
|
70
|
+
.map(tenant => ({
|
|
71
|
+
label: tenant.displayName ?? '',
|
|
72
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
73
|
+
description: `${tenant.tenantId}${isDuplicate(tenant.tenantId) ? ` (${tenant.account.label})` : ''}`,
|
|
74
|
+
detail: tenant.defaultDomain ?? '',
|
|
75
|
+
tenant,
|
|
76
|
+
}));
|
|
77
|
+
return picks;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=signInToTenant.js.map
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.getConfiguredAzureEnv = getConfiguredAzureEnv;
|
|
41
|
+
exports.setConfiguredAzureEnv = setConfiguredAzureEnv;
|
|
42
|
+
exports.getConfiguredAuthProviderId = getConfiguredAuthProviderId;
|
|
43
|
+
const azureEnv = __importStar(require("@azure/ms-rest-azure-env")); // This package is so small that it's not worth lazy loading
|
|
44
|
+
const vscode = __importStar(require("vscode"));
|
|
45
|
+
// These strings come from https://github.com/microsoft/vscode/blob/eac16e9b63a11885b538db3e0b533a02a2fb8143/extensions/microsoft-authentication/package.json#L40-L99
|
|
46
|
+
const CustomCloudConfigurationSection = 'microsoft-sovereign-cloud';
|
|
47
|
+
const CloudEnvironmentSettingName = 'environment';
|
|
48
|
+
const CustomEnvironmentSettingName = 'customEnvironment';
|
|
49
|
+
var CloudEnvironmentSettingValue;
|
|
50
|
+
(function (CloudEnvironmentSettingValue) {
|
|
51
|
+
CloudEnvironmentSettingValue["ChinaCloud"] = "ChinaCloud";
|
|
52
|
+
CloudEnvironmentSettingValue["USGovernment"] = "USGovernment";
|
|
53
|
+
CloudEnvironmentSettingValue["Custom"] = "custom";
|
|
54
|
+
})(CloudEnvironmentSettingValue || (CloudEnvironmentSettingValue = {}));
|
|
55
|
+
/**
|
|
56
|
+
* Gets the configured Azure environment.
|
|
57
|
+
*
|
|
58
|
+
* @returns The configured Azure environment from the settings in the built-in authentication provider extension
|
|
59
|
+
*/
|
|
60
|
+
function getConfiguredAzureEnv() {
|
|
61
|
+
const authProviderConfig = vscode.workspace.getConfiguration(CustomCloudConfigurationSection);
|
|
62
|
+
const environmentSettingValue = authProviderConfig.get(CloudEnvironmentSettingName);
|
|
63
|
+
if (environmentSettingValue === CloudEnvironmentSettingValue.ChinaCloud) {
|
|
64
|
+
return {
|
|
65
|
+
...azureEnv.Environment.ChinaCloud,
|
|
66
|
+
isCustomCloud: false,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
else if (environmentSettingValue === CloudEnvironmentSettingValue.USGovernment) {
|
|
70
|
+
return {
|
|
71
|
+
...azureEnv.Environment.USGovernment,
|
|
72
|
+
isCustomCloud: false,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
else if (environmentSettingValue === CloudEnvironmentSettingValue.Custom) {
|
|
76
|
+
const customCloud = authProviderConfig.get(CustomEnvironmentSettingName);
|
|
77
|
+
if (customCloud) {
|
|
78
|
+
return {
|
|
79
|
+
...new azureEnv.Environment(customCloud),
|
|
80
|
+
isCustomCloud: true,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
throw new Error(vscode.l10n.t('The custom cloud choice is not configured. Please configure the setting `{0}.{1}`.', CustomCloudConfigurationSection, CustomEnvironmentSettingName));
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
...azureEnv.Environment.get(azureEnv.Environment.AzureCloud.name),
|
|
87
|
+
isCustomCloud: false,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Sets the configured Azure cloud.
|
|
92
|
+
*
|
|
93
|
+
* @param cloud Use `'AzureCloud'` or `undefined` for public Azure cloud, `'ChinaCloud'` for Azure China, or `'USGovernment'` for Azure US Government.
|
|
94
|
+
* These are the same values as the cloud names in `@azure/ms-rest-azure-env`. For a custom cloud, use an instance of the `@azure/ms-rest-azure-env` {@link azureEnv.EnvironmentParameters}.
|
|
95
|
+
*
|
|
96
|
+
* @param target (Optional) The configuration target to use, by default {@link vscode.ConfigurationTarget.Global}.
|
|
97
|
+
*/
|
|
98
|
+
async function setConfiguredAzureEnv(cloud, target = vscode.ConfigurationTarget.Global) {
|
|
99
|
+
const authProviderConfig = vscode.workspace.getConfiguration(CustomCloudConfigurationSection);
|
|
100
|
+
if (typeof cloud === 'undefined' || !cloud) {
|
|
101
|
+
// Use public cloud implicitly--set `environment` setting to `undefined`
|
|
102
|
+
await authProviderConfig.update(CloudEnvironmentSettingName, undefined, target);
|
|
103
|
+
}
|
|
104
|
+
else if (typeof cloud === 'string' && cloud === 'AzureCloud') {
|
|
105
|
+
// Use public cloud explicitly--set `environment` setting to `undefined`
|
|
106
|
+
await authProviderConfig.update(CloudEnvironmentSettingName, undefined, target);
|
|
107
|
+
}
|
|
108
|
+
else if (typeof cloud === 'string') {
|
|
109
|
+
// Use a sovereign cloud--set the `environment` setting to the specified value
|
|
110
|
+
await authProviderConfig.update(CloudEnvironmentSettingName, cloud, target);
|
|
111
|
+
}
|
|
112
|
+
else if (typeof cloud === 'object') {
|
|
113
|
+
// use a custom cloud--set the `environment` setting to `custom` and the `customEnvironment` setting to the specified value
|
|
114
|
+
await authProviderConfig.update(CloudEnvironmentSettingName, CloudEnvironmentSettingValue.Custom, target);
|
|
115
|
+
await authProviderConfig.update(CustomEnvironmentSettingName, cloud, target);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
throw new Error(`Invalid cloud value: ${JSON.stringify(cloud)}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Gets the ID of the authentication provider configured to be used
|
|
123
|
+
* @returns The provider ID to use, either `'microsoft'` or `'microsoft-sovereign-cloud'`
|
|
124
|
+
*/
|
|
125
|
+
function getConfiguredAuthProviderId() {
|
|
126
|
+
return getConfiguredAzureEnv().name === azureEnv.Environment.AzureCloud.name ? 'microsoft' : 'microsoft-sovereign-cloud';
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=configuredAzureEnv.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.getUnauthenticatedTenants = getUnauthenticatedTenants;
|
|
8
|
+
/**
|
|
9
|
+
* @param subscriptionProvider The {@link AzureSubscriptionProvider} to use
|
|
10
|
+
* @param account (Optional) The account to get unauthenticated tenants for
|
|
11
|
+
* @returns list of tenants that VS Code doesn't have sessions for
|
|
12
|
+
*/
|
|
13
|
+
async function getUnauthenticatedTenants(subscriptionProvider, account) {
|
|
14
|
+
const tenants = await subscriptionProvider.getTenants(account);
|
|
15
|
+
const unauthenticatedTenants = [];
|
|
16
|
+
for await (const tenant of tenants) {
|
|
17
|
+
if (!await subscriptionProvider.isSignedIn(tenant.tenantId, tenant.account)) {
|
|
18
|
+
unauthenticatedTenants.push(tenant);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return unauthenticatedTenants;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=getUnauthenticatedTenants.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
* Licensed under the MIT License. See License.md in the project root for license information.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.isGetSubscriptionsTenantFilter = isGetSubscriptionsTenantFilter;
|
|
8
|
+
exports.isGetSubscriptionsAccountFilter = isGetSubscriptionsAccountFilter;
|
|
9
|
+
/**
|
|
10
|
+
* Check if an object is a {@link GetSubscriptionsFilter} with a tenantId.
|
|
11
|
+
*/
|
|
12
|
+
function isGetSubscriptionsTenantFilter(obj) {
|
|
13
|
+
if (typeof obj === 'object' && !!obj && 'tenantId' in obj && typeof obj.tenantId === 'string' && !!obj.tenantId) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Check if an object is a {@link GetSubscriptionsFilter} with an account.
|
|
20
|
+
*/
|
|
21
|
+
function isGetSubscriptionsAccountFilter(obj) {
|
|
22
|
+
if (typeof obj === 'object' && !!obj && 'account' in obj && typeof obj.account === 'object' && !!obj.account) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=isGetSubscriptionsFilter.js.map
|
|
@@ -13,9 +13,9 @@ export interface AzureAuthentication {
|
|
|
13
13
|
/**
|
|
14
14
|
* Gets a VS Code authentication session for an Azure subscription.
|
|
15
15
|
*
|
|
16
|
-
* @param
|
|
16
|
+
* @param scopeListOrRequest - The scopes or request for which the authentication is needed.
|
|
17
17
|
*
|
|
18
18
|
* @returns A VS Code authentication session or undefined, if none could be obtained.
|
|
19
19
|
*/
|
|
20
|
-
getSessionWithScopes(
|
|
20
|
+
getSessionWithScopes(scopeListOrRequest: string[] | vscode.AuthenticationWwwAuthenticateRequest): vscode.ProviderResult<vscode.AuthenticationSession>;
|
|
21
21
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=AzureAuthentication.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { AzureSubscription } from './AzureSubscription';
|
|
3
|
-
import { AzureSubscriptionProvider, GetSubscriptionsFilter } from './AzureSubscriptionProvider';
|
|
4
|
-
import { AzureTenant } from './AzureTenant';
|
|
1
|
+
import type * as vscode from 'vscode';
|
|
2
|
+
import type { AzureSubscription } from './AzureSubscription';
|
|
3
|
+
import type { AzureSubscriptionProvider, GetSubscriptionsFilter } from './AzureSubscriptionProvider';
|
|
4
|
+
import type { AzureTenant } from './AzureTenant';
|
|
5
5
|
export interface AzureDevOpsSubscriptionProviderInitializer {
|
|
6
6
|
/**
|
|
7
7
|
* The resource ID of the Azure DevOps federated service connection,
|
|
@@ -63,6 +63,6 @@ export declare class AzureDevOpsSubscriptionProvider implements AzureSubscriptio
|
|
|
63
63
|
* @returns A client, the credential used by the client, and the authentication function
|
|
64
64
|
*/
|
|
65
65
|
private getSubscriptionClient;
|
|
66
|
-
onDidSignIn: Event<void>;
|
|
67
|
-
onDidSignOut: Event<void>;
|
|
66
|
+
onDidSignIn: vscode.Event<void>;
|
|
67
|
+
onDidSignOut: vscode.Event<void>;
|
|
68
68
|
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { getConfiguredAzureEnv } from './utils/configuredAzureEnv';
|
|
6
|
+
let azureDevOpsSubscriptionProvider;
|
|
7
|
+
export function createAzureDevOpsSubscriptionProviderFactory(initializer) {
|
|
8
|
+
return async () => {
|
|
9
|
+
azureDevOpsSubscriptionProvider ??= new AzureDevOpsSubscriptionProvider(initializer);
|
|
10
|
+
return azureDevOpsSubscriptionProvider;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* AzureSubscriptionProvider implemented to authenticate via federated DevOps service connection, using workflow identity federation
|
|
15
|
+
* To learn how to configure your DevOps environment to use this provider, refer to the README.md
|
|
16
|
+
* NOTE: This provider is only available when running in an Azure DevOps pipeline
|
|
17
|
+
* Reference: https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation
|
|
18
|
+
*/
|
|
19
|
+
export class AzureDevOpsSubscriptionProvider {
|
|
20
|
+
_tokenCredential;
|
|
21
|
+
/**
|
|
22
|
+
* The resource ID of the Azure DevOps federated service connection,
|
|
23
|
+
* which can be found on the `resourceId` field of the URL at the address bar
|
|
24
|
+
* when viewing the service connection in the Azure DevOps portal
|
|
25
|
+
*/
|
|
26
|
+
_SERVICE_CONNECTION_ID;
|
|
27
|
+
/**
|
|
28
|
+
* The `Tenant ID` field of the service connection properties
|
|
29
|
+
*/
|
|
30
|
+
_DOMAIN;
|
|
31
|
+
/**
|
|
32
|
+
* The `Service Principal Id` field of the service connection properties
|
|
33
|
+
*/
|
|
34
|
+
_CLIENT_ID;
|
|
35
|
+
constructor({ serviceConnectionId, domain, clientId }) {
|
|
36
|
+
if (!serviceConnectionId || !domain || !clientId) {
|
|
37
|
+
throw new Error(`Missing initializer values to identify Azure DevOps federated service connection\n
|
|
38
|
+
Values provided:\n
|
|
39
|
+
serviceConnectionId: ${serviceConnectionId ? "✅" : "❌"}\n
|
|
40
|
+
domain: ${domain ? "✅" : "❌"}\n
|
|
41
|
+
clientId: ${clientId ? "✅" : "❌"}\n
|
|
42
|
+
`);
|
|
43
|
+
}
|
|
44
|
+
this._SERVICE_CONNECTION_ID = serviceConnectionId;
|
|
45
|
+
this._DOMAIN = domain;
|
|
46
|
+
this._CLIENT_ID = clientId;
|
|
47
|
+
}
|
|
48
|
+
async getSubscriptions(_filter) {
|
|
49
|
+
// ignore the filter setting because not every consumer of this provider will use the Resources extension
|
|
50
|
+
const results = [];
|
|
51
|
+
for (const tenant of await this.getTenants()) {
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
53
|
+
const tenantId = tenant.tenantId;
|
|
54
|
+
results.push(...await this.getSubscriptionsForTenant(tenantId));
|
|
55
|
+
}
|
|
56
|
+
const sortSubscriptions = (subscriptions) => subscriptions.sort((a, b) => a.name.localeCompare(b.name));
|
|
57
|
+
return sortSubscriptions(results);
|
|
58
|
+
}
|
|
59
|
+
async isSignedIn() {
|
|
60
|
+
return !!this._tokenCredential;
|
|
61
|
+
}
|
|
62
|
+
async signIn() {
|
|
63
|
+
this._tokenCredential = await getTokenCredential(this._SERVICE_CONNECTION_ID, this._DOMAIN, this._CLIENT_ID);
|
|
64
|
+
return !!this._tokenCredential;
|
|
65
|
+
}
|
|
66
|
+
async signOut() {
|
|
67
|
+
this._tokenCredential = undefined;
|
|
68
|
+
}
|
|
69
|
+
async getTenants() {
|
|
70
|
+
return [{
|
|
71
|
+
tenantId: this._tokenCredential?.tenantId,
|
|
72
|
+
account: {
|
|
73
|
+
id: "test-account-id",
|
|
74
|
+
label: "test-account",
|
|
75
|
+
}
|
|
76
|
+
}];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Gets the subscriptions for a given tenant.
|
|
80
|
+
*
|
|
81
|
+
* @param tenantId The tenant ID to get subscriptions for.
|
|
82
|
+
*
|
|
83
|
+
* @returns The list of subscriptions for the tenant.
|
|
84
|
+
*/
|
|
85
|
+
async getSubscriptionsForTenant(tenantId) {
|
|
86
|
+
const { client, credential, authentication } = await this.getSubscriptionClient(tenantId);
|
|
87
|
+
const environment = getConfiguredAzureEnv();
|
|
88
|
+
const subscriptions = [];
|
|
89
|
+
for await (const subscription of client.subscriptions.list()) {
|
|
90
|
+
subscriptions.push({
|
|
91
|
+
authentication,
|
|
92
|
+
environment: environment,
|
|
93
|
+
credential: credential,
|
|
94
|
+
isCustomCloud: environment.isCustomCloud,
|
|
95
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
96
|
+
name: subscription.displayName,
|
|
97
|
+
subscriptionId: subscription.subscriptionId,
|
|
98
|
+
/* eslint-enable @typescript-eslint/no-non-null-assertion */
|
|
99
|
+
tenantId,
|
|
100
|
+
account: {
|
|
101
|
+
id: "test-account-id",
|
|
102
|
+
label: "test-account",
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
return subscriptions;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Gets a fully-configured subscription client for a given tenant ID
|
|
110
|
+
*
|
|
111
|
+
* @param tenantId (Optional) The tenant ID to get a client for
|
|
112
|
+
*
|
|
113
|
+
* @returns A client, the credential used by the client, and the authentication function
|
|
114
|
+
*/
|
|
115
|
+
async getSubscriptionClient(_tenantId, scopes) {
|
|
116
|
+
const armSubs = await import('@azure/arm-resources-subscriptions');
|
|
117
|
+
if (!this._tokenCredential) {
|
|
118
|
+
throw new Error('Not signed in');
|
|
119
|
+
}
|
|
120
|
+
const accessToken = (await this._tokenCredential?.getToken("https://management.azure.com/.default"))?.token || '';
|
|
121
|
+
const getSession = () => {
|
|
122
|
+
return {
|
|
123
|
+
accessToken,
|
|
124
|
+
id: this._tokenCredential?.tenantId || '',
|
|
125
|
+
account: {
|
|
126
|
+
id: this._tokenCredential?.tenantId || '',
|
|
127
|
+
label: this._tokenCredential?.tenantId || '',
|
|
128
|
+
},
|
|
129
|
+
tenantId: this._tokenCredential?.tenantId || '',
|
|
130
|
+
scopes: scopes || [],
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
return {
|
|
134
|
+
client: new armSubs.SubscriptionClient(this._tokenCredential),
|
|
135
|
+
credential: this._tokenCredential,
|
|
136
|
+
authentication: {
|
|
137
|
+
getSession,
|
|
138
|
+
getSessionWithScopes: getSession,
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
onDidSignIn = () => { return { dispose() { } }; };
|
|
143
|
+
onDidSignOut = () => { return { dispose() { } }; };
|
|
144
|
+
}
|
|
145
|
+
/*
|
|
146
|
+
* @param serviceConnectionId The resource ID of the Azure DevOps federated service connection,
|
|
147
|
+
* which can be found on the `resourceId` field of the URL at the address bar when viewing the service connection in the Azure DevOps portal
|
|
148
|
+
* @param domain The `Tenant ID` field of the service connection properties
|
|
149
|
+
* @param clientId The `Service Principal Id` field of the service connection properties
|
|
150
|
+
*/
|
|
151
|
+
async function getTokenCredential(serviceConnectionId, domain, clientId) {
|
|
152
|
+
if (!process.env.AGENT_BUILDDIRECTORY) {
|
|
153
|
+
// Assume that AGENT_BUILDDIRECTORY is set if running in an Azure DevOps pipeline.
|
|
154
|
+
// So when not running in an Azure DevOps pipeline, throw an error since we cannot use the DevOps federated service connection credential.
|
|
155
|
+
throw new Error(`Cannot create DevOps federated service connection credential outside of an Azure DevOps pipeline.`);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
console.log(`Creating DevOps federated service connection credential for service connection..`);
|
|
159
|
+
// Pre-defined DevOps variable reference: https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops
|
|
160
|
+
const systemAccessToken = process.env.SYSTEM_ACCESSTOKEN;
|
|
161
|
+
const teamFoundationCollectionUri = process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI;
|
|
162
|
+
const teamProjectId = process.env.SYSTEM_TEAMPROJECTID;
|
|
163
|
+
const planId = process.env.SYSTEM_PLANID;
|
|
164
|
+
const jobId = process.env.SYSTEM_JOBID;
|
|
165
|
+
if (!systemAccessToken || !teamFoundationCollectionUri || !teamProjectId || !planId || !jobId) {
|
|
166
|
+
throw new Error(`Azure DevOps environment variables are not set.\n
|
|
167
|
+
process.env.SYSTEM_ACCESSTOKEN: ${process.env.SYSTEM_ACCESSTOKEN ? "✅" : "❌"}\n
|
|
168
|
+
process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI: ${process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI ? "✅" : "❌"}\n
|
|
169
|
+
process.env.SYSTEM_TEAMPROJECTID: ${process.env.SYSTEM_TEAMPROJECTID ? "✅" : "❌"}\n
|
|
170
|
+
process.env.SYSTEM_PLANID: ${process.env.SYSTEM_PLANID ? "✅" : "❌"}\n
|
|
171
|
+
process.env.SYSTEM_JOBID: ${process.env.SYSTEM_JOBID ? "✅" : "❌"}\n
|
|
172
|
+
REMEMBER: process.env.SYSTEM_ACCESSTOKEN must be explicitly mapped!\n
|
|
173
|
+
https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#systemaccesstoken
|
|
174
|
+
`);
|
|
175
|
+
}
|
|
176
|
+
const oidcRequestUrl = `${teamFoundationCollectionUri}${teamProjectId}/_apis/distributedtask/hubs/build/plans/${planId}/jobs/${jobId}/oidctoken?api-version=7.1-preview.1&serviceConnectionId=${serviceConnectionId}`;
|
|
177
|
+
const { ClientAssertionCredential } = await import("@azure/identity");
|
|
178
|
+
return new ClientAssertionCredential(domain, clientId, async () => await requestOidcToken(oidcRequestUrl, systemAccessToken));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* API reference: https://learn.microsoft.com/en-us/rest/api/azure/devops/distributedtask/oidctoken/create
|
|
183
|
+
*/
|
|
184
|
+
async function requestOidcToken(oidcRequestUrl, systemAccessToken) {
|
|
185
|
+
const { ServiceClient } = await import('@azure/core-client');
|
|
186
|
+
const { createHttpHeaders, createPipelineRequest } = await import('@azure/core-rest-pipeline');
|
|
187
|
+
const genericClient = new ServiceClient();
|
|
188
|
+
const request = createPipelineRequest({
|
|
189
|
+
url: oidcRequestUrl,
|
|
190
|
+
method: "POST",
|
|
191
|
+
headers: createHttpHeaders({
|
|
192
|
+
"Content-Type": "application/json",
|
|
193
|
+
"Authorization": `Bearer ${systemAccessToken}`
|
|
194
|
+
})
|
|
195
|
+
});
|
|
196
|
+
const response = await genericClient.sendRequest(request);
|
|
197
|
+
const body = response.bodyAsText?.toString() || "";
|
|
198
|
+
if (response.status !== 200) {
|
|
199
|
+
throw new Error(`Failed to get OIDC token:\n
|
|
200
|
+
Response status: ${response.status}\n
|
|
201
|
+
Response body: ${body}\n
|
|
202
|
+
Response headers: ${JSON.stringify(response.headers.toJSON())}
|
|
203
|
+
`);
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
console.log(`Successfully got OIDC token with status ${response.status}`);
|
|
207
|
+
}
|
|
208
|
+
return JSON.parse(body).oidcToken;
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=AzureDevOpsSubscriptionProvider.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { TokenCredential } from '@azure/core-auth';
|
|
2
2
|
import type { Environment } from '@azure/ms-rest-azure-env';
|
|
3
|
-
import * as vscode from "vscode";
|
|
4
|
-
import { AzureAuthentication } from './AzureAuthentication';
|
|
3
|
+
import type * as vscode from "vscode";
|
|
4
|
+
import type { AzureAuthentication } from './AzureAuthentication';
|
|
5
5
|
/**
|
|
6
6
|
* A type representing an Azure subscription ID, not including the tenant ID.
|
|
7
7
|
*/
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=AzureSubscription.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=AzureSubscriptionProvider.js.map
|