@sasjs/cli 4.18.5 → 4.19.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/build/commands/add/spec/addCommand.spec.js +0 -21
- package/build/commands/auth/authCommand.d.ts +9 -0
- package/build/commands/auth/authCommand.js +181 -0
- package/build/commands/auth/login.d.ts +16 -0
- package/build/commands/auth/login.js +130 -0
- package/build/commands/auth/spec/authCommand.spec.d.ts +1 -0
- package/build/commands/auth/spec/authCommand.spec.js +207 -0
- package/build/commands/auth/spec/login.spec.d.ts +1 -0
- package/build/commands/auth/spec/login.spec.js +364 -0
- package/build/commands/build/build.js +9 -2
- package/build/commands/build/spec/build.spec.js +3 -0
- package/build/commands/deploy/internal/executeDeployScriptSasViya.js +2 -1
- package/build/commands/fs/internal/executeCode.js +2 -1
- package/build/commands/help/help.js +3 -2
- package/build/commands/run/run.js +2 -1
- package/build/types/command/commandAliases.js +0 -1
- package/build/types/command/commandBase.js +1 -0
- package/build/types/command/commandFactory.js +2 -0
- package/build/utils/auth.d.ts +35 -16
- package/build/utils/auth.js +97 -37
- package/build/utils/config.d.ts +13 -2
- package/build/utils/config.js +125 -55
- package/build/utils/spec/auth.spec.d.ts +1 -0
- package/build/utils/spec/auth.spec.js +255 -0
- package/build/utils/spec/config.spec.js +334 -32
- package/package.json +4 -3
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
2
13
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
14
|
if (k2 === undefined) k2 = k;
|
|
4
15
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -64,12 +75,27 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
64
75
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
65
76
|
var config_1 = require("../config");
|
|
66
77
|
var authUtils = __importStar(require("../auth"));
|
|
78
|
+
var sasjsAuthUtils = __importStar(require("@sasjs/utils/auth"));
|
|
67
79
|
var fileUtils = __importStar(require("@sasjs/utils/file"));
|
|
68
80
|
var dotenv_1 = __importDefault(require("dotenv"));
|
|
69
81
|
var path_1 = __importDefault(require("path"));
|
|
70
82
|
var utils_1 = require("@sasjs/utils");
|
|
83
|
+
var file_1 = require("@sasjs/utils/file");
|
|
71
84
|
var test_1 = require("../test");
|
|
72
85
|
var setConstants_1 = require("../setConstants");
|
|
86
|
+
// The compiled @sasjs/utils/auth module exposes getters that jest.spyOn
|
|
87
|
+
// cannot redefine - mock the module with configurable jest.fn()s that
|
|
88
|
+
// default to the real implementations.
|
|
89
|
+
jest.mock('@sasjs/utils/auth', function () {
|
|
90
|
+
var actual = jest.requireActual('@sasjs/utils/auth');
|
|
91
|
+
return __assign(__assign({}, actual), { isAccessTokenExpiring: jest.fn(), isRefreshTokenExpiring: jest.fn() });
|
|
92
|
+
});
|
|
93
|
+
var actualAuthUtils = jest.requireActual('@sasjs/utils/auth');
|
|
94
|
+
beforeEach(function () {
|
|
95
|
+
;
|
|
96
|
+
sasjsAuthUtils.isAccessTokenExpiring.mockImplementation(actualAuthUtils.isAccessTokenExpiring);
|
|
97
|
+
sasjsAuthUtils.isRefreshTokenExpiring.mockImplementation(actualAuthUtils.isRefreshTokenExpiring);
|
|
98
|
+
});
|
|
73
99
|
describe('getAccessToken', function () {
|
|
74
100
|
beforeEach(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
75
101
|
return __generator(this, function (_a) {
|
|
@@ -189,12 +215,9 @@ describe('getAccessToken', function () {
|
|
|
189
215
|
return __generator(this, function (_a) {
|
|
190
216
|
switch (_a.label) {
|
|
191
217
|
case 0:
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
jest
|
|
196
|
-
.spyOn(authUtils, 'isRefreshTokenExpiring')
|
|
197
|
-
.mockImplementation(function () { return false; });
|
|
218
|
+
;
|
|
219
|
+
sasjsAuthUtils.isAccessTokenExpiring.mockImplementation(function () { return true; });
|
|
220
|
+
sasjsAuthUtils.isRefreshTokenExpiring.mockImplementation(function () { return false; });
|
|
198
221
|
jest.spyOn(authUtils, 'getNewAccessToken');
|
|
199
222
|
jest.spyOn(authUtils, 'refreshTokens').mockImplementation(function () {
|
|
200
223
|
return Promise.resolve({
|
|
@@ -212,8 +235,8 @@ describe('getAccessToken', function () {
|
|
|
212
235
|
return [4 /*yield*/, (0, config_1.getAccessToken)(target, true)];
|
|
213
236
|
case 1:
|
|
214
237
|
token = _a.sent();
|
|
215
|
-
expect(
|
|
216
|
-
expect(
|
|
238
|
+
expect(sasjsAuthUtils.isAccessTokenExpiring).toHaveBeenCalledTimes(1);
|
|
239
|
+
expect(sasjsAuthUtils.isRefreshTokenExpiring).toHaveBeenCalledTimes(1);
|
|
217
240
|
expect(authUtils.refreshTokens).toHaveBeenCalledTimes(1);
|
|
218
241
|
expect(authUtils.getNewAccessToken).not.toHaveBeenCalled();
|
|
219
242
|
expect(token).toEqual('N3WT0K3N');
|
|
@@ -226,12 +249,9 @@ describe('getAccessToken', function () {
|
|
|
226
249
|
return __generator(this, function (_a) {
|
|
227
250
|
switch (_a.label) {
|
|
228
251
|
case 0:
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
jest
|
|
233
|
-
.spyOn(authUtils, 'isRefreshTokenExpiring')
|
|
234
|
-
.mockImplementation(function () { return true; });
|
|
252
|
+
;
|
|
253
|
+
sasjsAuthUtils.isAccessTokenExpiring.mockImplementation(function () { return true; });
|
|
254
|
+
sasjsAuthUtils.isRefreshTokenExpiring.mockImplementation(function () { return true; });
|
|
235
255
|
jest.spyOn(authUtils, 'refreshTokens');
|
|
236
256
|
jest.spyOn(authUtils, 'getNewAccessToken').mockImplementation(function () {
|
|
237
257
|
return Promise.resolve({
|
|
@@ -250,8 +270,8 @@ describe('getAccessToken', function () {
|
|
|
250
270
|
return [4 /*yield*/, (0, config_1.getAccessToken)(target, true)];
|
|
251
271
|
case 1:
|
|
252
272
|
token = _a.sent();
|
|
253
|
-
expect(
|
|
254
|
-
expect(
|
|
273
|
+
expect(sasjsAuthUtils.isAccessTokenExpiring).toHaveBeenCalledTimes(1);
|
|
274
|
+
expect(sasjsAuthUtils.isRefreshTokenExpiring).toHaveBeenCalledTimes(1);
|
|
255
275
|
expect(authUtils.refreshTokens).not.toHaveBeenCalled();
|
|
256
276
|
expect(authUtils.getNewAccessToken).toHaveBeenCalledTimes(1);
|
|
257
277
|
expect(token).toEqual('N3WT0K3N');
|
|
@@ -264,12 +284,9 @@ describe('getAccessToken', function () {
|
|
|
264
284
|
return __generator(this, function (_a) {
|
|
265
285
|
switch (_a.label) {
|
|
266
286
|
case 0:
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
jest
|
|
271
|
-
.spyOn(authUtils, 'isRefreshTokenExpiring')
|
|
272
|
-
.mockImplementation(function () { return true; });
|
|
287
|
+
;
|
|
288
|
+
sasjsAuthUtils.isAccessTokenExpiring.mockImplementation(function () { return true; });
|
|
289
|
+
sasjsAuthUtils.isRefreshTokenExpiring.mockImplementation(function () { return true; });
|
|
273
290
|
jest.spyOn(authUtils, 'refreshTokens');
|
|
274
291
|
jest.spyOn(authUtils, 'getNewAccessToken').mockImplementation(function () {
|
|
275
292
|
return Promise.resolve({
|
|
@@ -287,8 +304,8 @@ describe('getAccessToken', function () {
|
|
|
287
304
|
return [4 /*yield*/, (0, config_1.getAccessToken)(target, true)];
|
|
288
305
|
case 1:
|
|
289
306
|
token = _a.sent();
|
|
290
|
-
expect(
|
|
291
|
-
expect(
|
|
307
|
+
expect(sasjsAuthUtils.isAccessTokenExpiring).toHaveBeenCalledTimes(1);
|
|
308
|
+
expect(sasjsAuthUtils.isRefreshTokenExpiring).toHaveBeenCalledTimes(1);
|
|
292
309
|
expect(authUtils.refreshTokens).not.toHaveBeenCalled();
|
|
293
310
|
expect(authUtils.getNewAccessToken).toHaveBeenCalledTimes(1);
|
|
294
311
|
expect(token).toEqual('N3WT0K3N');
|
|
@@ -301,17 +318,17 @@ describe('getAccessToken', function () {
|
|
|
301
318
|
return __generator(this, function (_a) {
|
|
302
319
|
switch (_a.label) {
|
|
303
320
|
case 0:
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
.mockImplementation(function () { return true; });
|
|
321
|
+
;
|
|
322
|
+
sasjsAuthUtils.isAccessTokenExpiring.mockImplementation(function () { return true; });
|
|
307
323
|
target = {
|
|
324
|
+
name: 'viya',
|
|
308
325
|
authConfig: {
|
|
309
326
|
access_token: 'T0K3N',
|
|
310
327
|
secret: '53CR3T'
|
|
311
328
|
}
|
|
312
329
|
};
|
|
313
330
|
process.env.CLIENT = undefined;
|
|
314
|
-
return [4 /*yield*/, expect((0, config_1.getAccessToken)(target)).rejects.toThrow()];
|
|
331
|
+
return [4 /*yield*/, expect((0, config_1.getAccessToken)(target)).rejects.toThrow(/sasjs auth login -t viya/)];
|
|
315
332
|
case 1:
|
|
316
333
|
_a.sent();
|
|
317
334
|
return [2 /*return*/];
|
|
@@ -323,17 +340,98 @@ describe('getAccessToken', function () {
|
|
|
323
340
|
return __generator(this, function (_a) {
|
|
324
341
|
switch (_a.label) {
|
|
325
342
|
case 0:
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
.mockImplementation(function () { return true; });
|
|
343
|
+
;
|
|
344
|
+
sasjsAuthUtils.isAccessTokenExpiring.mockImplementation(function () { return true; });
|
|
329
345
|
target = {
|
|
346
|
+
name: 'viya',
|
|
330
347
|
authConfig: {
|
|
331
348
|
access_token: 'T0K3N',
|
|
332
349
|
client: 'CL13NT'
|
|
333
350
|
}
|
|
334
351
|
};
|
|
335
352
|
process.env.SECRET = undefined;
|
|
336
|
-
return [4 /*yield*/, expect((0, config_1.getAccessToken)(target)).rejects.toThrow()];
|
|
353
|
+
return [4 /*yield*/, expect((0, config_1.getAccessToken)(target)).rejects.toThrow(/sasjs auth login -t viya/)];
|
|
354
|
+
case 1:
|
|
355
|
+
_a.sent();
|
|
356
|
+
return [2 /*return*/];
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
}); });
|
|
360
|
+
});
|
|
361
|
+
describe('getAuthConfig', function () {
|
|
362
|
+
beforeEach(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
363
|
+
return __generator(this, function (_a) {
|
|
364
|
+
process.projectDir = process.cwd();
|
|
365
|
+
process.env.ACCESS_TOKEN = undefined;
|
|
366
|
+
process.env.CLIENT = undefined;
|
|
367
|
+
process.env.SECRET = undefined;
|
|
368
|
+
process.env.REFRESH_TOKEN = undefined;
|
|
369
|
+
return [2 /*return*/];
|
|
370
|
+
});
|
|
371
|
+
}); });
|
|
372
|
+
afterEach(function () {
|
|
373
|
+
jest.resetAllMocks();
|
|
374
|
+
});
|
|
375
|
+
it('should return a fresh access token even when client and secret are not configured', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
376
|
+
var target, authConfig;
|
|
377
|
+
return __generator(this, function (_a) {
|
|
378
|
+
switch (_a.label) {
|
|
379
|
+
case 0:
|
|
380
|
+
;
|
|
381
|
+
sasjsAuthUtils.isAccessTokenExpiring.mockImplementation(function () { return false; });
|
|
382
|
+
target = {
|
|
383
|
+
name: 'viya',
|
|
384
|
+
authConfig: {
|
|
385
|
+
access_token: 'T0K3N'
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
return [4 /*yield*/, (0, config_1.getAuthConfig)(target)];
|
|
389
|
+
case 1:
|
|
390
|
+
authConfig = _a.sent();
|
|
391
|
+
expect(authConfig.access_token).toEqual('T0K3N');
|
|
392
|
+
return [2 /*return*/];
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
}); });
|
|
396
|
+
it('should return the configured secret on the fresh-token early return when client/secret are set', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
397
|
+
var target, authConfig;
|
|
398
|
+
return __generator(this, function (_a) {
|
|
399
|
+
switch (_a.label) {
|
|
400
|
+
case 0:
|
|
401
|
+
;
|
|
402
|
+
sasjsAuthUtils.isAccessTokenExpiring.mockImplementation(function () { return false; });
|
|
403
|
+
target = {
|
|
404
|
+
name: 'viya',
|
|
405
|
+
authConfig: {
|
|
406
|
+
access_token: 'T0K3N',
|
|
407
|
+
client: 'CL13NT',
|
|
408
|
+
secret: '53CR3T'
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
return [4 /*yield*/, (0, config_1.getAuthConfig)(target)];
|
|
412
|
+
case 1:
|
|
413
|
+
authConfig = _a.sent();
|
|
414
|
+
expect(authConfig.access_token).toEqual('T0K3N');
|
|
415
|
+
expect(authConfig.client).toEqual('CL13NT');
|
|
416
|
+
expect(authConfig.secret).toEqual('53CR3T');
|
|
417
|
+
return [2 /*return*/];
|
|
418
|
+
}
|
|
419
|
+
});
|
|
420
|
+
}); });
|
|
421
|
+
it('should throw an error mentioning sasjs auth login when the token is expiring and no client is available', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
422
|
+
var target;
|
|
423
|
+
return __generator(this, function (_a) {
|
|
424
|
+
switch (_a.label) {
|
|
425
|
+
case 0:
|
|
426
|
+
;
|
|
427
|
+
sasjsAuthUtils.isAccessTokenExpiring.mockImplementation(function () { return true; });
|
|
428
|
+
target = {
|
|
429
|
+
name: 'viya',
|
|
430
|
+
authConfig: {
|
|
431
|
+
access_token: 'T0K3N'
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
return [4 /*yield*/, expect((0, config_1.getAuthConfig)(target)).rejects.toThrow(/sasjs auth login/)];
|
|
337
435
|
case 1:
|
|
338
436
|
_a.sent();
|
|
339
437
|
return [2 /*return*/];
|
|
@@ -341,6 +439,210 @@ describe('getAccessToken', function () {
|
|
|
341
439
|
});
|
|
342
440
|
}); });
|
|
343
441
|
});
|
|
442
|
+
describe('getAuthConfig - opaque refresh tokens', function () {
|
|
443
|
+
var opaqueRefreshToken = '1f8da55057bd4f50a6577f0bc2b38b1a-r';
|
|
444
|
+
var projectDir;
|
|
445
|
+
var setupLocalProjectWithTarget = function (target) { return __awaiter(void 0, void 0, void 0, function () {
|
|
446
|
+
return __generator(this, function (_a) {
|
|
447
|
+
switch (_a.label) {
|
|
448
|
+
case 0:
|
|
449
|
+
projectDir = path_1.default.join(process.env.TEMP || process.env.TMP || '/tmp', "sasjs-cli-test-".concat((0, utils_1.generateTimestamp)()));
|
|
450
|
+
process.projectDir = projectDir;
|
|
451
|
+
return [4 /*yield*/, (0, setConstants_1.setConstants)()];
|
|
452
|
+
case 1:
|
|
453
|
+
_a.sent();
|
|
454
|
+
return [4 /*yield*/, (0, utils_1.createFile)(path_1.default.join(projectDir, 'sasjs', 'sasjsconfig.json'), JSON.stringify({ targets: [target.toJson()] }))];
|
|
455
|
+
case 2:
|
|
456
|
+
_a.sent();
|
|
457
|
+
return [2 /*return*/];
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
}); };
|
|
461
|
+
beforeEach(function () {
|
|
462
|
+
process.env.ACCESS_TOKEN = undefined;
|
|
463
|
+
process.env.CLIENT = undefined;
|
|
464
|
+
process.env.SECRET = undefined;
|
|
465
|
+
process.env.REFRESH_TOKEN = undefined;
|
|
466
|
+
});
|
|
467
|
+
afterEach(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
468
|
+
return __generator(this, function (_a) {
|
|
469
|
+
switch (_a.label) {
|
|
470
|
+
case 0:
|
|
471
|
+
jest.resetAllMocks();
|
|
472
|
+
return [4 /*yield*/, (0, utils_1.deleteFile)(projectDir).catch(function () { })];
|
|
473
|
+
case 1:
|
|
474
|
+
_a.sent();
|
|
475
|
+
return [2 /*return*/];
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
}); });
|
|
479
|
+
it('should refresh without crashing and persist the rotated pair in the client/secret branch', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
480
|
+
var target, authConfig, envContent;
|
|
481
|
+
return __generator(this, function (_a) {
|
|
482
|
+
switch (_a.label) {
|
|
483
|
+
case 0:
|
|
484
|
+
// The real isRefreshTokenExpiring must be used - it should treat the
|
|
485
|
+
// opaque token as usable rather than throwing InvalidTokenError.
|
|
486
|
+
;
|
|
487
|
+
sasjsAuthUtils.isAccessTokenExpiring.mockImplementation(function () { return true; });
|
|
488
|
+
jest.spyOn(authUtils, 'refreshTokens').mockImplementation(function () {
|
|
489
|
+
return Promise.resolve({
|
|
490
|
+
access_token: 'N3WT0K3N',
|
|
491
|
+
refresh_token: 'N3WR3FR35H'
|
|
492
|
+
});
|
|
493
|
+
});
|
|
494
|
+
target = new utils_1.Target({
|
|
495
|
+
name: 'opaq',
|
|
496
|
+
serverType: utils_1.ServerType.SasViya,
|
|
497
|
+
serverUrl: 'https://example.com',
|
|
498
|
+
appLoc: '/Public/app',
|
|
499
|
+
contextName: 'test context',
|
|
500
|
+
authConfig: {
|
|
501
|
+
access_token: 'T0K3N',
|
|
502
|
+
refresh_token: opaqueRefreshToken,
|
|
503
|
+
client: 'CL13NT',
|
|
504
|
+
secret: '53CR3T'
|
|
505
|
+
}
|
|
506
|
+
});
|
|
507
|
+
return [4 /*yield*/, setupLocalProjectWithTarget(target)];
|
|
508
|
+
case 1:
|
|
509
|
+
_a.sent();
|
|
510
|
+
return [4 /*yield*/, (0, config_1.getAuthConfig)(target)];
|
|
511
|
+
case 2:
|
|
512
|
+
authConfig = _a.sent();
|
|
513
|
+
expect(authUtils.refreshTokens).toHaveBeenCalledTimes(1);
|
|
514
|
+
expect(authConfig.access_token).toEqual('N3WT0K3N');
|
|
515
|
+
return [4 /*yield*/, (0, file_1.readFile)(path_1.default.join(projectDir, '.env.opaq'))];
|
|
516
|
+
case 3:
|
|
517
|
+
envContent = _a.sent();
|
|
518
|
+
expect(envContent).toContain('ACCESS_TOKEN=N3WT0K3N');
|
|
519
|
+
expect(envContent).toContain('REFRESH_TOKEN=N3WR3FR35H');
|
|
520
|
+
expect(envContent).toContain('CLIENT=CL13NT');
|
|
521
|
+
return [2 /*return*/];
|
|
522
|
+
}
|
|
523
|
+
});
|
|
524
|
+
}); });
|
|
525
|
+
it('should refresh via the sas.cli public client and persist the rotated pair when no client is configured', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
526
|
+
var refreshTokensSpy, target, authConfig, envContent;
|
|
527
|
+
return __generator(this, function (_a) {
|
|
528
|
+
switch (_a.label) {
|
|
529
|
+
case 0:
|
|
530
|
+
;
|
|
531
|
+
sasjsAuthUtils.isAccessTokenExpiring.mockImplementation(function () { return true; });
|
|
532
|
+
refreshTokensSpy = jest
|
|
533
|
+
.spyOn(authUtils, 'refreshTokens')
|
|
534
|
+
.mockImplementation(function () {
|
|
535
|
+
return Promise.resolve({
|
|
536
|
+
access_token: 'N3WT0K3N',
|
|
537
|
+
refresh_token: 'N3WR3FR35H'
|
|
538
|
+
});
|
|
539
|
+
});
|
|
540
|
+
target = new utils_1.Target({
|
|
541
|
+
name: 'opaq',
|
|
542
|
+
serverType: utils_1.ServerType.SasViya,
|
|
543
|
+
serverUrl: 'https://example.com',
|
|
544
|
+
appLoc: '/Public/app',
|
|
545
|
+
contextName: 'test context',
|
|
546
|
+
authConfig: {
|
|
547
|
+
access_token: 'T0K3N',
|
|
548
|
+
refresh_token: opaqueRefreshToken
|
|
549
|
+
}
|
|
550
|
+
});
|
|
551
|
+
return [4 /*yield*/, setupLocalProjectWithTarget(target)];
|
|
552
|
+
case 1:
|
|
553
|
+
_a.sent();
|
|
554
|
+
return [4 /*yield*/, (0, config_1.getAuthConfig)(target)];
|
|
555
|
+
case 2:
|
|
556
|
+
authConfig = _a.sent();
|
|
557
|
+
expect(refreshTokensSpy).toHaveBeenCalledWith(expect.anything(), 'sas.cli', '', opaqueRefreshToken);
|
|
558
|
+
expect(authConfig.access_token).toEqual('N3WT0K3N');
|
|
559
|
+
expect(authConfig.client).toBeUndefined();
|
|
560
|
+
expect(authConfig.secret).toBeUndefined();
|
|
561
|
+
return [4 /*yield*/, (0, file_1.readFile)(path_1.default.join(projectDir, '.env.opaq'))];
|
|
562
|
+
case 3:
|
|
563
|
+
envContent = _a.sent();
|
|
564
|
+
expect(envContent).toContain('ACCESS_TOKEN=N3WT0K3N');
|
|
565
|
+
expect(envContent).toContain('REFRESH_TOKEN=N3WR3FR35H');
|
|
566
|
+
expect(envContent).not.toContain('CLIENT=');
|
|
567
|
+
return [2 /*return*/];
|
|
568
|
+
}
|
|
569
|
+
});
|
|
570
|
+
}); });
|
|
571
|
+
it('should persist tokens refreshed internally by the adapter without dropping client/secret', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
572
|
+
var target, envContent;
|
|
573
|
+
return __generator(this, function (_a) {
|
|
574
|
+
switch (_a.label) {
|
|
575
|
+
case 0:
|
|
576
|
+
target = new utils_1.Target({
|
|
577
|
+
name: 'opaq',
|
|
578
|
+
serverType: utils_1.ServerType.SasViya,
|
|
579
|
+
serverUrl: 'https://example.com',
|
|
580
|
+
appLoc: '/Public/app',
|
|
581
|
+
contextName: 'test context',
|
|
582
|
+
authConfig: {
|
|
583
|
+
access_token: 'T0K3N',
|
|
584
|
+
refresh_token: opaqueRefreshToken,
|
|
585
|
+
client: 'CL13NT',
|
|
586
|
+
secret: '53CR3T'
|
|
587
|
+
}
|
|
588
|
+
});
|
|
589
|
+
return [4 /*yield*/, setupLocalProjectWithTarget(target)];
|
|
590
|
+
case 1:
|
|
591
|
+
_a.sent();
|
|
592
|
+
return [4 /*yield*/, (0, config_1.persistTokensRefreshedByAdapter)(target)({
|
|
593
|
+
access_token: '4D4PT3R',
|
|
594
|
+
refresh_token: '4D4PT3RR3FR35H'
|
|
595
|
+
})];
|
|
596
|
+
case 2:
|
|
597
|
+
_a.sent();
|
|
598
|
+
return [4 /*yield*/, (0, file_1.readFile)(path_1.default.join(projectDir, '.env.opaq'))];
|
|
599
|
+
case 3:
|
|
600
|
+
envContent = _a.sent();
|
|
601
|
+
expect(envContent).toContain('ACCESS_TOKEN=4D4PT3R');
|
|
602
|
+
expect(envContent).toContain('REFRESH_TOKEN=4D4PT3RR3FR35H');
|
|
603
|
+
expect(envContent).toContain('CLIENT=CL13NT');
|
|
604
|
+
expect(envContent).toContain('SECRET=53CR3T');
|
|
605
|
+
return [2 /*return*/];
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
}); });
|
|
609
|
+
it('should persist tokens refreshed by the adapter without adding CLIENT=/SECRET= lines for a password-grant-only target', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
610
|
+
var target, envContent;
|
|
611
|
+
return __generator(this, function (_a) {
|
|
612
|
+
switch (_a.label) {
|
|
613
|
+
case 0:
|
|
614
|
+
target = new utils_1.Target({
|
|
615
|
+
name: 'opaq',
|
|
616
|
+
serverType: utils_1.ServerType.SasViya,
|
|
617
|
+
serverUrl: 'https://example.com',
|
|
618
|
+
appLoc: '/Public/app',
|
|
619
|
+
contextName: 'test context',
|
|
620
|
+
authConfig: {
|
|
621
|
+
access_token: 'T0K3N',
|
|
622
|
+
refresh_token: opaqueRefreshToken
|
|
623
|
+
}
|
|
624
|
+
});
|
|
625
|
+
return [4 /*yield*/, setupLocalProjectWithTarget(target)];
|
|
626
|
+
case 1:
|
|
627
|
+
_a.sent();
|
|
628
|
+
return [4 /*yield*/, (0, config_1.persistTokensRefreshedByAdapter)(target)({
|
|
629
|
+
access_token: '4D4PT3R',
|
|
630
|
+
refresh_token: '4D4PT3RR3FR35H'
|
|
631
|
+
})];
|
|
632
|
+
case 2:
|
|
633
|
+
_a.sent();
|
|
634
|
+
return [4 /*yield*/, (0, file_1.readFile)(path_1.default.join(projectDir, '.env.opaq'))];
|
|
635
|
+
case 3:
|
|
636
|
+
envContent = _a.sent();
|
|
637
|
+
expect(envContent).toContain('ACCESS_TOKEN=4D4PT3R');
|
|
638
|
+
expect(envContent).toContain('REFRESH_TOKEN=4D4PT3RR3FR35H');
|
|
639
|
+
expect(envContent).not.toContain('CLIENT=');
|
|
640
|
+
expect(envContent).not.toContain('SECRET=');
|
|
641
|
+
return [2 /*return*/];
|
|
642
|
+
}
|
|
643
|
+
});
|
|
644
|
+
}); });
|
|
645
|
+
});
|
|
344
646
|
describe('sanitizeAppLoc', function () {
|
|
345
647
|
var notValidAppLoc = '///Public/app///';
|
|
346
648
|
var validAppLoc = '/Public/app';
|
package/package.json
CHANGED
|
@@ -69,10 +69,10 @@
|
|
|
69
69
|
"registry": "https://registry.npmjs.org"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@sasjs/adapter": "4.
|
|
72
|
+
"@sasjs/adapter": "^4.18.0",
|
|
73
73
|
"@sasjs/core": "4.68.1",
|
|
74
74
|
"@sasjs/lint": "2.4.3",
|
|
75
|
-
"@sasjs/utils": "3.
|
|
75
|
+
"@sasjs/utils": "^3.6.0",
|
|
76
76
|
"adm-zip": "0.6.0",
|
|
77
77
|
"chalk": "4.1.2",
|
|
78
78
|
"dotenv": "16.0.3",
|
|
@@ -85,6 +85,7 @@
|
|
|
85
85
|
"node-graphviz": "0.1.1",
|
|
86
86
|
"node-powershell": "5.0.1",
|
|
87
87
|
"ora": "5.4.1",
|
|
88
|
+
"prompts": "2.4.1",
|
|
88
89
|
"shelljs": "0.10.0",
|
|
89
90
|
"ssl-root-cas": "1.3.1",
|
|
90
91
|
"xml": "1.0.1",
|
|
@@ -123,5 +124,5 @@
|
|
|
123
124
|
"ws": "8.21.0",
|
|
124
125
|
"nanoid": "3.3.18"
|
|
125
126
|
},
|
|
126
|
-
"version": "4.
|
|
127
|
+
"version": "4.19.0"
|
|
127
128
|
}
|