@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.
Files changed (51) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/cjs/src/AzureDevOpsSubscriptionProvider.js +215 -0
  3. package/dist/cjs/src/NotSignedInError.js +63 -0
  4. package/dist/cjs/src/VSCodeAzureSubscriptionProvider.js +385 -0
  5. package/dist/cjs/src/getSessionFromVSCode.js +108 -0
  6. package/{out → dist/cjs}/src/index.js +2 -1
  7. package/dist/cjs/src/signInToTenant.js +79 -0
  8. package/dist/cjs/src/utils/configuredAzureEnv.js +128 -0
  9. package/dist/cjs/src/utils/getUnauthenticatedTenants.js +23 -0
  10. package/dist/cjs/src/utils/isGetSubscriptionsFilter.js +27 -0
  11. package/{out → dist/esm}/src/AzureAuthentication.d.ts +2 -2
  12. package/dist/esm/src/AzureAuthentication.js +6 -0
  13. package/{out → dist/esm}/src/AzureDevOpsSubscriptionProvider.d.ts +6 -6
  14. package/dist/esm/src/AzureDevOpsSubscriptionProvider.js +210 -0
  15. package/{out → dist/esm}/src/AzureSubscription.d.ts +2 -2
  16. package/dist/esm/src/AzureSubscription.js +6 -0
  17. package/dist/esm/src/AzureSubscriptionProvider.js +6 -0
  18. package/{out → dist/esm}/src/AzureTenant.d.ts +2 -2
  19. package/dist/esm/src/AzureTenant.js +6 -0
  20. package/{out → dist/esm}/src/NotSignedInError.js +4 -9
  21. package/{out → dist/esm}/src/VSCodeAzureSubscriptionProvider.d.ts +8 -13
  22. package/dist/esm/src/VSCodeAzureSubscriptionProvider.js +348 -0
  23. package/{out → dist/esm}/src/getSessionFromVSCode.d.ts +3 -3
  24. package/dist/esm/src/getSessionFromVSCode.js +72 -0
  25. package/{out → dist/esm}/src/index.d.ts +2 -1
  26. package/dist/esm/src/index.js +16 -0
  27. package/dist/esm/src/signInToTenant.js +43 -0
  28. package/dist/esm/src/utils/configuredAzureEnv.js +90 -0
  29. package/dist/esm/src/utils/getUnauthenticatedTenants.d.ts +9 -0
  30. package/dist/esm/src/utils/getUnauthenticatedTenants.js +20 -0
  31. package/dist/esm/src/utils/isAuthenticationWwwAuthenticateRequest.js +12 -0
  32. package/dist/esm/src/utils/isGetSubscriptionsFilter.d.ts +14 -0
  33. package/dist/esm/src/utils/isGetSubscriptionsFilter.js +23 -0
  34. package/package.json +13 -12
  35. package/out/src/AzureDevOpsSubscriptionProvider.js +0 -252
  36. package/out/src/VSCodeAzureSubscriptionProvider.js +0 -384
  37. package/out/src/getSessionFromVSCode.js +0 -76
  38. package/out/src/signInToTenant.js +0 -64
  39. package/out/src/utils/configuredAzureEnv.js +0 -94
  40. package/out/src/utils/getUnauthenticatedTenants.d.ts +0 -6
  41. package/out/src/utils/getUnauthenticatedTenants.js +0 -52
  42. /package/{out → dist/cjs}/src/AzureAuthentication.js +0 -0
  43. /package/{out → dist/cjs}/src/AzureSubscription.js +0 -0
  44. /package/{out → dist/cjs}/src/AzureSubscriptionProvider.js +0 -0
  45. /package/{out → dist/cjs}/src/AzureTenant.js +0 -0
  46. /package/{out → dist/cjs}/src/utils/isAuthenticationWwwAuthenticateRequest.js +0 -0
  47. /package/{out → dist/esm}/src/AzureSubscriptionProvider.d.ts +0 -0
  48. /package/{out → dist/esm}/src/NotSignedInError.d.ts +0 -0
  49. /package/{out → dist/esm}/src/signInToTenant.d.ts +0 -0
  50. /package/{out → dist/esm}/src/utils/configuredAzureEnv.d.ts +0 -0
  51. /package/{out → dist/esm}/src/utils/isAuthenticationWwwAuthenticateRequest.d.ts +0 -0
@@ -0,0 +1,90 @@
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 * as azureEnv from '@azure/ms-rest-azure-env'; // This package is so small that it's not worth lazy loading
6
+ import * as vscode from 'vscode';
7
+ // These strings come from https://github.com/microsoft/vscode/blob/eac16e9b63a11885b538db3e0b533a02a2fb8143/extensions/microsoft-authentication/package.json#L40-L99
8
+ const CustomCloudConfigurationSection = 'microsoft-sovereign-cloud';
9
+ const CloudEnvironmentSettingName = 'environment';
10
+ const CustomEnvironmentSettingName = 'customEnvironment';
11
+ var CloudEnvironmentSettingValue;
12
+ (function (CloudEnvironmentSettingValue) {
13
+ CloudEnvironmentSettingValue["ChinaCloud"] = "ChinaCloud";
14
+ CloudEnvironmentSettingValue["USGovernment"] = "USGovernment";
15
+ CloudEnvironmentSettingValue["Custom"] = "custom";
16
+ })(CloudEnvironmentSettingValue || (CloudEnvironmentSettingValue = {}));
17
+ /**
18
+ * Gets the configured Azure environment.
19
+ *
20
+ * @returns The configured Azure environment from the settings in the built-in authentication provider extension
21
+ */
22
+ export function getConfiguredAzureEnv() {
23
+ const authProviderConfig = vscode.workspace.getConfiguration(CustomCloudConfigurationSection);
24
+ const environmentSettingValue = authProviderConfig.get(CloudEnvironmentSettingName);
25
+ if (environmentSettingValue === CloudEnvironmentSettingValue.ChinaCloud) {
26
+ return {
27
+ ...azureEnv.Environment.ChinaCloud,
28
+ isCustomCloud: false,
29
+ };
30
+ }
31
+ else if (environmentSettingValue === CloudEnvironmentSettingValue.USGovernment) {
32
+ return {
33
+ ...azureEnv.Environment.USGovernment,
34
+ isCustomCloud: false,
35
+ };
36
+ }
37
+ else if (environmentSettingValue === CloudEnvironmentSettingValue.Custom) {
38
+ const customCloud = authProviderConfig.get(CustomEnvironmentSettingName);
39
+ if (customCloud) {
40
+ return {
41
+ ...new azureEnv.Environment(customCloud),
42
+ isCustomCloud: true,
43
+ };
44
+ }
45
+ throw new Error(vscode.l10n.t('The custom cloud choice is not configured. Please configure the setting `{0}.{1}`.', CustomCloudConfigurationSection, CustomEnvironmentSettingName));
46
+ }
47
+ return {
48
+ ...azureEnv.Environment.get(azureEnv.Environment.AzureCloud.name),
49
+ isCustomCloud: false,
50
+ };
51
+ }
52
+ /**
53
+ * Sets the configured Azure cloud.
54
+ *
55
+ * @param cloud Use `'AzureCloud'` or `undefined` for public Azure cloud, `'ChinaCloud'` for Azure China, or `'USGovernment'` for Azure US Government.
56
+ * 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}.
57
+ *
58
+ * @param target (Optional) The configuration target to use, by default {@link vscode.ConfigurationTarget.Global}.
59
+ */
60
+ export async function setConfiguredAzureEnv(cloud, target = vscode.ConfigurationTarget.Global) {
61
+ const authProviderConfig = vscode.workspace.getConfiguration(CustomCloudConfigurationSection);
62
+ if (typeof cloud === 'undefined' || !cloud) {
63
+ // Use public cloud implicitly--set `environment` setting to `undefined`
64
+ await authProviderConfig.update(CloudEnvironmentSettingName, undefined, target);
65
+ }
66
+ else if (typeof cloud === 'string' && cloud === 'AzureCloud') {
67
+ // Use public cloud explicitly--set `environment` setting to `undefined`
68
+ await authProviderConfig.update(CloudEnvironmentSettingName, undefined, target);
69
+ }
70
+ else if (typeof cloud === 'string') {
71
+ // Use a sovereign cloud--set the `environment` setting to the specified value
72
+ await authProviderConfig.update(CloudEnvironmentSettingName, cloud, target);
73
+ }
74
+ else if (typeof cloud === 'object') {
75
+ // use a custom cloud--set the `environment` setting to `custom` and the `customEnvironment` setting to the specified value
76
+ await authProviderConfig.update(CloudEnvironmentSettingName, CloudEnvironmentSettingValue.Custom, target);
77
+ await authProviderConfig.update(CustomEnvironmentSettingName, cloud, target);
78
+ }
79
+ else {
80
+ throw new Error(`Invalid cloud value: ${JSON.stringify(cloud)}`);
81
+ }
82
+ }
83
+ /**
84
+ * Gets the ID of the authentication provider configured to be used
85
+ * @returns The provider ID to use, either `'microsoft'` or `'microsoft-sovereign-cloud'`
86
+ */
87
+ export function getConfiguredAuthProviderId() {
88
+ return getConfiguredAzureEnv().name === azureEnv.Environment.AzureCloud.name ? 'microsoft' : 'microsoft-sovereign-cloud';
89
+ }
90
+ //# sourceMappingURL=configuredAzureEnv.js.map
@@ -0,0 +1,9 @@
1
+ import type * as vscode from "vscode";
2
+ import type { AzureSubscriptionProvider } from "../AzureSubscriptionProvider";
3
+ import type { AzureTenant } from "../AzureTenant";
4
+ /**
5
+ * @param subscriptionProvider The {@link AzureSubscriptionProvider} to use
6
+ * @param account (Optional) The account to get unauthenticated tenants for
7
+ * @returns list of tenants that VS Code doesn't have sessions for
8
+ */
9
+ export declare function getUnauthenticatedTenants(subscriptionProvider: AzureSubscriptionProvider, account?: vscode.AuthenticationSessionAccountInformation): Promise<AzureTenant[]>;
@@ -0,0 +1,20 @@
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
+ /**
6
+ * @param subscriptionProvider The {@link AzureSubscriptionProvider} to use
7
+ * @param account (Optional) The account to get unauthenticated tenants for
8
+ * @returns list of tenants that VS Code doesn't have sessions for
9
+ */
10
+ export async function getUnauthenticatedTenants(subscriptionProvider, account) {
11
+ const tenants = await subscriptionProvider.getTenants(account);
12
+ const unauthenticatedTenants = [];
13
+ for await (const tenant of tenants) {
14
+ if (!await subscriptionProvider.isSignedIn(tenant.tenantId, tenant.account)) {
15
+ unauthenticatedTenants.push(tenant);
16
+ }
17
+ }
18
+ return unauthenticatedTenants;
19
+ }
20
+ //# sourceMappingURL=getUnauthenticatedTenants.js.map
@@ -0,0 +1,12 @@
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
+ // Copied straight from https://github.com/microsoft/vscode/blob/32a309c4eceb1df1252215e36766ffb7e4e5afb3/src/vs/workbench/services/authentication/common/authentication.ts#L80-L85
6
+ export function isAuthenticationWwwAuthenticateRequest(obj) {
7
+ return typeof obj === 'object'
8
+ && obj !== null
9
+ && 'wwwAuthenticate' in obj
10
+ && (typeof obj.wwwAuthenticate === 'string');
11
+ }
12
+ //# sourceMappingURL=isAuthenticationWwwAuthenticateRequest.js.map
@@ -0,0 +1,14 @@
1
+ import type * as vscode from 'vscode';
2
+ import type { GetSubscriptionsFilter } from '../AzureSubscriptionProvider';
3
+ /**
4
+ * Check if an object is a {@link GetSubscriptionsFilter} with a tenantId.
5
+ */
6
+ export declare function isGetSubscriptionsTenantFilter(obj: unknown): obj is GetSubscriptionsFilter & {
7
+ tenantId: string;
8
+ };
9
+ /**
10
+ * Check if an object is a {@link GetSubscriptionsFilter} with an account.
11
+ */
12
+ export declare function isGetSubscriptionsAccountFilter(obj: unknown): obj is GetSubscriptionsFilter & {
13
+ account: vscode.AuthenticationSessionAccountInformation;
14
+ };
@@ -0,0 +1,23 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.md in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ /**
6
+ * Check if an object is a {@link GetSubscriptionsFilter} with a tenantId.
7
+ */
8
+ export function isGetSubscriptionsTenantFilter(obj) {
9
+ if (typeof obj === 'object' && !!obj && 'tenantId' in obj && typeof obj.tenantId === 'string' && !!obj.tenantId) {
10
+ return true;
11
+ }
12
+ return false;
13
+ }
14
+ /**
15
+ * Check if an object is a {@link GetSubscriptionsFilter} with an account.
16
+ */
17
+ export function isGetSubscriptionsAccountFilter(obj) {
18
+ if (typeof obj === 'object' && !!obj && 'account' in obj && typeof obj.account === 'object' && !!obj.account) {
19
+ return true;
20
+ }
21
+ return false;
22
+ }
23
+ //# sourceMappingURL=isGetSubscriptionsFilter.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@microsoft/vscode-azext-azureauth",
3
3
  "author": "Microsoft Corporation",
4
- "version": "4.2.2",
4
+ "version": "5.1.0",
5
5
  "description": "Azure authentication helpers for Visual Studio Code",
6
6
  "tags": [
7
7
  "azure",
@@ -11,8 +11,9 @@
11
11
  "azure",
12
12
  "vscode"
13
13
  ],
14
- "main": "out/src/index.js",
15
- "types": "out/src/index.d.ts",
14
+ "module": "dist/esm/src/index.js",
15
+ "main": "dist/cjs/src/index.js",
16
+ "types": "dist/esm/src/index.d.ts",
16
17
  "license": "MIT",
17
18
  "repository": {
18
19
  "type": "git",
@@ -23,26 +24,25 @@
23
24
  },
24
25
  "homepage": "https://github.com/Microsoft/vscode-azuretools/blob/main/auth/README.md",
25
26
  "scripts": {
26
- "build": "tsc -p ./",
27
- "compile": "tsc -watch -p ./",
27
+ "build": "npm run build:esm && npm run build:cjs",
28
+ "build:esm": "tsc -p ./",
29
+ "build:cjs": "tsc -p ./ --outDir ./dist/cjs --module nodenext --moduleResolution nodenext --declaration false",
28
30
  "lint": "eslint --ext .ts .",
29
31
  "lint-fix": "eslint --ext .ts . --fix",
30
- "test": "node ./out/test/runTest.js",
32
+ "test": "node ./dist/cjs/test/runTest.js",
31
33
  "package": "npm pack",
32
34
  "l10n": "npx @vscode/l10n-dev export --outDir ./l10n ./src"
33
35
  },
36
+ "engines": {
37
+ "vscode": "^1.105.0"
38
+ },
34
39
  "devDependencies": {
35
40
  "@azure/core-auth": "^1.4.0",
36
- "@azure/identity": "^4.2.0",
37
41
  "@microsoft/eslint-config-azuretools": "^0.2.1",
38
42
  "@types/glob": "^8.1.0",
39
- "@types/html-to-text": "^8.1.0",
40
43
  "@types/mocha": "^7.0.2",
41
44
  "@types/node": "^18.18.7",
42
- "@types/node-fetch": "2.6.7",
43
- "@types/semver": "^7.3.9",
44
- "@types/uuid": "^9.0.1",
45
- "@types/vscode": "^1.94.0",
45
+ "@types/vscode": "1.105.0",
46
46
  "@typescript-eslint/eslint-plugin": "^5.53.0",
47
47
  "@vscode/test-electron": "^2.3.8",
48
48
  "eslint": "^8.34.0",
@@ -57,6 +57,7 @@
57
57
  "@azure/arm-resources-subscriptions": "^2.1.0",
58
58
  "@azure/core-client": "^1.9.2",
59
59
  "@azure/core-rest-pipeline": "^1.16.0",
60
+ "@azure/identity": "^4.2.0",
60
61
  "@azure/ms-rest-azure-env": "^2.0.0"
61
62
  }
62
63
  }
@@ -1,252 +0,0 @@
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
7
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
8
- return new (P || (P = Promise))(function (resolve, reject) {
9
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
10
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
11
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
12
- step((generator = generator.apply(thisArg, _arguments || [])).next());
13
- });
14
- };
15
- var __asyncValues = (this && this.__asyncValues) || function (o) {
16
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
17
- var m = o[Symbol.asyncIterator], i;
18
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
19
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
20
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
21
- };
22
- Object.defineProperty(exports, "__esModule", { value: true });
23
- exports.AzureDevOpsSubscriptionProvider = void 0;
24
- exports.createAzureDevOpsSubscriptionProviderFactory = createAzureDevOpsSubscriptionProviderFactory;
25
- const vscode_1 = require("vscode");
26
- const configuredAzureEnv_1 = require("./utils/configuredAzureEnv");
27
- let azureDevOpsSubscriptionProvider;
28
- function createAzureDevOpsSubscriptionProviderFactory(initializer) {
29
- return () => __awaiter(this, void 0, void 0, function* () {
30
- azureDevOpsSubscriptionProvider !== null && azureDevOpsSubscriptionProvider !== void 0 ? azureDevOpsSubscriptionProvider : (azureDevOpsSubscriptionProvider = new AzureDevOpsSubscriptionProvider(initializer));
31
- return azureDevOpsSubscriptionProvider;
32
- });
33
- }
34
- /**
35
- * AzureSubscriptionProvider implemented to authenticate via federated DevOps service connection, using workflow identity federation
36
- * To learn how to configure your DevOps environment to use this provider, refer to the README.md
37
- * NOTE: This provider is only available when running in an Azure DevOps pipeline
38
- * Reference: https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation
39
- */
40
- class AzureDevOpsSubscriptionProvider {
41
- constructor({ serviceConnectionId, domain, clientId }) {
42
- this.onDidSignIn = () => { return new vscode_1.Disposable(() => { }); };
43
- this.onDidSignOut = () => { return new vscode_1.Disposable(() => { }); };
44
- if (!serviceConnectionId || !domain || !clientId) {
45
- throw new Error(`Missing initializer values to identify Azure DevOps federated service connection\n
46
- Values provided:\n
47
- serviceConnectionId: ${serviceConnectionId ? "✅" : "❌"}\n
48
- domain: ${domain ? "✅" : "❌"}\n
49
- clientId: ${clientId ? "✅" : "❌"}\n
50
- `);
51
- }
52
- this._SERVICE_CONNECTION_ID = serviceConnectionId;
53
- this._DOMAIN = domain;
54
- this._CLIENT_ID = clientId;
55
- }
56
- getSubscriptions(_filter) {
57
- return __awaiter(this, void 0, void 0, function* () {
58
- // ignore the filter setting because not every consumer of this provider will use the Resources extension
59
- const results = [];
60
- for (const tenant of yield this.getTenants()) {
61
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
62
- const tenantId = tenant.tenantId;
63
- results.push(...yield this.getSubscriptionsForTenant(tenantId));
64
- }
65
- const sortSubscriptions = (subscriptions) => subscriptions.sort((a, b) => a.name.localeCompare(b.name));
66
- return sortSubscriptions(results);
67
- });
68
- }
69
- isSignedIn() {
70
- return __awaiter(this, void 0, void 0, function* () {
71
- return !!this._tokenCredential;
72
- });
73
- }
74
- signIn() {
75
- return __awaiter(this, void 0, void 0, function* () {
76
- this._tokenCredential = yield getTokenCredential(this._SERVICE_CONNECTION_ID, this._DOMAIN, this._CLIENT_ID);
77
- return !!this._tokenCredential;
78
- });
79
- }
80
- signOut() {
81
- return __awaiter(this, void 0, void 0, function* () {
82
- this._tokenCredential = undefined;
83
- });
84
- }
85
- getTenants() {
86
- return __awaiter(this, void 0, void 0, function* () {
87
- var _a;
88
- return [{
89
- tenantId: (_a = this._tokenCredential) === null || _a === void 0 ? void 0 : _a.tenantId,
90
- account: {
91
- id: "test-account-id",
92
- label: "test-account",
93
- }
94
- }];
95
- });
96
- }
97
- /**
98
- * Gets the subscriptions for a given tenant.
99
- *
100
- * @param tenantId The tenant ID to get subscriptions for.
101
- *
102
- * @returns The list of subscriptions for the tenant.
103
- */
104
- getSubscriptionsForTenant(tenantId) {
105
- return __awaiter(this, void 0, void 0, function* () {
106
- var _a, e_1, _b, _c;
107
- const { client, credential, authentication } = yield this.getSubscriptionClient(tenantId);
108
- const environment = (0, configuredAzureEnv_1.getConfiguredAzureEnv)();
109
- const subscriptions = [];
110
- try {
111
- for (var _d = true, _e = __asyncValues(client.subscriptions.list()), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
112
- _c = _f.value;
113
- _d = false;
114
- const subscription = _c;
115
- subscriptions.push({
116
- authentication,
117
- environment: environment,
118
- credential: credential,
119
- isCustomCloud: environment.isCustomCloud,
120
- /* eslint-disable @typescript-eslint/no-non-null-assertion */
121
- name: subscription.displayName,
122
- subscriptionId: subscription.subscriptionId,
123
- /* eslint-enable @typescript-eslint/no-non-null-assertion */
124
- tenantId,
125
- account: {
126
- id: "test-account-id",
127
- label: "test-account",
128
- },
129
- });
130
- }
131
- }
132
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
133
- finally {
134
- try {
135
- if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
136
- }
137
- finally { if (e_1) throw e_1.error; }
138
- }
139
- return subscriptions;
140
- });
141
- }
142
- /**
143
- * Gets a fully-configured subscription client for a given tenant ID
144
- *
145
- * @param tenantId (Optional) The tenant ID to get a client for
146
- *
147
- * @returns A client, the credential used by the client, and the authentication function
148
- */
149
- getSubscriptionClient(_tenantId, scopes) {
150
- return __awaiter(this, void 0, void 0, function* () {
151
- var _a, _b;
152
- const armSubs = yield Promise.resolve().then(() => require('@azure/arm-resources-subscriptions'));
153
- if (!this._tokenCredential) {
154
- throw new Error('Not signed in');
155
- }
156
- const accessToken = ((_b = (yield ((_a = this._tokenCredential) === null || _a === void 0 ? void 0 : _a.getToken("https://management.azure.com/.default")))) === null || _b === void 0 ? void 0 : _b.token) || '';
157
- const getSession = () => {
158
- var _a, _b, _c, _d;
159
- return {
160
- accessToken,
161
- id: ((_a = this._tokenCredential) === null || _a === void 0 ? void 0 : _a.tenantId) || '',
162
- account: {
163
- id: ((_b = this._tokenCredential) === null || _b === void 0 ? void 0 : _b.tenantId) || '',
164
- label: ((_c = this._tokenCredential) === null || _c === void 0 ? void 0 : _c.tenantId) || '',
165
- },
166
- tenantId: ((_d = this._tokenCredential) === null || _d === void 0 ? void 0 : _d.tenantId) || '',
167
- scopes: scopes || [],
168
- };
169
- };
170
- return {
171
- client: new armSubs.SubscriptionClient(this._tokenCredential),
172
- credential: this._tokenCredential,
173
- authentication: {
174
- getSession,
175
- getSessionWithScopes: getSession,
176
- }
177
- };
178
- });
179
- }
180
- }
181
- exports.AzureDevOpsSubscriptionProvider = AzureDevOpsSubscriptionProvider;
182
- /*
183
- * @param serviceConnectionId The resource ID of the Azure DevOps federated service connection,
184
- * 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
185
- * @param domain The `Tenant ID` field of the service connection properties
186
- * @param clientId The `Service Principal Id` field of the service connection properties
187
- */
188
- function getTokenCredential(serviceConnectionId, domain, clientId) {
189
- return __awaiter(this, void 0, void 0, function* () {
190
- if (!process.env.AGENT_BUILDDIRECTORY) {
191
- // Assume that AGENT_BUILDDIRECTORY is set if running in an Azure DevOps pipeline.
192
- // So when not running in an Azure DevOps pipeline, throw an error since we cannot use the DevOps federated service connection credential.
193
- throw new Error(`Cannot create DevOps federated service connection credential outside of an Azure DevOps pipeline.`);
194
- }
195
- else {
196
- console.log(`Creating DevOps federated service connection credential for service connection..`);
197
- // Pre-defined DevOps variable reference: https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops
198
- const systemAccessToken = process.env.SYSTEM_ACCESSTOKEN;
199
- const teamFoundationCollectionUri = process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI;
200
- const teamProjectId = process.env.SYSTEM_TEAMPROJECTID;
201
- const planId = process.env.SYSTEM_PLANID;
202
- const jobId = process.env.SYSTEM_JOBID;
203
- if (!systemAccessToken || !teamFoundationCollectionUri || !teamProjectId || !planId || !jobId) {
204
- throw new Error(`Azure DevOps environment variables are not set.\n
205
- process.env.SYSTEM_ACCESSTOKEN: ${process.env.SYSTEM_ACCESSTOKEN ? "✅" : "❌"}\n
206
- process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI: ${process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI ? "✅" : "❌"}\n
207
- process.env.SYSTEM_TEAMPROJECTID: ${process.env.SYSTEM_TEAMPROJECTID ? "✅" : "❌"}\n
208
- process.env.SYSTEM_PLANID: ${process.env.SYSTEM_PLANID ? "✅" : "❌"}\n
209
- process.env.SYSTEM_JOBID: ${process.env.SYSTEM_JOBID ? "✅" : "❌"}\n
210
- REMEMBER: process.env.SYSTEM_ACCESSTOKEN must be explicitly mapped!\n
211
- https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#systemaccesstoken
212
- `);
213
- }
214
- const oidcRequestUrl = `${teamFoundationCollectionUri}${teamProjectId}/_apis/distributedtask/hubs/build/plans/${planId}/jobs/${jobId}/oidctoken?api-version=7.1-preview.1&serviceConnectionId=${serviceConnectionId}`;
215
- const { ClientAssertionCredential } = yield Promise.resolve().then(() => require("@azure/identity"));
216
- return new ClientAssertionCredential(domain, clientId, () => __awaiter(this, void 0, void 0, function* () { return yield requestOidcToken(oidcRequestUrl, systemAccessToken); }));
217
- }
218
- });
219
- }
220
- /**
221
- * API reference: https://learn.microsoft.com/en-us/rest/api/azure/devops/distributedtask/oidctoken/create
222
- */
223
- function requestOidcToken(oidcRequestUrl, systemAccessToken) {
224
- return __awaiter(this, void 0, void 0, function* () {
225
- var _a;
226
- const { ServiceClient } = yield Promise.resolve().then(() => require('@azure/core-client'));
227
- const { createHttpHeaders, createPipelineRequest } = yield Promise.resolve().then(() => require('@azure/core-rest-pipeline'));
228
- const genericClient = new ServiceClient();
229
- const request = createPipelineRequest({
230
- url: oidcRequestUrl,
231
- method: "POST",
232
- headers: createHttpHeaders({
233
- "Content-Type": "application/json",
234
- "Authorization": `Bearer ${systemAccessToken}`
235
- })
236
- });
237
- const response = yield genericClient.sendRequest(request);
238
- const body = ((_a = response.bodyAsText) === null || _a === void 0 ? void 0 : _a.toString()) || "";
239
- if (response.status !== 200) {
240
- throw new Error(`Failed to get OIDC token:\n
241
- Response status: ${response.status}\n
242
- Response body: ${body}\n
243
- Response headers: ${JSON.stringify(response.headers.toJSON())}
244
- `);
245
- }
246
- else {
247
- console.log(`Successfully got OIDC token with status ${response.status}`);
248
- }
249
- return JSON.parse(body).oidcToken;
250
- });
251
- }
252
- //# sourceMappingURL=AzureDevOpsSubscriptionProvider.js.map