@sap/cds-dk 4.9.3 → 4.9.6
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 +29 -0
- package/lib/client/helper/string_helper.js +6 -1
- package/lib/client/settings_manager.js +24 -35
- package/lib/init/constants.js +1 -1
- package/npm-shrinkwrap.json +409 -287
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,35 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
|
8
8
|
|
|
9
|
+
## Version 4.9.6 - 2022-06-08
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Include `@sap/cds` 5.9.6
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- `cds login` (and `cds extend`, `cds activate` if previously logged in) now properly renew token URL
|
|
18
|
+
- Improved logging during those commands
|
|
19
|
+
|
|
20
|
+
## Version 4.9.5 - 2022-05-17
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- Include `@sap/cds` 5.9.5
|
|
25
|
+
- Include `@sap/cds-compiler` 2.15.2
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- `cds init` uses latest Maven Java archetype version 1.24.0 for creating Java projects.
|
|
30
|
+
|
|
31
|
+
## Version 4.9.4 - 2022-05-09
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- Include `@sap/cds` 5.9.4
|
|
36
|
+
- Bump `axios` to latest (CVE-2022-1214)
|
|
37
|
+
|
|
9
38
|
## Version 4.9.3 - 2022-04-27
|
|
10
39
|
|
|
11
40
|
### Changed
|
|
@@ -47,7 +47,12 @@ function escapeRegex(str) {
|
|
|
47
47
|
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
function capitalize(str) {
|
|
51
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
52
|
+
}
|
|
53
|
+
|
|
50
54
|
module.exports = {
|
|
51
55
|
formatObjectsFixedWidth,
|
|
52
|
-
escapeRegex
|
|
56
|
+
escapeRegex,
|
|
57
|
+
capitalize
|
|
53
58
|
};
|
|
@@ -12,6 +12,7 @@ const Logger = require('./helper/logging');
|
|
|
12
12
|
const Question = require('./helper/question');
|
|
13
13
|
const { defaultSchema, extractSubdomain, schemaRegex } = require('./helper/url_helper');
|
|
14
14
|
const { ParamCollection, Persistence } = require('./params');
|
|
15
|
+
const { capitalize } = require('./helper/string_helper');
|
|
15
16
|
|
|
16
17
|
const CONFIG_SUBDIRS = {
|
|
17
18
|
linux: '.config',
|
|
@@ -107,7 +108,7 @@ function getKeyringAccountName(params) {
|
|
|
107
108
|
|
|
108
109
|
function logConfigPaths() {
|
|
109
110
|
Logger.debug(`Settings are stored in ${CONFIG.paths.settings}`);
|
|
110
|
-
Logger.debug(`Authentication data is stored in ${CONFIG.paths.auth} or
|
|
111
|
+
Logger.debug(`Authentication data is stored in ${CONFIG.paths.auth} (${TOKEN_STORAGE_DESC.plain}) or ${CONFIG.keyringDesignation} (${TOKEN_STORAGE_DESC.keyring})`);
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
function notifyLoggedIn(params) {
|
|
@@ -133,9 +134,6 @@ class SettingsManager {
|
|
|
133
134
|
// Call with 'projectFolder' param as a resolved path.
|
|
134
135
|
static async saveSettings(params) {
|
|
135
136
|
Logger.debug(`Saving settings for project ${params.get('projectFolder')}`);
|
|
136
|
-
if (params.has('token') && ! params.has('tokenStorage')) {
|
|
137
|
-
Logger.log('Note: the authentication token is not saved by default. To save the token for later commands, please run `cds login`.');
|
|
138
|
-
}
|
|
139
137
|
|
|
140
138
|
await this._saveToFile(params.get('projectFolder'), params.toValueMap(Persistence.setting));
|
|
141
139
|
|
|
@@ -153,6 +151,8 @@ class SettingsManager {
|
|
|
153
151
|
await this._saveAuthToFile(params, params.toValueMap(Persistence.auth));
|
|
154
152
|
} else if (params.get('tokenStorage') === 'keyring') {
|
|
155
153
|
await this._saveAuthToKeyring(params, params.toValueMap(Persistence.auth));
|
|
154
|
+
} else {
|
|
155
|
+
Logger.log('Note: the authentication token is not saved by default. To save the token for later commands, please run `cds login`.');
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
|
|
@@ -160,19 +160,19 @@ class SettingsManager {
|
|
|
160
160
|
const projectFolder = getProjectFolder(params);
|
|
161
161
|
params.set('projectFolder', projectFolder);
|
|
162
162
|
|
|
163
|
-
Logger.debug(`Loading settings for project ${projectFolder}`);
|
|
164
163
|
const loadedSettings = await this._loadFromFile(projectFolder);
|
|
165
|
-
Logger.debug(`Loaded project settings: ${loadedSettings.format()}`);
|
|
164
|
+
Logger.debug(`Loaded project settings for ${params.get('projectFolder')}: ${loadedSettings.format()}`);
|
|
165
|
+
const loadedAppUrl = loadedSettings.get('appUrl');
|
|
166
166
|
|
|
167
167
|
params.mergeLower(loadedSettings);
|
|
168
168
|
|
|
169
|
-
await this.updateUrls(params, logout);
|
|
169
|
+
await this.updateUrls(params, logout, loadedAppUrl);
|
|
170
170
|
await this.checkKeytar(params, logout);
|
|
171
171
|
await this.addAuth(params, logout);
|
|
172
172
|
Logger.debug(`Effective project settings: ${params.format()}`);
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
static async updateUrls(params, logout) {
|
|
175
|
+
static async updateUrls(params, logout, loadedAppUrl) {
|
|
176
176
|
async function addAppUrlAndSubdomain() {
|
|
177
177
|
if (params.has('appUrl') && !schemaRegex.test(params.get('appUrl'))) {
|
|
178
178
|
params.set('appUrl', defaultSchema + params.get('appUrl'));
|
|
@@ -202,7 +202,7 @@ class SettingsManager {
|
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
204
|
function renewTokenUrl() {
|
|
205
|
-
const renewUrl = params.get('appUrl') !==
|
|
205
|
+
const renewUrl = params.get('appUrl') !== loadedAppUrl;
|
|
206
206
|
if (!params.get('tokenUrl') || renewUrl) {
|
|
207
207
|
params.set('tokenUrl', getTokenBaseUrl(params, renewUrl));
|
|
208
208
|
}
|
|
@@ -218,7 +218,7 @@ class SettingsManager {
|
|
|
218
218
|
static async checkKeytar(params, logout) {
|
|
219
219
|
if (isBas()) {
|
|
220
220
|
if (params.get('tokenStorage') === 'keyring') {
|
|
221
|
-
Logger.log(`NOTE:
|
|
221
|
+
Logger.log(`NOTE: ${capitalize(TOKEN_STORAGE_DESC.keyring)} not supported on SAP Business Application Studio. Switching to ${TOKEN_STORAGE_DESC.plain}.`);
|
|
222
222
|
params.set('tokenStorage', 'plain');
|
|
223
223
|
}
|
|
224
224
|
return;
|
|
@@ -227,11 +227,11 @@ class SettingsManager {
|
|
|
227
227
|
return;
|
|
228
228
|
}
|
|
229
229
|
if (params.get('tokenStorage') === 'keyring') {
|
|
230
|
-
throw new Error(
|
|
231
|
-
|
|
230
|
+
throw new Error(`${capitalize(TOKEN_STORAGE_DESC.keyring)} requested but keytar not installed. Run 'npm install -g keytar' or ` +
|
|
231
|
+
`switch to ${TOKEN_STORAGE_DESC.plain} by adding '--plain' (discouraged).`);
|
|
232
232
|
}
|
|
233
233
|
if (params.get('renewLogin') || logout) {
|
|
234
|
-
Logger.log(
|
|
234
|
+
Logger.log(`Disabling ${TOKEN_STORAGE_DESC.keyring} functionality: 'keytar' module not found. Run 'npm install -g keytar' to install it.`);
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
237
|
|
|
@@ -288,8 +288,6 @@ class SettingsManager {
|
|
|
288
288
|
}
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
-
Logger.debug(`Consolidating authentication data for project ${params.get('projectFolder')}`);
|
|
292
|
-
|
|
293
291
|
if (params.has('username')) {
|
|
294
292
|
if (!params.get('password') && !logout) {
|
|
295
293
|
await addPassword();
|
|
@@ -325,7 +323,7 @@ class SettingsManager {
|
|
|
325
323
|
|
|
326
324
|
fromStorage = fromStorage || allParams.get('tokenStorage');
|
|
327
325
|
if (!fromStorage) {
|
|
328
|
-
Logger.log(`
|
|
326
|
+
Logger.log(`Failed to delete authentication data: none found for ${target}`);
|
|
329
327
|
return;
|
|
330
328
|
}
|
|
331
329
|
|
|
@@ -339,13 +337,10 @@ class SettingsManager {
|
|
|
339
337
|
|
|
340
338
|
static async deleteSettingsWithoutToken(params) {
|
|
341
339
|
const projectFolder = getProjectFolder(params);
|
|
342
|
-
Logger.debug(`Deleting settings for project ${projectFolder}`);
|
|
343
340
|
await this._saveToFile(projectFolder, null);
|
|
344
341
|
}
|
|
345
342
|
|
|
346
343
|
static async deleteInvalid() {
|
|
347
|
-
Logger.log('Deleting invalid project settings');
|
|
348
|
-
|
|
349
344
|
const settingsByFolder = await this._loadFromFile(undefined);
|
|
350
345
|
const deletionFolders = [];
|
|
351
346
|
const deletionUrlsAndSubdomains = new Set();
|
|
@@ -395,11 +390,10 @@ class SettingsManager {
|
|
|
395
390
|
}
|
|
396
391
|
|
|
397
392
|
static async _saveAuthToFile(params, authValues) {
|
|
398
|
-
Logger.debug(`Updating authentication data to ${CONFIG.paths.auth}`);
|
|
399
393
|
const appUrl = params.get('appUrl');
|
|
400
|
-
const location =
|
|
401
|
-
|
|
394
|
+
const location = `${TOKEN_STORAGE_DESC.plain} at ${CONFIG.paths.auth} for app URL ${appUrl}, subdomain ${params.get('subdomain')}`;
|
|
402
395
|
const allAuthValues = await this._loadAuthFromFile(undefined, undefined);
|
|
396
|
+
|
|
403
397
|
if (authValues !== null) {
|
|
404
398
|
(allAuthValues[appUrl] || (allAuthValues[appUrl] = {}))[params.get('subdomain')] = authValues;
|
|
405
399
|
await fse.outputJson(CONFIG.paths.auth, allAuthValues, { spaces: 2 });
|
|
@@ -412,7 +406,7 @@ class SettingsManager {
|
|
|
412
406
|
await fse.outputJson(CONFIG.paths.auth, allAuthValues, { spaces: 2 });
|
|
413
407
|
Logger.log(`Deleted authentication data from ${location}`);
|
|
414
408
|
} else {
|
|
415
|
-
|
|
409
|
+
notifyLoggedIn(params)(`No authentication data to delete from ${location}`);
|
|
416
410
|
}
|
|
417
411
|
}
|
|
418
412
|
|
|
@@ -421,8 +415,7 @@ class SettingsManager {
|
|
|
421
415
|
return;
|
|
422
416
|
}
|
|
423
417
|
|
|
424
|
-
|
|
425
|
-
const location = `keyring for app URL ${params.get('appUrl')}, subdomain ${params.get('subdomain')}`;
|
|
418
|
+
const location = `${TOKEN_STORAGE_DESC.keyring} for app URL ${params.get('appUrl')}, subdomain ${params.get('subdomain')}`;
|
|
426
419
|
|
|
427
420
|
if (auth !== null) {
|
|
428
421
|
await keytar.setPassword(MTX_FULLY_QUALIFIED, getKeyringAccountName(params), JSON.stringify(auth));
|
|
@@ -437,11 +430,10 @@ class SettingsManager {
|
|
|
437
430
|
const all = !projectFolder;
|
|
438
431
|
|
|
439
432
|
if (!fs.existsSync(CONFIG.paths.settings)) {
|
|
440
|
-
Logger.debug('Settings file
|
|
433
|
+
Logger.debug('Settings file not found');
|
|
441
434
|
return emptyData(all);
|
|
442
435
|
}
|
|
443
436
|
|
|
444
|
-
Logger.debug('Reading settings file');
|
|
445
437
|
const settingsByFolder = await fse.readJson(CONFIG.paths.settings);
|
|
446
438
|
|
|
447
439
|
if (!settingsByFolder) {
|
|
@@ -465,15 +457,14 @@ class SettingsManager {
|
|
|
465
457
|
const all = !appUrl;
|
|
466
458
|
|
|
467
459
|
if (!fs.existsSync(CONFIG.paths.auth)) {
|
|
468
|
-
Logger.debug('Authentication-data file
|
|
460
|
+
Logger.debug('Authentication-data file not found');
|
|
469
461
|
return emptyData(all);
|
|
470
462
|
}
|
|
471
463
|
|
|
472
|
-
Logger.debug(`Reading authentication data from ${CONFIG.paths.auth}`);
|
|
473
464
|
const allAuth = await fse.readJson(CONFIG.paths.auth);
|
|
474
465
|
|
|
475
466
|
if (!allAuth) {
|
|
476
|
-
Logger.debug('Empty authentication
|
|
467
|
+
Logger.debug('Empty authentication-data file');
|
|
477
468
|
return emptyData(all);
|
|
478
469
|
}
|
|
479
470
|
|
|
@@ -482,14 +473,14 @@ class SettingsManager {
|
|
|
482
473
|
}
|
|
483
474
|
|
|
484
475
|
if (!allAuth[appUrl]) {
|
|
485
|
-
Logger.debug(`
|
|
476
|
+
Logger.debug(`File contains no authentication data for app URL ${appUrl}`);
|
|
486
477
|
return new ParamCollection();
|
|
487
478
|
}
|
|
488
479
|
|
|
489
480
|
const authForSubdomain = allAuth[appUrl][subdomain];
|
|
490
481
|
|
|
491
482
|
if (!authForSubdomain) {
|
|
492
|
-
Logger.debug(`
|
|
483
|
+
Logger.debug(`File contains no authentication data for subdomain ${subdomain} (app URL: ${appUrl})`);
|
|
493
484
|
return new ParamCollection();
|
|
494
485
|
}
|
|
495
486
|
|
|
@@ -505,12 +496,10 @@ class SettingsManager {
|
|
|
505
496
|
return new ParamCollection();
|
|
506
497
|
}
|
|
507
498
|
|
|
508
|
-
Logger.debug('Reading authentication data from keyring');
|
|
509
|
-
|
|
510
499
|
const authString = await keytar.getPassword(MTX_FULLY_QUALIFIED, getKeyringAccountName(new ParamCollection({ appUrl, subdomain })));
|
|
511
500
|
|
|
512
501
|
if (!authString) {
|
|
513
|
-
Logger.debug(
|
|
502
|
+
Logger.debug(`${capitalize(TOKEN_STORAGE_DESC.keyring)} contains no authentication data for URL ${appUrl} and subdomain '${subdomain}'`);
|
|
514
503
|
return new ParamCollection();
|
|
515
504
|
}
|
|
516
505
|
|