@adinsure-ops/ops-cli 5.2.1 → 5.3.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/README.md +123 -9
- package/lib/commands/config/get.d.ts +11 -0
- package/lib/commands/config/get.js +40 -0
- package/lib/commands/config/list.d.ts +8 -0
- package/lib/commands/config/list.js +26 -0
- package/lib/commands/config/set.d.ts +12 -0
- package/lib/commands/config/set.js +60 -0
- package/lib/commands/config/unset.d.ts +11 -0
- package/lib/commands/config/unset.js +42 -0
- package/lib/commands/download/client.d.ts +11 -3
- package/lib/commands/download/client.js +52 -8
- package/lib/commands/download/identity-server.d.ts +11 -3
- package/lib/commands/download/identity-server.js +53 -8
- package/lib/commands/download/jmeter.d.ts +1 -1
- package/lib/commands/download/jmeter.js +13 -3
- package/lib/commands/download/keycloak-scim.d.ts +1 -1
- package/lib/commands/download/keycloak-scim.js +13 -3
- package/lib/commands/download/platform.d.ts +11 -3
- package/lib/commands/download/platform.js +53 -8
- package/lib/commands/download/scheduler.d.ts +11 -3
- package/lib/commands/download/scheduler.js +52 -8
- package/lib/commands/download/server.d.ts +11 -3
- package/lib/commands/download/server.js +53 -9
- package/lib/commands/download/signalr.d.ts +11 -3
- package/lib/commands/download/signalr.js +52 -8
- package/lib/commands/download/studio.d.ts +11 -3
- package/lib/commands/download/studio.js +52 -8
- package/lib/commands/login.d.ts +9 -0
- package/lib/commands/login.js +60 -1
- package/lib/commands/login.ru.d.ts +12 -0
- package/lib/commands/login.ru.js +42 -0
- package/lib/commands/npm/check-publish.js +1 -1
- package/lib/lib/config.d.ts +10 -0
- package/lib/lib/config.js +33 -0
- package/lib/lib/yarnrc.d.ts +22 -0
- package/lib/lib/yarnrc.js +40 -0
- package/lib/security/context.d.ts +22 -0
- package/lib/security/context.js +113 -0
- package/oclif.manifest.json +415 -152
- package/package.json +1 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export default class YarnRc {
|
|
2
|
+
private readonly filePath;
|
|
3
|
+
private config;
|
|
4
|
+
constructor(createIfNotExists?: boolean);
|
|
5
|
+
/**
|
|
6
|
+
* Load config file
|
|
7
|
+
* @returns {void}
|
|
8
|
+
*/
|
|
9
|
+
load(): void;
|
|
10
|
+
/**
|
|
11
|
+
* Add registry to config file
|
|
12
|
+
* @param key Config key
|
|
13
|
+
* @param value Config value
|
|
14
|
+
* @returns {void}
|
|
15
|
+
*/
|
|
16
|
+
set(key: string, value: string): void;
|
|
17
|
+
/**
|
|
18
|
+
* Set token for Registry
|
|
19
|
+
* @returns {void}
|
|
20
|
+
*/
|
|
21
|
+
save(): void;
|
|
22
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import os from "os";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import yaml from "yaml";
|
|
5
|
+
export default class YarnRc {
|
|
6
|
+
constructor(createIfNotExists = true) {
|
|
7
|
+
this.config = {};
|
|
8
|
+
this.filePath = path.resolve(os.homedir(), `.yarnrc.yml`);
|
|
9
|
+
if (!fs.existsSync(this.filePath) && createIfNotExists) {
|
|
10
|
+
fs.writeFileSync(this.filePath, JSON.stringify({}));
|
|
11
|
+
}
|
|
12
|
+
if (fs.existsSync(this.filePath) &&
|
|
13
|
+
fs.lstatSync(this.filePath).isFile()) {
|
|
14
|
+
this.load();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Load config file
|
|
19
|
+
* @returns {void}
|
|
20
|
+
*/
|
|
21
|
+
load() {
|
|
22
|
+
this.config = yaml.parse(fs.readFileSync(this.filePath, "utf8"));
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Add registry to config file
|
|
26
|
+
* @param key Config key
|
|
27
|
+
* @param value Config value
|
|
28
|
+
* @returns {void}
|
|
29
|
+
*/
|
|
30
|
+
set(key, value) {
|
|
31
|
+
this.config[key] = value;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Set token for Registry
|
|
35
|
+
* @returns {void}
|
|
36
|
+
*/
|
|
37
|
+
save() {
|
|
38
|
+
fs.writeFileSync(this.filePath, yaml.stringify(this.config));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -7,11 +7,16 @@ import { ParsedUrlQuery } from 'querystring';
|
|
|
7
7
|
export default class SecurityContext {
|
|
8
8
|
private readonly clientId;
|
|
9
9
|
private readonly devopsResourceId;
|
|
10
|
+
private readonly managementCoreWindowsNet;
|
|
10
11
|
private readonly tenant;
|
|
12
|
+
private readonly tenantId;
|
|
13
|
+
private readonly registry;
|
|
11
14
|
private readonly authorityUrl;
|
|
12
15
|
private readonly redirectUri;
|
|
13
16
|
private readonly resource;
|
|
14
17
|
private readonly _accessTokenPath;
|
|
18
|
+
private readonly _accessTokenRuPath;
|
|
19
|
+
private readonly _accessConfigPath;
|
|
15
20
|
private readonly _pca;
|
|
16
21
|
private readonly _cryptoProvider;
|
|
17
22
|
private _verifier;
|
|
@@ -26,6 +31,16 @@ export default class SecurityContext {
|
|
|
26
31
|
* @returns {string} Returns access token path
|
|
27
32
|
*/
|
|
28
33
|
getTokenPath(): string;
|
|
34
|
+
/**
|
|
35
|
+
* Get the accessTokenRuPath, as it is a private variable
|
|
36
|
+
* @returns {string} Returns access token Ru path
|
|
37
|
+
*/
|
|
38
|
+
getTokenRuPath(): string;
|
|
39
|
+
/**
|
|
40
|
+
* Get the accessConfigPath, as it is a private variable
|
|
41
|
+
* @returns {string} Returns config.json path
|
|
42
|
+
*/
|
|
43
|
+
getConfigPath(): string;
|
|
29
44
|
/**
|
|
30
45
|
* Contacts authority server, fetches and saves the authentication token to be used in subsequent requests.
|
|
31
46
|
*
|
|
@@ -58,6 +73,13 @@ export default class SecurityContext {
|
|
|
58
73
|
* @returns Promise that resolves bearer authentication token
|
|
59
74
|
*/
|
|
60
75
|
getToken(): Promise<string>;
|
|
76
|
+
/**
|
|
77
|
+
* Fetches the locally stored token for GitlabRu
|
|
78
|
+
* @returns authentication token for gitlabru.adacta-fintech.ru
|
|
79
|
+
*/
|
|
80
|
+
getTokenRu(): string;
|
|
81
|
+
getAADToken(): Promise<string>;
|
|
82
|
+
getACRToken(): Promise<string>;
|
|
61
83
|
/**
|
|
62
84
|
* Contacts authority server, fetches and saves the authentication token to be used in subsequent requests.
|
|
63
85
|
*
|
package/lib/security/context.js
CHANGED
|
@@ -2,7 +2,10 @@ import { __awaiter } from "tslib";
|
|
|
2
2
|
import { AuthError, ConfidentialClientApplication, CryptoProvider, InteractionRequiredAuthError, PublicClientApplication, } from '@azure/msal-node';
|
|
3
3
|
import { reject } from 'lodash-es';
|
|
4
4
|
import path from 'path';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import querystring from 'querystring';
|
|
5
7
|
import LocalCachePlugin from './cache.js';
|
|
8
|
+
import axios from 'axios';
|
|
6
9
|
/**
|
|
7
10
|
* Security context that keeps track of current authentication token.
|
|
8
11
|
* It's not recommended you instantiate this class on your own but rather inherit your commands from [[CommandBase]].
|
|
@@ -15,13 +18,18 @@ export default class SecurityContext {
|
|
|
15
18
|
constructor(configDir) {
|
|
16
19
|
this.clientId = 'bed40d09-53d7-4af8-bf63-3288658b65fb';
|
|
17
20
|
this.devopsResourceId = '499b84ac-1321-427f-aa17-267ca6975798';
|
|
21
|
+
this.managementCoreWindowsNet = 'https://management.core.windows.net//';
|
|
18
22
|
this.tenant = 'adfintech.onmicrosoft.com';
|
|
23
|
+
this.tenantId = 'cdeb9156-219a-49e3-b414-f63acd298e9c';
|
|
24
|
+
this.registry = 'adinsure.azurecr.io';
|
|
19
25
|
this.authorityUrl = `https://login.microsoftonline.com/${this.tenant}/`;
|
|
20
26
|
this.redirectUri = 'http://localhost:3044';
|
|
21
27
|
this.resource = 'https://ops.adinsure.com';
|
|
22
28
|
this._verifier = null;
|
|
23
29
|
this._challenge = null;
|
|
24
30
|
this._accessTokenPath = path.resolve(configDir, 'accessToken.json');
|
|
31
|
+
this._accessTokenRuPath = path.resolve(configDir, 'accessTokenRu.json');
|
|
32
|
+
this._accessConfigPath = path.resolve(configDir, 'config.json');
|
|
25
33
|
this._cryptoProvider = new CryptoProvider();
|
|
26
34
|
this._pca = new PublicClientApplication({
|
|
27
35
|
auth: {
|
|
@@ -40,6 +48,20 @@ export default class SecurityContext {
|
|
|
40
48
|
getTokenPath() {
|
|
41
49
|
return this._accessTokenPath;
|
|
42
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Get the accessTokenRuPath, as it is a private variable
|
|
53
|
+
* @returns {string} Returns access token Ru path
|
|
54
|
+
*/
|
|
55
|
+
getTokenRuPath() {
|
|
56
|
+
return this._accessTokenRuPath;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get the accessConfigPath, as it is a private variable
|
|
60
|
+
* @returns {string} Returns config.json path
|
|
61
|
+
*/
|
|
62
|
+
getConfigPath() {
|
|
63
|
+
return this._accessConfigPath;
|
|
64
|
+
}
|
|
43
65
|
/**
|
|
44
66
|
* Contacts authority server, fetches and saves the authentication token to be used in subsequent requests.
|
|
45
67
|
*
|
|
@@ -202,6 +224,97 @@ export default class SecurityContext {
|
|
|
202
224
|
}));
|
|
203
225
|
});
|
|
204
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Fetches the locally stored token for GitlabRu
|
|
229
|
+
* @returns authentication token for gitlabru.adacta-fintech.ru
|
|
230
|
+
*/
|
|
231
|
+
getTokenRu() {
|
|
232
|
+
try {
|
|
233
|
+
const fileContent = fs.readFileSync(this._accessTokenRuPath, 'utf8').trim();
|
|
234
|
+
if (!fileContent) {
|
|
235
|
+
throw new Error('Token file is empty.');
|
|
236
|
+
}
|
|
237
|
+
const tokenData = JSON.parse(fileContent);
|
|
238
|
+
if (!tokenData.accessTokenRu) {
|
|
239
|
+
throw new Error('GitLabRu token not found in file.');
|
|
240
|
+
}
|
|
241
|
+
return tokenData.accessTokenRu;
|
|
242
|
+
//eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
243
|
+
}
|
|
244
|
+
catch (err) {
|
|
245
|
+
throw new Error(`Failed to retrieve GitLabRu token: ${err.message}`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
getAADToken() {
|
|
249
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
250
|
+
const msalTokenCache = this._pca.getTokenCache();
|
|
251
|
+
const cachedAccounts = yield msalTokenCache.getAllAccounts();
|
|
252
|
+
return new Promise((resolve, reject) => {
|
|
253
|
+
if (cachedAccounts.length > 0) {
|
|
254
|
+
this._pca
|
|
255
|
+
.acquireTokenSilent({
|
|
256
|
+
account: cachedAccounts[0],
|
|
257
|
+
scopes: [
|
|
258
|
+
this.managementCoreWindowsNet + '.default',
|
|
259
|
+
'offline_access',
|
|
260
|
+
],
|
|
261
|
+
})
|
|
262
|
+
.then((response) => {
|
|
263
|
+
if (response) {
|
|
264
|
+
resolve(response.accessToken);
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
reject(new Error('Error getting token, please call `ops login`.'));
|
|
268
|
+
}
|
|
269
|
+
})
|
|
270
|
+
.catch((error) => {
|
|
271
|
+
reject(new Error(error));
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
reject();
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
getACRToken() {
|
|
281
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
282
|
+
try {
|
|
283
|
+
// First, retrieve the AAD token using your existing method.
|
|
284
|
+
const aadAccessToken = yield this.getAADToken();
|
|
285
|
+
// Build the form data as per the ACR token exchange API:
|
|
286
|
+
// grant_type=access_token
|
|
287
|
+
// service=<registry>
|
|
288
|
+
// tenant=<tenantId>
|
|
289
|
+
// access_token=<aadAccessToken>
|
|
290
|
+
const postData = querystring.stringify({
|
|
291
|
+
grant_type: 'access_token',
|
|
292
|
+
service: this.registry, // e.g., "adinsure.azurecr.io"
|
|
293
|
+
tenant: this.tenantId, // e.g., "cdeb9156-219a-49e3-b414-f63acd298e9c"
|
|
294
|
+
access_token: aadAccessToken,
|
|
295
|
+
});
|
|
296
|
+
// Define the URL for token exchange:
|
|
297
|
+
const url = `https://${this.registry}/oauth2/exchange`;
|
|
298
|
+
// Make the POST request with the appropriate headers.
|
|
299
|
+
const response = yield axios.post(url, postData, {
|
|
300
|
+
headers: {
|
|
301
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
// The ACR token should be in the "access_token" field of the response.
|
|
305
|
+
if (response.data && response.data.refresh_token) {
|
|
306
|
+
return response.data.refresh_token;
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
throw new Error('ACR token not found in the response.');
|
|
310
|
+
}
|
|
311
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
throw new Error('Failed to retrieve ACR token: ' + error.message);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
}
|
|
205
318
|
/**
|
|
206
319
|
* Contacts authority server, fetches and saves the authentication token to be used in subsequent requests.
|
|
207
320
|
*
|