@socketsecurity/cli-with-sentry 0.14.66 → 0.14.67
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/dist/constants.d.ts +2 -0
- package/dist/constants.js +10 -2
- package/dist/constants.js.map +1 -1
- package/dist/instrument-with-sentry.js +2 -2
- package/dist/instrument-with-sentry.js.map +1 -1
- package/dist/module-sync/cli.js +872 -391
- package/dist/module-sync/cli.js.map +1 -1
- package/dist/module-sync/config.d.ts +19 -0
- package/dist/module-sync/path-resolve.d.ts +2 -2
- package/dist/module-sync/shadow-npm-inject.js +93 -83
- package/dist/module-sync/shadow-npm-inject.js.map +1 -1
- package/dist/module-sync/shadow-npm-paths.js +3 -3
- package/dist/module-sync/shadow-npm-paths.js.map +1 -1
- package/dist/require/cli.js +872 -391
- package/dist/require/cli.js.map +1 -1
- package/package.json +11 -11
- package/dist/module-sync/settings.d.ts +0 -15
package/dist/module-sync/cli.js
CHANGED
|
@@ -56,8 +56,7 @@ var tinyglobby = _socketInterop(require('tinyglobby'));
|
|
|
56
56
|
var promises = require('@socketsecurity/registry/lib/promises');
|
|
57
57
|
var yaml = _socketInterop(require('yaml'));
|
|
58
58
|
var betterAjvErrors = _socketInterop(require('@apideck/better-ajv-errors'));
|
|
59
|
-
var config$
|
|
60
|
-
var assert = require('node:assert');
|
|
59
|
+
var config$H = require('@socketsecurity/config');
|
|
61
60
|
var readline = require('node:readline/promises');
|
|
62
61
|
var open = _socketInterop(require('open'));
|
|
63
62
|
var BoxWidget = _socketInterop(require('blessed/lib/widgets/box'));
|
|
@@ -105,7 +104,7 @@ function getLastFiveOfApiToken(token) {
|
|
|
105
104
|
|
|
106
105
|
// The API server that should be used for operations.
|
|
107
106
|
function getDefaultApiBaseUrl() {
|
|
108
|
-
const baseUrl = process$1.env['SOCKET_SECURITY_API_BASE_URL'] || shadowNpmInject.
|
|
107
|
+
const baseUrl = process$1.env['SOCKET_SECURITY_API_BASE_URL'] || shadowNpmInject.getConfigValue('apiBaseUrl');
|
|
109
108
|
return strings.isNonEmptyString(baseUrl) ? baseUrl : undefined;
|
|
110
109
|
}
|
|
111
110
|
async function queryApi(path, apiToken) {
|
|
@@ -119,8 +118,8 @@ async function queryApi(path, apiToken) {
|
|
|
119
118
|
}
|
|
120
119
|
|
|
121
120
|
async function fetchOrgAnalyticsData(time, spinner, apiToken) {
|
|
122
|
-
const
|
|
123
|
-
const result = await handleApiCall(
|
|
121
|
+
const sockSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
122
|
+
const result = await handleApiCall(sockSdk.getOrgAnalytics(time.toString()), 'fetching analytics data');
|
|
124
123
|
if (result.success === false) {
|
|
125
124
|
handleUnsuccessfulApiResponse('getOrgAnalytics', result);
|
|
126
125
|
return undefined;
|
|
@@ -134,8 +133,8 @@ async function fetchOrgAnalyticsData(time, spinner, apiToken) {
|
|
|
134
133
|
}
|
|
135
134
|
|
|
136
135
|
async function fetchRepoAnalyticsData(repo, time, spinner, apiToken) {
|
|
137
|
-
const
|
|
138
|
-
const result = await handleApiCall(
|
|
136
|
+
const sockSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
137
|
+
const result = await handleApiCall(sockSdk.getRepoAnalytics(repo, time.toString()), 'fetching analytics data');
|
|
139
138
|
if (result.success === false) {
|
|
140
139
|
handleUnsuccessfulApiResponse('getRepoAnalytics', result);
|
|
141
140
|
return undefined;
|
|
@@ -655,9 +654,9 @@ function emitBanner(name) {
|
|
|
655
654
|
}
|
|
656
655
|
function getAsciiHeader(command) {
|
|
657
656
|
const cliVersion = // The '@rollup/plugin-replace' will replace "process.env['INLINED_SOCKET_CLI_VERSION_HASH']".
|
|
658
|
-
"0.14.
|
|
657
|
+
"0.14.67:a2db5d2:df42d424:pub";
|
|
659
658
|
const nodeVersion = process.version;
|
|
660
|
-
const apiToken = shadowNpmInject.
|
|
659
|
+
const apiToken = shadowNpmInject.getConfigValue('apiToken');
|
|
661
660
|
const shownToken = apiToken ? getLastFiveOfApiToken(apiToken) : 'no';
|
|
662
661
|
const relCwd = path.normalizePath(process.cwd().replace(new RegExp(`^${regexps.escapeRegExp(constants.homePath)}(?:${path$1.sep}|$)`, 'i'), '~/'));
|
|
663
662
|
const body = `
|
|
@@ -669,9 +668,9 @@ function getAsciiHeader(command) {
|
|
|
669
668
|
}
|
|
670
669
|
|
|
671
670
|
const {
|
|
672
|
-
DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
671
|
+
DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$F
|
|
673
672
|
} = constants;
|
|
674
|
-
const config$
|
|
673
|
+
const config$G = {
|
|
675
674
|
commandName: 'analytics',
|
|
676
675
|
description: `Look up analytics data`,
|
|
677
676
|
hidden: false,
|
|
@@ -722,16 +721,16 @@ const config$C = {
|
|
|
722
721
|
`
|
|
723
722
|
};
|
|
724
723
|
const cmdAnalytics = {
|
|
725
|
-
description: config$
|
|
726
|
-
hidden: config$
|
|
727
|
-
run: run$
|
|
724
|
+
description: config$G.description,
|
|
725
|
+
hidden: config$G.hidden,
|
|
726
|
+
run: run$G
|
|
728
727
|
};
|
|
729
|
-
async function run$
|
|
728
|
+
async function run$G(argv, importMeta, {
|
|
730
729
|
parentName
|
|
731
730
|
}) {
|
|
732
731
|
const cli = meowOrExit({
|
|
733
732
|
argv,
|
|
734
|
-
config: config$
|
|
733
|
+
config: config$G,
|
|
735
734
|
importMeta,
|
|
736
735
|
parentName
|
|
737
736
|
});
|
|
@@ -768,7 +767,7 @@ async function run$C(argv, importMeta, {
|
|
|
768
767
|
return;
|
|
769
768
|
}
|
|
770
769
|
if (cli.flags['dryRun']) {
|
|
771
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
770
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$F);
|
|
772
771
|
return;
|
|
773
772
|
}
|
|
774
773
|
return await displayAnalytics({
|
|
@@ -811,8 +810,8 @@ async function fetchAuditLogWithToken(apiToken, {
|
|
|
811
810
|
spinner
|
|
812
811
|
} = constants;
|
|
813
812
|
spinner.start(`Looking up audit log for ${orgSlug}`);
|
|
814
|
-
const
|
|
815
|
-
const result = await handleApiCall(
|
|
813
|
+
const sockSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
814
|
+
const result = await handleApiCall(sockSdk.getAuditLogEvents(orgSlug, {
|
|
816
815
|
// I'm not sure this is used at all.
|
|
817
816
|
outputJson: String(outputKind === 'json'),
|
|
818
817
|
// I'm not sure this is used at all.
|
|
@@ -955,9 +954,9 @@ async function handleAuditLog({
|
|
|
955
954
|
}
|
|
956
955
|
|
|
957
956
|
const {
|
|
958
|
-
DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
957
|
+
DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$E
|
|
959
958
|
} = constants;
|
|
960
|
-
const config$
|
|
959
|
+
const config$F = {
|
|
961
960
|
commandName: 'audit-log',
|
|
962
961
|
description: 'Look up the audit log for an organization',
|
|
963
962
|
hidden: false,
|
|
@@ -998,16 +997,16 @@ const config$B = {
|
|
|
998
997
|
`
|
|
999
998
|
};
|
|
1000
999
|
const cmdAuditLog = {
|
|
1001
|
-
description: config$
|
|
1002
|
-
hidden: config$
|
|
1003
|
-
run: run$
|
|
1000
|
+
description: config$F.description,
|
|
1001
|
+
hidden: config$F.hidden,
|
|
1002
|
+
run: run$F
|
|
1004
1003
|
};
|
|
1005
|
-
async function run$
|
|
1004
|
+
async function run$F(argv, importMeta, {
|
|
1006
1005
|
parentName
|
|
1007
1006
|
}) {
|
|
1008
1007
|
const cli = meowOrExit({
|
|
1009
1008
|
argv,
|
|
1010
|
-
config: config$
|
|
1009
|
+
config: config$F,
|
|
1011
1010
|
importMeta,
|
|
1012
1011
|
parentName
|
|
1013
1012
|
});
|
|
@@ -1032,7 +1031,7 @@ async function run$B(argv, importMeta, {
|
|
|
1032
1031
|
return;
|
|
1033
1032
|
}
|
|
1034
1033
|
if (cli.flags['dryRun']) {
|
|
1035
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
1034
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$E);
|
|
1036
1035
|
return;
|
|
1037
1036
|
}
|
|
1038
1037
|
await handleAuditLog({
|
|
@@ -1149,7 +1148,7 @@ function isHelpFlag(cmdArg) {
|
|
|
1149
1148
|
|
|
1150
1149
|
// import { meowOrExit } from '../../utils/meow-with-subcommands'
|
|
1151
1150
|
const {
|
|
1152
|
-
DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
1151
|
+
DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$D
|
|
1153
1152
|
} = constants;
|
|
1154
1153
|
|
|
1155
1154
|
// TODO: convert yargs to meow. Or convert all the other things to yargs.
|
|
@@ -1226,7 +1225,7 @@ const yargsConfig = {
|
|
|
1226
1225
|
'yes'],
|
|
1227
1226
|
string: ['api-key', 'lifecycle', 'output', 'parent-project-id', 'profile', 'project-group', 'project-name', 'project-version', 'project-id', 'server-host', 'server-port', 'server-url', 'spec-version']
|
|
1228
1227
|
};
|
|
1229
|
-
const config$
|
|
1228
|
+
const config$E = {
|
|
1230
1229
|
commandName: 'cdxgen',
|
|
1231
1230
|
description: 'Create an SBOM with CycloneDX generator (cdxgen)',
|
|
1232
1231
|
hidden: false,
|
|
@@ -1242,18 +1241,18 @@ const config$A = {
|
|
|
1242
1241
|
`
|
|
1243
1242
|
};
|
|
1244
1243
|
const cmdCdxgen = {
|
|
1245
|
-
description: config$
|
|
1246
|
-
hidden: config$
|
|
1247
|
-
run: run$
|
|
1244
|
+
description: config$E.description,
|
|
1245
|
+
hidden: config$E.hidden,
|
|
1246
|
+
run: run$E
|
|
1248
1247
|
};
|
|
1249
|
-
async function run$
|
|
1248
|
+
async function run$E(argv, importMeta, {
|
|
1250
1249
|
parentName
|
|
1251
1250
|
}) {
|
|
1252
1251
|
const cli = meowOrExit({
|
|
1253
1252
|
allowUnknownFlags: true,
|
|
1254
1253
|
// Don't let meow take over --help.
|
|
1255
1254
|
argv: argv.filter(a => !isHelpFlag(a)),
|
|
1256
|
-
config: config$
|
|
1255
|
+
config: config$E,
|
|
1257
1256
|
importMeta,
|
|
1258
1257
|
parentName
|
|
1259
1258
|
});
|
|
@@ -1285,7 +1284,7 @@ async function run$A(argv, importMeta, {
|
|
|
1285
1284
|
return;
|
|
1286
1285
|
}
|
|
1287
1286
|
if (cli.flags['dryRun']) {
|
|
1288
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
1287
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$D);
|
|
1289
1288
|
return;
|
|
1290
1289
|
}
|
|
1291
1290
|
if (yargv.output === undefined) {
|
|
@@ -1294,6 +1293,405 @@ async function run$A(argv, importMeta, {
|
|
|
1294
1293
|
await runCycloneDX(yargv);
|
|
1295
1294
|
}
|
|
1296
1295
|
|
|
1296
|
+
async function outputConfigGet(key, value, outputKind) {
|
|
1297
|
+
if (outputKind === 'json') {
|
|
1298
|
+
logger.logger.log(JSON.stringify({
|
|
1299
|
+
success: true,
|
|
1300
|
+
result: {
|
|
1301
|
+
key,
|
|
1302
|
+
value
|
|
1303
|
+
}
|
|
1304
|
+
}));
|
|
1305
|
+
} else if (outputKind === 'markdown') {
|
|
1306
|
+
logger.logger.log(`# Config Value`);
|
|
1307
|
+
logger.logger.log('');
|
|
1308
|
+
logger.logger.log(`Config key '${key}' has value '${value}`);
|
|
1309
|
+
} else {
|
|
1310
|
+
logger.logger.log(`${key}: ${value}`);
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
async function handleConfigGet({
|
|
1315
|
+
key,
|
|
1316
|
+
outputKind
|
|
1317
|
+
}) {
|
|
1318
|
+
const value = shadowNpmInject.getConfigValue(key);
|
|
1319
|
+
await outputConfigGet(key, value, outputKind);
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
const {
|
|
1323
|
+
DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$C
|
|
1324
|
+
} = constants;
|
|
1325
|
+
const config$D = {
|
|
1326
|
+
commandName: 'get',
|
|
1327
|
+
description: 'Get the value of a local CLI config item',
|
|
1328
|
+
hidden: false,
|
|
1329
|
+
flags: {
|
|
1330
|
+
...commonFlags,
|
|
1331
|
+
...outputFlags
|
|
1332
|
+
},
|
|
1333
|
+
help: (command, config) => `
|
|
1334
|
+
Usage
|
|
1335
|
+
$ ${command} <org slug>
|
|
1336
|
+
|
|
1337
|
+
Options
|
|
1338
|
+
${getFlagListOutput(config.flags, 6)}
|
|
1339
|
+
|
|
1340
|
+
Keys:
|
|
1341
|
+
|
|
1342
|
+
${Array.from(shadowNpmInject.supportedConfigKeys.entries()).map(([key, desc]) => ` - ${key} -- ${desc}`).join('\n')}
|
|
1343
|
+
|
|
1344
|
+
Examples
|
|
1345
|
+
$ ${command} FakeOrg --repoName=test-repo
|
|
1346
|
+
`
|
|
1347
|
+
};
|
|
1348
|
+
const cmdConfigGet = {
|
|
1349
|
+
description: config$D.description,
|
|
1350
|
+
hidden: config$D.hidden,
|
|
1351
|
+
run: run$D
|
|
1352
|
+
};
|
|
1353
|
+
async function run$D(argv, importMeta, {
|
|
1354
|
+
parentName
|
|
1355
|
+
}) {
|
|
1356
|
+
const cli = meowOrExit({
|
|
1357
|
+
argv,
|
|
1358
|
+
config: config$D,
|
|
1359
|
+
importMeta,
|
|
1360
|
+
parentName
|
|
1361
|
+
});
|
|
1362
|
+
const {
|
|
1363
|
+
json,
|
|
1364
|
+
markdown
|
|
1365
|
+
} = cli.flags;
|
|
1366
|
+
const [key = ''] = cli.input;
|
|
1367
|
+
if (!shadowNpmInject.supportedConfigKeys.has(key) && key !== 'test') {
|
|
1368
|
+
// Use exit status of 2 to indicate incorrect usage, generally invalid
|
|
1369
|
+
// options or missing arguments.
|
|
1370
|
+
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
1371
|
+
process.exitCode = 2;
|
|
1372
|
+
logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
1373
|
+
|
|
1374
|
+
- Config key should be the first arg ${!key ? colors.red('(missing!)') : !shadowNpmInject.supportedConfigKeys.has(key) ? colors.red('(invalid config key!)') : colors.green('(ok)')}
|
|
1375
|
+
`);
|
|
1376
|
+
return;
|
|
1377
|
+
}
|
|
1378
|
+
if (cli.flags['dryRun']) {
|
|
1379
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$C);
|
|
1380
|
+
return;
|
|
1381
|
+
}
|
|
1382
|
+
await handleConfigGet({
|
|
1383
|
+
key: key,
|
|
1384
|
+
outputKind: json ? 'json' : markdown ? 'markdown' : 'text'
|
|
1385
|
+
});
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
async function outputConfigList({
|
|
1389
|
+
full,
|
|
1390
|
+
outputKind
|
|
1391
|
+
}) {
|
|
1392
|
+
if (outputKind === 'json') {
|
|
1393
|
+
const obj = {};
|
|
1394
|
+
for (const key of shadowNpmInject.supportedConfigKeys.keys()) {
|
|
1395
|
+
let value = shadowNpmInject.getConfigValue(key);
|
|
1396
|
+
if (!full && shadowNpmInject.sensitiveConfigKeys.has(key)) {
|
|
1397
|
+
value = '********';
|
|
1398
|
+
}
|
|
1399
|
+
if (full || value !== undefined) {
|
|
1400
|
+
obj[key] = value ?? '<none>';
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
logger.logger.log(JSON.stringify({
|
|
1404
|
+
success: true,
|
|
1405
|
+
full,
|
|
1406
|
+
config: obj
|
|
1407
|
+
}, null, 2));
|
|
1408
|
+
} else {
|
|
1409
|
+
const maxWidth = Array.from(shadowNpmInject.supportedConfigKeys.keys()).reduce((a, b) => Math.max(a, b.length), 0);
|
|
1410
|
+
logger.logger.log('# Local CLI Config');
|
|
1411
|
+
logger.logger.log('');
|
|
1412
|
+
logger.logger.log(`This is the local CLI config (full=${!!full}):`);
|
|
1413
|
+
logger.logger.log('');
|
|
1414
|
+
for (const key of shadowNpmInject.supportedConfigKeys.keys()) {
|
|
1415
|
+
let value = shadowNpmInject.getConfigValue(key);
|
|
1416
|
+
if (!full && shadowNpmInject.sensitiveConfigKeys.has(key)) {
|
|
1417
|
+
value = '********';
|
|
1418
|
+
}
|
|
1419
|
+
if (full || value !== undefined) {
|
|
1420
|
+
logger.logger.log(`- ${key}:${' '.repeat(Math.max(0, maxWidth - key.length + 3))} ${Array.isArray(value) ? value.join(', ') || '<none>' : value ?? '<none>'}`);
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1426
|
+
const {
|
|
1427
|
+
DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$B
|
|
1428
|
+
} = constants;
|
|
1429
|
+
const config$C = {
|
|
1430
|
+
commandName: 'list',
|
|
1431
|
+
description: 'Show all local CLI config items and their values',
|
|
1432
|
+
hidden: false,
|
|
1433
|
+
flags: {
|
|
1434
|
+
...commonFlags,
|
|
1435
|
+
...outputFlags,
|
|
1436
|
+
full: {
|
|
1437
|
+
type: 'boolean',
|
|
1438
|
+
default: false,
|
|
1439
|
+
description: 'Show full tokens in plaintext (unsafe)'
|
|
1440
|
+
}
|
|
1441
|
+
},
|
|
1442
|
+
help: (command, config) => `
|
|
1443
|
+
Usage
|
|
1444
|
+
$ ${command} <org slug>
|
|
1445
|
+
|
|
1446
|
+
Options
|
|
1447
|
+
${getFlagListOutput(config.flags, 6)}
|
|
1448
|
+
|
|
1449
|
+
Keys:
|
|
1450
|
+
|
|
1451
|
+
${Array.from(shadowNpmInject.supportedConfigKeys.entries()).map(([key, desc]) => ` - ${key} -- ${desc}`).join('\n')}
|
|
1452
|
+
|
|
1453
|
+
Examples
|
|
1454
|
+
$ ${command} FakeOrg --repoName=test-repo
|
|
1455
|
+
`
|
|
1456
|
+
};
|
|
1457
|
+
const cmdConfigList = {
|
|
1458
|
+
description: config$C.description,
|
|
1459
|
+
hidden: config$C.hidden,
|
|
1460
|
+
run: run$C
|
|
1461
|
+
};
|
|
1462
|
+
async function run$C(argv, importMeta, {
|
|
1463
|
+
parentName
|
|
1464
|
+
}) {
|
|
1465
|
+
const cli = meowOrExit({
|
|
1466
|
+
argv,
|
|
1467
|
+
config: config$C,
|
|
1468
|
+
importMeta,
|
|
1469
|
+
parentName
|
|
1470
|
+
});
|
|
1471
|
+
const {
|
|
1472
|
+
full,
|
|
1473
|
+
json,
|
|
1474
|
+
markdown
|
|
1475
|
+
} = cli.flags;
|
|
1476
|
+
if (cli.flags['dryRun']) {
|
|
1477
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$B);
|
|
1478
|
+
return;
|
|
1479
|
+
}
|
|
1480
|
+
await outputConfigList({
|
|
1481
|
+
full: !!full,
|
|
1482
|
+
outputKind: json ? 'json' : markdown ? 'markdown' : 'text'
|
|
1483
|
+
});
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
async function outputConfigSet(key, _value, outputKind) {
|
|
1487
|
+
if (outputKind === 'json') {
|
|
1488
|
+
logger.logger.log(JSON.stringify({
|
|
1489
|
+
success: true,
|
|
1490
|
+
message: `Config key '${key}' was updated`
|
|
1491
|
+
}));
|
|
1492
|
+
} else if (outputKind === 'markdown') {
|
|
1493
|
+
logger.logger.log(`# Update config`);
|
|
1494
|
+
logger.logger.log('');
|
|
1495
|
+
logger.logger.log(`Config key '${key}' was updated`);
|
|
1496
|
+
} else {
|
|
1497
|
+
logger.logger.log(`OK`);
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
async function handleConfigSet({
|
|
1502
|
+
key,
|
|
1503
|
+
outputKind,
|
|
1504
|
+
value
|
|
1505
|
+
}) {
|
|
1506
|
+
shadowNpmInject.updateConfigValue(key, value);
|
|
1507
|
+
await outputConfigSet(key, value, outputKind);
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
const {
|
|
1511
|
+
DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$A
|
|
1512
|
+
} = constants;
|
|
1513
|
+
const config$B = {
|
|
1514
|
+
commandName: 'set',
|
|
1515
|
+
description: 'Update the value of a local CLI config item',
|
|
1516
|
+
hidden: false,
|
|
1517
|
+
flags: {
|
|
1518
|
+
...commonFlags,
|
|
1519
|
+
...outputFlags
|
|
1520
|
+
},
|
|
1521
|
+
help: (command, config) => `
|
|
1522
|
+
Usage
|
|
1523
|
+
$ ${command} <key> <value>
|
|
1524
|
+
|
|
1525
|
+
Options
|
|
1526
|
+
${getFlagListOutput(config.flags, 6)}
|
|
1527
|
+
|
|
1528
|
+
This is a crude way of updating the local configuration for this CLI tool.
|
|
1529
|
+
|
|
1530
|
+
Note that updating a value here is nothing more than updating a key/value
|
|
1531
|
+
store entry. No validation is happening. The server may reject your config.
|
|
1532
|
+
|
|
1533
|
+
Keys:
|
|
1534
|
+
|
|
1535
|
+
${Array.from(shadowNpmInject.supportedConfigKeys.entries()).map(([key, desc]) => ` - ${key} -- ${desc}`).join('\n')}
|
|
1536
|
+
|
|
1537
|
+
Examples
|
|
1538
|
+
$ ${command} apiProxy https://example.com
|
|
1539
|
+
`
|
|
1540
|
+
};
|
|
1541
|
+
const cmdConfigSet = {
|
|
1542
|
+
description: config$B.description,
|
|
1543
|
+
hidden: config$B.hidden,
|
|
1544
|
+
run: run$B
|
|
1545
|
+
};
|
|
1546
|
+
async function run$B(argv, importMeta, {
|
|
1547
|
+
parentName
|
|
1548
|
+
}) {
|
|
1549
|
+
const cli = meowOrExit({
|
|
1550
|
+
argv,
|
|
1551
|
+
config: config$B,
|
|
1552
|
+
importMeta,
|
|
1553
|
+
parentName
|
|
1554
|
+
});
|
|
1555
|
+
const {
|
|
1556
|
+
json,
|
|
1557
|
+
markdown
|
|
1558
|
+
} = cli.flags;
|
|
1559
|
+
const [key = '', ...rest] = cli.input;
|
|
1560
|
+
const value = rest.join(' ');
|
|
1561
|
+
if (!shadowNpmInject.supportedConfigKeys.has(key) && key !== 'test' || !value) {
|
|
1562
|
+
// Use exit status of 2 to indicate incorrect usage, generally invalid
|
|
1563
|
+
// options or missing arguments.
|
|
1564
|
+
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
1565
|
+
process.exitCode = 2;
|
|
1566
|
+
logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
1567
|
+
|
|
1568
|
+
- Config key should be the first arg ${!key ? colors.red('(missing!)') : !shadowNpmInject.supportedConfigKeys.has(key) ? colors.red('(invalid config key!)') : colors.green('(ok)')}
|
|
1569
|
+
|
|
1570
|
+
- Key value should be the remaining args (use \`del\` to unset a value) ${!value ? colors.red('(missing!)') : colors.green('(ok)')}`);
|
|
1571
|
+
return;
|
|
1572
|
+
}
|
|
1573
|
+
if (cli.flags['dryRun']) {
|
|
1574
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$A);
|
|
1575
|
+
return;
|
|
1576
|
+
}
|
|
1577
|
+
await handleConfigSet({
|
|
1578
|
+
key: key,
|
|
1579
|
+
outputKind: json ? 'json' : markdown ? 'markdown' : 'text',
|
|
1580
|
+
value
|
|
1581
|
+
});
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
async function outputConfigUnset(key, outputKind) {
|
|
1585
|
+
if (outputKind === 'json') {
|
|
1586
|
+
logger.logger.log(JSON.stringify({
|
|
1587
|
+
success: true,
|
|
1588
|
+
message: `Config key '${key}' was unset`
|
|
1589
|
+
}));
|
|
1590
|
+
} else if (outputKind === 'markdown') {
|
|
1591
|
+
logger.logger.log(`# Update config`);
|
|
1592
|
+
logger.logger.log('');
|
|
1593
|
+
logger.logger.log(`Config key '${key}' was unset`);
|
|
1594
|
+
} else {
|
|
1595
|
+
logger.logger.log(`OK`);
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
async function handleConfigUnset({
|
|
1600
|
+
key,
|
|
1601
|
+
outputKind
|
|
1602
|
+
}) {
|
|
1603
|
+
shadowNpmInject.updateConfigValue(key, undefined);
|
|
1604
|
+
await outputConfigUnset(key, outputKind);
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
const {
|
|
1608
|
+
DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$z
|
|
1609
|
+
} = constants;
|
|
1610
|
+
const config$A = {
|
|
1611
|
+
commandName: 'unset',
|
|
1612
|
+
description: 'Clear the value of a local CLI config item',
|
|
1613
|
+
hidden: false,
|
|
1614
|
+
flags: {
|
|
1615
|
+
...commonFlags,
|
|
1616
|
+
...outputFlags
|
|
1617
|
+
},
|
|
1618
|
+
help: (command, config) => `
|
|
1619
|
+
Usage
|
|
1620
|
+
$ ${command} <org slug>
|
|
1621
|
+
|
|
1622
|
+
Options
|
|
1623
|
+
${getFlagListOutput(config.flags, 6)}
|
|
1624
|
+
|
|
1625
|
+
Keys:
|
|
1626
|
+
|
|
1627
|
+
${Array.from(shadowNpmInject.supportedConfigKeys.entries()).map(([key, desc]) => ` - ${key} -- ${desc}`).join('\n')}
|
|
1628
|
+
|
|
1629
|
+
Examples
|
|
1630
|
+
$ ${command} FakeOrg --repoName=test-repo
|
|
1631
|
+
`
|
|
1632
|
+
};
|
|
1633
|
+
const cmdConfigUnset = {
|
|
1634
|
+
description: config$A.description,
|
|
1635
|
+
hidden: config$A.hidden,
|
|
1636
|
+
run: run$A
|
|
1637
|
+
};
|
|
1638
|
+
async function run$A(argv, importMeta, {
|
|
1639
|
+
parentName
|
|
1640
|
+
}) {
|
|
1641
|
+
const cli = meowOrExit({
|
|
1642
|
+
argv,
|
|
1643
|
+
config: config$A,
|
|
1644
|
+
importMeta,
|
|
1645
|
+
parentName
|
|
1646
|
+
});
|
|
1647
|
+
const {
|
|
1648
|
+
json,
|
|
1649
|
+
markdown
|
|
1650
|
+
} = cli.flags;
|
|
1651
|
+
const [key = ''] = cli.input;
|
|
1652
|
+
if (!shadowNpmInject.supportedConfigKeys.has(key) && key !== 'test') {
|
|
1653
|
+
// Use exit status of 2 to indicate incorrect usage, generally invalid
|
|
1654
|
+
// options or missing arguments.
|
|
1655
|
+
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
1656
|
+
process.exitCode = 2;
|
|
1657
|
+
logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
1658
|
+
|
|
1659
|
+
- Config key should be the first arg ${!key ? colors.red('(missing!)') : !shadowNpmInject.supportedConfigKeys.has(key) ? colors.red('(invalid config key!)') : colors.green('(ok)')}
|
|
1660
|
+
`);
|
|
1661
|
+
return;
|
|
1662
|
+
}
|
|
1663
|
+
if (cli.flags['dryRun']) {
|
|
1664
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$z);
|
|
1665
|
+
return;
|
|
1666
|
+
}
|
|
1667
|
+
await handleConfigUnset({
|
|
1668
|
+
key: key,
|
|
1669
|
+
outputKind: json ? 'json' : markdown ? 'markdown' : 'text'
|
|
1670
|
+
});
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
const description$7 = 'Commands related to the local CLI configuration';
|
|
1674
|
+
const cmdConfig = {
|
|
1675
|
+
description: description$7,
|
|
1676
|
+
hidden: true,
|
|
1677
|
+
// [beta]
|
|
1678
|
+
async run(argv, importMeta, {
|
|
1679
|
+
parentName
|
|
1680
|
+
}) {
|
|
1681
|
+
await meowWithSubcommands({
|
|
1682
|
+
unset: cmdConfigUnset,
|
|
1683
|
+
get: cmdConfigGet,
|
|
1684
|
+
list: cmdConfigList,
|
|
1685
|
+
set: cmdConfigSet
|
|
1686
|
+
}, {
|
|
1687
|
+
argv,
|
|
1688
|
+
description: description$7,
|
|
1689
|
+
importMeta,
|
|
1690
|
+
name: `${parentName} config`
|
|
1691
|
+
});
|
|
1692
|
+
}
|
|
1693
|
+
};
|
|
1694
|
+
|
|
1297
1695
|
async function fetchDependencies({
|
|
1298
1696
|
limit,
|
|
1299
1697
|
offset
|
|
@@ -1316,8 +1714,8 @@ async function fetchDependenciesWithToken(apiToken, {
|
|
|
1316
1714
|
spinner
|
|
1317
1715
|
} = constants;
|
|
1318
1716
|
spinner.start('Fetching organization dependencies...');
|
|
1319
|
-
const
|
|
1320
|
-
const result = await handleApiCall(
|
|
1717
|
+
const sockSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
1718
|
+
const result = await handleApiCall(sockSdk.searchDependencies({
|
|
1321
1719
|
limit,
|
|
1322
1720
|
offset
|
|
1323
1721
|
}), 'Searching dependencies');
|
|
@@ -1830,12 +2228,12 @@ async function getAlertsMapFromPnpmLockfile(lockfile, options) {
|
|
|
1830
2228
|
}
|
|
1831
2229
|
const getText = () => `Looking up data for ${remaining} packages`;
|
|
1832
2230
|
spinner?.start(getText());
|
|
1833
|
-
const
|
|
2231
|
+
const sockSdk = await shadowNpmInject.setupSdk(shadowNpmInject.getPublicToken());
|
|
1834
2232
|
const toAlertsMapOptions = {
|
|
1835
2233
|
overrides: lockfile.overrides,
|
|
1836
2234
|
...options
|
|
1837
2235
|
};
|
|
1838
|
-
for await (const batchPackageFetchResult of
|
|
2236
|
+
for await (const batchPackageFetchResult of sockSdk.batchPackageStream({
|
|
1839
2237
|
alerts: 'true',
|
|
1840
2238
|
compact: 'true',
|
|
1841
2239
|
fixable: include.unfixable ? 'false' : 'true'
|
|
@@ -2436,15 +2834,15 @@ async function run$x(argv, importMeta, {
|
|
|
2436
2834
|
}
|
|
2437
2835
|
|
|
2438
2836
|
async function fetchPackageInfo(pkgName, pkgVersion, includeAllIssues) {
|
|
2439
|
-
const
|
|
2837
|
+
const sockSdk = await shadowNpmInject.setupSdk(shadowNpmInject.getPublicToken());
|
|
2440
2838
|
|
|
2441
2839
|
// Lazily access constants.spinner.
|
|
2442
2840
|
const {
|
|
2443
2841
|
spinner
|
|
2444
2842
|
} = constants;
|
|
2445
2843
|
spinner.start(pkgVersion === 'latest' ? `Looking up data for the latest version of ${pkgName}` : `Looking up data for version ${pkgVersion} of ${pkgName}`);
|
|
2446
|
-
const result = await handleApiCall(
|
|
2447
|
-
const scoreResult = await handleApiCall(
|
|
2844
|
+
const result = await handleApiCall(sockSdk.getIssuesByNPMPackage(pkgName, pkgVersion), 'looking up package');
|
|
2845
|
+
const scoreResult = await handleApiCall(sockSdk.getScoreByNPMPackage(pkgName, pkgVersion), 'looking up package score');
|
|
2448
2846
|
spinner.successAndStop('Data fetched');
|
|
2449
2847
|
if (result.success === false) {
|
|
2450
2848
|
return handleUnsuccessfulApiResponse('getIssuesByNPMPackage', result);
|
|
@@ -2659,18 +3057,18 @@ async function run$w(argv, importMeta, {
|
|
|
2659
3057
|
}
|
|
2660
3058
|
|
|
2661
3059
|
function applyLogin(apiToken, enforcedOrgs, apiBaseUrl, apiProxy) {
|
|
2662
|
-
shadowNpmInject.
|
|
2663
|
-
shadowNpmInject.
|
|
2664
|
-
shadowNpmInject.
|
|
2665
|
-
shadowNpmInject.
|
|
3060
|
+
shadowNpmInject.updateConfigValue('enforcedOrgs', enforcedOrgs);
|
|
3061
|
+
shadowNpmInject.updateConfigValue('apiToken', apiToken);
|
|
3062
|
+
shadowNpmInject.updateConfigValue('apiBaseUrl', apiBaseUrl);
|
|
3063
|
+
shadowNpmInject.updateConfigValue('apiProxy', apiProxy);
|
|
2666
3064
|
}
|
|
2667
3065
|
|
|
2668
3066
|
const {
|
|
2669
3067
|
SOCKET_PUBLIC_API_TOKEN
|
|
2670
3068
|
} = constants;
|
|
2671
3069
|
async function attemptLogin(apiBaseUrl, apiProxy) {
|
|
2672
|
-
apiBaseUrl ??= shadowNpmInject.
|
|
2673
|
-
apiProxy ??= shadowNpmInject.
|
|
3070
|
+
apiBaseUrl ??= shadowNpmInject.getConfigValue('apiBaseUrl') ?? undefined;
|
|
3071
|
+
apiProxy ??= shadowNpmInject.getConfigValue('apiProxy') ?? undefined;
|
|
2674
3072
|
const apiToken = (await prompts.password({
|
|
2675
3073
|
message: `Enter your ${terminalLink('Socket.dev API key', 'https://docs.socket.dev/docs/api-keys')} (leave blank for a public key)`
|
|
2676
3074
|
})) || SOCKET_PUBLIC_API_TOKEN;
|
|
@@ -2726,7 +3124,7 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
|
|
|
2726
3124
|
}
|
|
2727
3125
|
}
|
|
2728
3126
|
spinner.stop();
|
|
2729
|
-
const oldToken = shadowNpmInject.
|
|
3127
|
+
const oldToken = shadowNpmInject.getConfigValue('apiToken');
|
|
2730
3128
|
try {
|
|
2731
3129
|
applyLogin(apiToken, enforcedOrgs, apiBaseUrl, apiProxy);
|
|
2732
3130
|
logger.logger.success(`API credentials ${oldToken ? 'updated' : 'set'}`);
|
|
@@ -2794,10 +3192,10 @@ async function run$v(argv, importMeta, {
|
|
|
2794
3192
|
}
|
|
2795
3193
|
|
|
2796
3194
|
function applyLogout() {
|
|
2797
|
-
shadowNpmInject.
|
|
2798
|
-
shadowNpmInject.
|
|
2799
|
-
shadowNpmInject.
|
|
2800
|
-
shadowNpmInject.
|
|
3195
|
+
shadowNpmInject.updateConfigValue('apiToken', null);
|
|
3196
|
+
shadowNpmInject.updateConfigValue('apiBaseUrl', null);
|
|
3197
|
+
shadowNpmInject.updateConfigValue('apiProxy', null);
|
|
3198
|
+
shadowNpmInject.updateConfigValue('enforcedOrgs', null);
|
|
2801
3199
|
}
|
|
2802
3200
|
|
|
2803
3201
|
function attemptLogout() {
|
|
@@ -4546,14 +4944,14 @@ async function fetchOrganization() {
|
|
|
4546
4944
|
return await fetchOrganizationWithToken(apiToken);
|
|
4547
4945
|
}
|
|
4548
4946
|
async function fetchOrganizationWithToken(apiToken) {
|
|
4549
|
-
const
|
|
4947
|
+
const sockSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
4550
4948
|
|
|
4551
4949
|
// Lazily access constants.spinner.
|
|
4552
4950
|
const {
|
|
4553
4951
|
spinner
|
|
4554
4952
|
} = constants;
|
|
4555
4953
|
spinner.start('Fetching organization list...');
|
|
4556
|
-
const result = await handleApiCall(
|
|
4954
|
+
const result = await handleApiCall(sockSdk.getOrganizations(), 'looking up organizations');
|
|
4557
4955
|
spinner.successAndStop('Received organization list response.');
|
|
4558
4956
|
if (!result.success) {
|
|
4559
4957
|
handleUnsuccessfulApiResponse('getOrganizations', result);
|
|
@@ -4683,9 +5081,9 @@ async function fetchSecurityPolicyWithToken(apiToken, orgSlug) {
|
|
|
4683
5081
|
const {
|
|
4684
5082
|
spinner
|
|
4685
5083
|
} = constants;
|
|
4686
|
-
const
|
|
5084
|
+
const sockSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
4687
5085
|
spinner.start('Fetching organization quota...');
|
|
4688
|
-
const result = await handleApiCall(
|
|
5086
|
+
const result = await handleApiCall(sockSdk.getOrgSecurityPolicy(orgSlug), 'looking up organization quota');
|
|
4689
5087
|
spinner?.successAndStop('Received organization quota response.');
|
|
4690
5088
|
if (!result.success) {
|
|
4691
5089
|
handleUnsuccessfulApiResponse('getOrgSecurityPolicy', result);
|
|
@@ -4828,9 +5226,9 @@ async function fetchQuotaWithToken(apiToken) {
|
|
|
4828
5226
|
const {
|
|
4829
5227
|
spinner
|
|
4830
5228
|
} = constants;
|
|
4831
|
-
const
|
|
5229
|
+
const sockSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
4832
5230
|
spinner.start('Fetching organization quota...');
|
|
4833
|
-
const result = await handleApiCall(
|
|
5231
|
+
const result = await handleApiCall(sockSdk.getQuota(), 'looking up organization quota');
|
|
4834
5232
|
spinner?.successAndStop('Recieved organization quota response.');
|
|
4835
5233
|
if (!result.success) {
|
|
4836
5234
|
handleUnsuccessfulApiResponse('getQuota', result);
|
|
@@ -4957,8 +5355,8 @@ async function fetchPurlsShallowScore(purls) {
|
|
|
4957
5355
|
spinner
|
|
4958
5356
|
} = constants;
|
|
4959
5357
|
spinner.start(`Requesting data ...`);
|
|
4960
|
-
const
|
|
4961
|
-
const result = await handleApiCall(
|
|
5358
|
+
const sockSdk = await shadowNpmInject.setupSdk(shadowNpmInject.getPublicToken());
|
|
5359
|
+
const result = await handleApiCall(sockSdk.batchPackageFetch({
|
|
4962
5360
|
alerts: 'true'
|
|
4963
5361
|
// compact: false,
|
|
4964
5362
|
// fixable: false,
|
|
@@ -5359,8 +5757,8 @@ async function createReport(socketConfig, inputPaths, {
|
|
|
5359
5757
|
const {
|
|
5360
5758
|
spinner
|
|
5361
5759
|
} = constants;
|
|
5362
|
-
const
|
|
5363
|
-
const supportedFiles = await
|
|
5760
|
+
const sockSdk = await shadowNpmInject.setupSdk();
|
|
5761
|
+
const supportedFiles = await sockSdk.getReportSupportedFiles().then(res => {
|
|
5364
5762
|
if (!res.success) handleUnsuccessfulApiResponse('getReportSupportedFiles', res);
|
|
5365
5763
|
return res.data;
|
|
5366
5764
|
}).catch(cause => {
|
|
@@ -5368,7 +5766,7 @@ async function createReport(socketConfig, inputPaths, {
|
|
|
5368
5766
|
cause
|
|
5369
5767
|
});
|
|
5370
5768
|
});
|
|
5371
|
-
const packagePaths = await shadowNpmPaths.
|
|
5769
|
+
const packagePaths = await shadowNpmPaths.getPackageFilesForScan(cwd, inputPaths, supportedFiles, socketConfig);
|
|
5372
5770
|
const packagePathsCount = packagePaths.length;
|
|
5373
5771
|
if (packagePathsCount && debug.isDebug()) {
|
|
5374
5772
|
for (const pkgPath of packagePaths) {
|
|
@@ -5380,7 +5778,7 @@ async function createReport(socketConfig, inputPaths, {
|
|
|
5380
5778
|
return undefined;
|
|
5381
5779
|
}
|
|
5382
5780
|
spinner.start(`Creating report with ${packagePathsCount} package ${words.pluralize('file', packagePathsCount)}`);
|
|
5383
|
-
const apiCall =
|
|
5781
|
+
const apiCall = sockSdk.createReportFromFilePaths(packagePaths, cwd, socketConfig?.issueRules);
|
|
5384
5782
|
const result = await handleApiCall(apiCall, 'creating report');
|
|
5385
5783
|
if (!result.success) {
|
|
5386
5784
|
handleUnsuccessfulApiResponse('createReport', result);
|
|
@@ -5391,8 +5789,8 @@ async function createReport(socketConfig, inputPaths, {
|
|
|
5391
5789
|
}
|
|
5392
5790
|
|
|
5393
5791
|
async function getSocketConfig(absoluteConfigPath) {
|
|
5394
|
-
const socketConfig = await config$
|
|
5395
|
-
if (cause && typeof cause === 'object' && cause instanceof config$
|
|
5792
|
+
const socketConfig = await config$H.readSocketConfig(absoluteConfigPath).catch(cause => {
|
|
5793
|
+
if (cause && typeof cause === 'object' && cause instanceof config$H.SocketValidationError) {
|
|
5396
5794
|
// Inspired by workbox-build:
|
|
5397
5795
|
// https://github.com/GoogleChrome/workbox/blob/95f97a207fd51efb3f8a653f6e3e58224183a778/packages/workbox-build/src/lib/validate-options.ts#L68-L71
|
|
5398
5796
|
const betterErrors = betterAjvErrors.betterAjvErrors({
|
|
@@ -5420,12 +5818,12 @@ async function fetchReportData$1(reportId, includeAllIssues, strict) {
|
|
|
5420
5818
|
} = constants;
|
|
5421
5819
|
spinner.log('Fetching report with ID ${reportId} (this could take a while)');
|
|
5422
5820
|
spinner.start(`Fetch started... (this could take a while)`);
|
|
5423
|
-
const
|
|
5821
|
+
const sockSdk = await shadowNpmInject.setupSdk();
|
|
5424
5822
|
let result;
|
|
5425
5823
|
for (let retry = 1; !result; ++retry) {
|
|
5426
5824
|
try {
|
|
5427
5825
|
// eslint-disable-next-line no-await-in-loop
|
|
5428
|
-
result = await handleApiCall(
|
|
5826
|
+
result = await handleApiCall(sockSdk.getReport(reportId), 'fetching report');
|
|
5429
5827
|
} catch (err) {
|
|
5430
5828
|
if (retry >= MAX_TIMEOUT_RETRY || !(err instanceof Error) || err.cause?.cause?.response?.statusCode !== HTTP_CODE_TIMEOUT) {
|
|
5431
5829
|
spinner.stop(`Failed to fetch report`);
|
|
@@ -5477,7 +5875,7 @@ function formatReportDataOutput(reportId, data, commandName, outputKind, strict,
|
|
|
5477
5875
|
}
|
|
5478
5876
|
}
|
|
5479
5877
|
|
|
5480
|
-
async function
|
|
5878
|
+
async function fetchScan(orgSlug, scanId) {
|
|
5481
5879
|
// Lazily access constants.spinner.
|
|
5482
5880
|
const {
|
|
5483
5881
|
spinner
|
|
@@ -5487,7 +5885,7 @@ async function getFullScan(orgSlug, fullScanId) {
|
|
|
5487
5885
|
throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
|
|
5488
5886
|
}
|
|
5489
5887
|
spinner.start('Fetching full-scan...');
|
|
5490
|
-
const response = await queryApi(`orgs/${orgSlug}/full-scans/${encodeURIComponent(
|
|
5888
|
+
const response = await queryApi(`orgs/${orgSlug}/full-scans/${encodeURIComponent(scanId)}`, apiToken);
|
|
5491
5889
|
spinner.stop('Fetch complete.');
|
|
5492
5890
|
if (!response.ok) {
|
|
5493
5891
|
const err = await handleApiError(response.status);
|
|
@@ -5516,7 +5914,7 @@ async function viewReport(reportId, {
|
|
|
5516
5914
|
strict
|
|
5517
5915
|
}) {
|
|
5518
5916
|
const result = await fetchReportData$1(reportId, all, strict);
|
|
5519
|
-
const artifacts = await
|
|
5917
|
+
const artifacts = await fetchScan('socketdev', reportId);
|
|
5520
5918
|
if (result) {
|
|
5521
5919
|
formatReportDataOutput(reportId, result, commandName, outputKind, strict, artifacts);
|
|
5522
5920
|
}
|
|
@@ -5717,9 +6115,9 @@ async function fetchCreateRepoWithToken(apiToken, {
|
|
|
5717
6115
|
const {
|
|
5718
6116
|
spinner
|
|
5719
6117
|
} = constants;
|
|
5720
|
-
const
|
|
6118
|
+
const sockSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
5721
6119
|
spinner.start('Sending request ot create a repository...');
|
|
5722
|
-
const result = await handleApiCall(
|
|
6120
|
+
const result = await handleApiCall(sockSdk.createOrgRepo(orgSlug, {
|
|
5723
6121
|
name: repoName,
|
|
5724
6122
|
description,
|
|
5725
6123
|
homepage,
|
|
@@ -5864,8 +6262,8 @@ async function deleteRepoWithToken(orgSlug, repoName, apiToken) {
|
|
|
5864
6262
|
spinner
|
|
5865
6263
|
} = constants;
|
|
5866
6264
|
spinner.start('Deleting repository...');
|
|
5867
|
-
const
|
|
5868
|
-
const result = await handleApiCall(
|
|
6265
|
+
const sockSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
6266
|
+
const result = await handleApiCall(sockSdk.deleteOrgRepo(orgSlug, repoName), 'deleting repository');
|
|
5869
6267
|
if (!result.success) {
|
|
5870
6268
|
handleUnsuccessfulApiResponse('deleteOrgRepo', result);
|
|
5871
6269
|
return;
|
|
@@ -5960,9 +6358,9 @@ async function fetchListReposWithToken(apiToken, {
|
|
|
5960
6358
|
const {
|
|
5961
6359
|
spinner
|
|
5962
6360
|
} = constants;
|
|
5963
|
-
const
|
|
6361
|
+
const sockSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
5964
6362
|
spinner.start('Fetching list of repositories...');
|
|
5965
|
-
const result = await handleApiCall(
|
|
6363
|
+
const result = await handleApiCall(sockSdk.getOrgRepoList(orgSlug, {
|
|
5966
6364
|
sort,
|
|
5967
6365
|
direction,
|
|
5968
6366
|
per_page: String(per_page),
|
|
@@ -6149,8 +6547,8 @@ async function fetchUpdateRepoWithToken(apiToken, {
|
|
|
6149
6547
|
spinner
|
|
6150
6548
|
} = constants;
|
|
6151
6549
|
spinner.start('Sending request to update a repository...');
|
|
6152
|
-
const
|
|
6153
|
-
const result = await handleApiCall(
|
|
6550
|
+
const sockSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
6551
|
+
const result = await handleApiCall(sockSdk.updateOrgRepo(orgSlug, repoName, {
|
|
6154
6552
|
orgSlug,
|
|
6155
6553
|
name: repoName,
|
|
6156
6554
|
description,
|
|
@@ -6297,9 +6695,9 @@ async function fetchViewRepoWithToken(orgSlug, repoName, apiToken) {
|
|
|
6297
6695
|
const {
|
|
6298
6696
|
spinner
|
|
6299
6697
|
} = constants;
|
|
6300
|
-
const
|
|
6698
|
+
const sockSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
6301
6699
|
spinner.start('Fetching repository data...');
|
|
6302
|
-
const result = await handleApiCall(
|
|
6700
|
+
const result = await handleApiCall(sockSdk.getOrgRepo(orgSlug, repoName), 'fetching repository');
|
|
6303
6701
|
spinner.successAndStop('Received response while fetched repository data.');
|
|
6304
6702
|
if (!result.success) {
|
|
6305
6703
|
handleUnsuccessfulApiResponse('getOrgRepo', result);
|
|
@@ -6453,8 +6851,106 @@ const cmdRepos = {
|
|
|
6453
6851
|
}
|
|
6454
6852
|
};
|
|
6455
6853
|
|
|
6456
|
-
async function
|
|
6457
|
-
const
|
|
6854
|
+
async function fetchCreateOrgFullScan(packagePaths, orgSlug, repoName, branchName, commitMessage, defaultBranch, pendingHead, tmp, cwd) {
|
|
6855
|
+
const sockSdk = await shadowNpmInject.setupSdk();
|
|
6856
|
+
|
|
6857
|
+
// Lazily access constants.spinner.
|
|
6858
|
+
const {
|
|
6859
|
+
spinner
|
|
6860
|
+
} = constants;
|
|
6861
|
+
spinner.start(`Creating a scan with ${packagePaths.length} packages...`);
|
|
6862
|
+
const result = await handleApiCall(sockSdk.createOrgFullScan(orgSlug, {
|
|
6863
|
+
repo: repoName,
|
|
6864
|
+
branch: branchName,
|
|
6865
|
+
commit_message: commitMessage,
|
|
6866
|
+
make_default_branch: String(defaultBranch),
|
|
6867
|
+
set_as_pending_head: String(pendingHead),
|
|
6868
|
+
tmp: String(tmp)
|
|
6869
|
+
}, packagePaths, cwd), 'Creating scan');
|
|
6870
|
+
spinner.successAndStop('Scan created successfully');
|
|
6871
|
+
if (!result.success) {
|
|
6872
|
+
handleUnsuccessfulApiResponse('CreateOrgFullScan', result);
|
|
6873
|
+
return;
|
|
6874
|
+
}
|
|
6875
|
+
return result.data;
|
|
6876
|
+
}
|
|
6877
|
+
|
|
6878
|
+
async function fetchSupportedScanFileNames() {
|
|
6879
|
+
const sockSdk = await shadowNpmInject.setupSdk();
|
|
6880
|
+
|
|
6881
|
+
// Lazily access constants.spinner.
|
|
6882
|
+
const {
|
|
6883
|
+
spinner
|
|
6884
|
+
} = constants;
|
|
6885
|
+
spinner.start('Requesting supported scan file types from API...');
|
|
6886
|
+
const result = await handleApiCall(sockSdk.getReportSupportedFiles(), 'fetching supported scan file types');
|
|
6887
|
+
spinner.successAndStop('Received response while fetched supported scan file types.');
|
|
6888
|
+
if (!result.success) {
|
|
6889
|
+
handleUnsuccessfulApiResponse('getReportSupportedFiles', result);
|
|
6890
|
+
return;
|
|
6891
|
+
}
|
|
6892
|
+
return result.data;
|
|
6893
|
+
}
|
|
6894
|
+
|
|
6895
|
+
async function outputCreateNewScan(data) {
|
|
6896
|
+
const link = colors.underline(colors.cyan(`${data.html_report_url}`));
|
|
6897
|
+
logger.logger.log(`Available at: ${link}`);
|
|
6898
|
+
const rl = readline.createInterface({
|
|
6899
|
+
input: process$1.stdin,
|
|
6900
|
+
output: process$1.stdout
|
|
6901
|
+
});
|
|
6902
|
+
const answer = await rl.question('Would you like to open it in your browser? (y/n)');
|
|
6903
|
+
if (answer.toLowerCase() === 'y') {
|
|
6904
|
+
await open(`${data.html_report_url}`);
|
|
6905
|
+
}
|
|
6906
|
+
rl.close();
|
|
6907
|
+
}
|
|
6908
|
+
|
|
6909
|
+
async function handleCreateNewScan({
|
|
6910
|
+
branchName,
|
|
6911
|
+
commitMessage,
|
|
6912
|
+
cwd,
|
|
6913
|
+
defaultBranch,
|
|
6914
|
+
orgSlug,
|
|
6915
|
+
pendingHead,
|
|
6916
|
+
readOnly,
|
|
6917
|
+
repoName,
|
|
6918
|
+
targets,
|
|
6919
|
+
tmp
|
|
6920
|
+
}) {
|
|
6921
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
6922
|
+
|
|
6923
|
+
// Note: you need an apiToken to request supportedScanFileNames from the API
|
|
6924
|
+
if (!apiToken) {
|
|
6925
|
+
throw new shadowNpmInject.AuthError('User must be authenticated to create and submit new scans. To log in, run the command `socket login` and enter your API key.');
|
|
6926
|
+
}
|
|
6927
|
+
const supportedFileNames = await fetchSupportedScanFileNames();
|
|
6928
|
+
if (!supportedFileNames) return;
|
|
6929
|
+
const packagePaths = await shadowNpmPaths.getPackageFilesForScan(cwd, targets, supportedFileNames
|
|
6930
|
+
// socketConfig
|
|
6931
|
+
);
|
|
6932
|
+
if (!packagePaths.length) {
|
|
6933
|
+
// Use exit status of 2 to indicate incorrect usage, generally invalid
|
|
6934
|
+
// options or missing arguments.
|
|
6935
|
+
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
6936
|
+
process$1.exitCode = 2;
|
|
6937
|
+
logger.logger.fail(commonTags.stripIndents`
|
|
6938
|
+
${colors.bgRed(colors.white('Input error'))}: The TARGET did not contain any matching / supported files for a scan
|
|
6939
|
+
`);
|
|
6940
|
+
return;
|
|
6941
|
+
}
|
|
6942
|
+
if (readOnly) {
|
|
6943
|
+
logger.logger.log('[ReadOnly] Bailing now');
|
|
6944
|
+
return;
|
|
6945
|
+
}
|
|
6946
|
+
const data = await fetchCreateOrgFullScan(packagePaths, orgSlug, repoName, branchName, commitMessage, defaultBranch, pendingHead, tmp, cwd);
|
|
6947
|
+
if (!data) return;
|
|
6948
|
+
await outputCreateNewScan(data);
|
|
6949
|
+
}
|
|
6950
|
+
|
|
6951
|
+
async function suggestOrgSlug() {
|
|
6952
|
+
const sockSdk = await shadowNpmInject.setupSdk();
|
|
6953
|
+
const result = await handleApiCall(sockSdk.getOrganizations(), 'looking up organizations');
|
|
6458
6954
|
// Ignore a failed request here. It was not the primary goal of
|
|
6459
6955
|
// running this command and reporting it only leads to end-user confusion.
|
|
6460
6956
|
if (result.success) {
|
|
@@ -6475,13 +6971,17 @@ async function suggestOrgSlug(socketSdk) {
|
|
|
6475
6971
|
if (proceed) {
|
|
6476
6972
|
return proceed;
|
|
6477
6973
|
}
|
|
6974
|
+
} else {
|
|
6975
|
+
logger.logger.fail('Failed to lookup organization list from API, unable to suggest.');
|
|
6478
6976
|
}
|
|
6479
6977
|
}
|
|
6480
6978
|
|
|
6481
|
-
async function suggestRepoSlug(
|
|
6979
|
+
async function suggestRepoSlug(orgSlug) {
|
|
6980
|
+
const sockSdk = await shadowNpmInject.setupSdk();
|
|
6981
|
+
|
|
6482
6982
|
// Same as above, but if there's a repo with the same name as cwd then
|
|
6483
6983
|
// default the selection to that name.
|
|
6484
|
-
const result = await handleApiCall(
|
|
6984
|
+
const result = await handleApiCall(sockSdk.getOrgRepoList(orgSlug, {
|
|
6485
6985
|
orgSlug,
|
|
6486
6986
|
sort: 'name',
|
|
6487
6987
|
direction: 'asc',
|
|
@@ -6491,6 +6991,7 @@ async function suggestRepoSlug(socketSdk, orgSlug) {
|
|
|
6491
6991
|
perPage: '10',
|
|
6492
6992
|
page: '0'
|
|
6493
6993
|
}), 'looking up known repos');
|
|
6994
|
+
|
|
6494
6995
|
// Ignore a failed request here. It was not the primary goal of
|
|
6495
6996
|
// running this command and reporting it only leads to end-user confusion.
|
|
6496
6997
|
if (result.success) {
|
|
@@ -6498,7 +6999,7 @@ async function suggestRepoSlug(socketSdk, orgSlug) {
|
|
|
6498
6999
|
let cwdIsKnown = !!currentDirName && result.data.results.some(obj => obj.slug === currentDirName);
|
|
6499
7000
|
if (!cwdIsKnown && currentDirName) {
|
|
6500
7001
|
// Do an explicit request so we can assert that the cwd exists or not
|
|
6501
|
-
const result = await handleApiCall(
|
|
7002
|
+
const result = await handleApiCall(sockSdk.getOrgRepo(orgSlug, currentDirName), 'checking if current cwd is a known repo');
|
|
6502
7003
|
if (result.success) {
|
|
6503
7004
|
cwdIsKnown = true;
|
|
6504
7005
|
}
|
|
@@ -6537,203 +7038,64 @@ async function suggestRepoSlug(socketSdk, orgSlug) {
|
|
|
6537
7038
|
}
|
|
6538
7039
|
});
|
|
6539
7040
|
return {
|
|
6540
|
-
slug: repoName,
|
|
6541
|
-
defaultBranch: repoDefaultBranch
|
|
6542
|
-
};
|
|
6543
|
-
}
|
|
6544
|
-
}
|
|
6545
|
-
}
|
|
6546
|
-
function dirNameToSlug(name) {
|
|
6547
|
-
// Uses slug specs asserted by our servers
|
|
6548
|
-
// Note: this can lead to collisions; eg. slug for `x--y` and `x---y` is `x-y`
|
|
6549
|
-
return name.toLowerCase().replace(/[^[a-zA-Z0-9_.-]/g, '_').replace(/--+/g, '-').replace(/__+/g, '_').replace(/\.\.+/g, '.').replace(/[._-]+$/, '');
|
|
6550
|
-
}
|
|
6551
|
-
|
|
6552
|
-
async function suggestBranchSlug(repoDefaultBranch) {
|
|
6553
|
-
const spawnResult = spawn.spawnSync('git', ['branch', '--show-current']);
|
|
6554
|
-
const currentBranch = spawnResult.stdout.toString('utf8').trim();
|
|
6555
|
-
if (currentBranch && spawnResult.status === 0) {
|
|
6556
|
-
const proceed = await prompts.select({
|
|
6557
|
-
message: 'Use the current git branch as target branch name?',
|
|
6558
|
-
choices: [{
|
|
6559
|
-
name: `Yes [${currentBranch}]`,
|
|
6560
|
-
value: currentBranch,
|
|
6561
|
-
description: 'Use the current git branch for branch name'
|
|
6562
|
-
}, ...(repoDefaultBranch && repoDefaultBranch !== currentBranch ? [{
|
|
6563
|
-
name: `No, use the default branch [${repoDefaultBranch}]`,
|
|
6564
|
-
value: repoDefaultBranch,
|
|
6565
|
-
description: 'Use the default branch for target repo as the target branch name'
|
|
6566
|
-
}] : []), {
|
|
6567
|
-
name: 'No',
|
|
6568
|
-
value: '',
|
|
6569
|
-
description: 'Do not use the current git branch as name (will end in a no-op)'
|
|
6570
|
-
}].filter(Boolean)
|
|
6571
|
-
});
|
|
6572
|
-
if (proceed) {
|
|
6573
|
-
return proceed;
|
|
6574
|
-
}
|
|
6575
|
-
}
|
|
6576
|
-
}
|
|
6577
|
-
|
|
6578
|
-
async function suggestTarget() {
|
|
6579
|
-
// We could prefill this with sub-dirs of the current
|
|
6580
|
-
// dir ... but is that going to be useful?
|
|
6581
|
-
const proceed = await prompts.select({
|
|
6582
|
-
message: 'No TARGET given. Do you want to use the current directory?',
|
|
6583
|
-
choices: [{
|
|
6584
|
-
name: 'Yes',
|
|
6585
|
-
value: true,
|
|
6586
|
-
description: 'Target the current directory'
|
|
6587
|
-
}, {
|
|
6588
|
-
name: 'No',
|
|
6589
|
-
value: false,
|
|
6590
|
-
description: 'Do not use the current directory (this will end in a no-op)'
|
|
6591
|
-
}]
|
|
6592
|
-
});
|
|
6593
|
-
if (proceed) {
|
|
6594
|
-
return ['.'];
|
|
6595
|
-
}
|
|
6596
|
-
}
|
|
6597
|
-
|
|
6598
|
-
async function createFullScan({
|
|
6599
|
-
branchName,
|
|
6600
|
-
commitHash: _commitHash,
|
|
6601
|
-
commitMessage,
|
|
6602
|
-
committers: _committers,
|
|
6603
|
-
cwd,
|
|
6604
|
-
defaultBranch,
|
|
6605
|
-
orgSlug,
|
|
6606
|
-
pendingHead,
|
|
6607
|
-
pullRequest: _pullRequest,
|
|
6608
|
-
readOnly,
|
|
6609
|
-
repoName,
|
|
6610
|
-
targets,
|
|
6611
|
-
tmp
|
|
6612
|
-
}) {
|
|
6613
|
-
// Lazily access constants.spinner.
|
|
6614
|
-
const {
|
|
6615
|
-
spinner
|
|
6616
|
-
} = constants;
|
|
6617
|
-
const socketSdk = await shadowNpmInject.setupSdk();
|
|
6618
|
-
const supportedFiles = await socketSdk.getReportSupportedFiles().then(res => {
|
|
6619
|
-
if (!res.success) {
|
|
6620
|
-
handleUnsuccessfulApiResponse('getReportSupportedFiles', res);
|
|
6621
|
-
assert(false, 'handleUnsuccessfulApiResponse should unconditionally throw');
|
|
6622
|
-
}
|
|
6623
|
-
return res.data;
|
|
6624
|
-
}).catch(cause => {
|
|
6625
|
-
throw new Error('Failed getting supported files for report', {
|
|
6626
|
-
cause
|
|
6627
|
-
});
|
|
6628
|
-
});
|
|
6629
|
-
|
|
6630
|
-
// If we updated any inputs then we should print the command line to repeat
|
|
6631
|
-
// the command without requiring user input, as a suggestion.
|
|
6632
|
-
let updatedInput = false;
|
|
6633
|
-
if (!targets.length) {
|
|
6634
|
-
const received = await suggestTarget();
|
|
6635
|
-
targets = received ?? [];
|
|
6636
|
-
updatedInput = true;
|
|
6637
|
-
}
|
|
6638
|
-
|
|
6639
|
-
// // TODO: we'll probably use socket.json or something else soon...
|
|
6640
|
-
// const absoluteConfigPath = path.join(cwd, 'socket.yml')
|
|
6641
|
-
// const socketConfig = await getSocketConfig(absoluteConfigPath)
|
|
6642
|
-
|
|
6643
|
-
const packagePaths = await shadowNpmPaths.getPackageFilesFullScans(cwd, targets, supportedFiles
|
|
6644
|
-
// socketConfig
|
|
6645
|
-
);
|
|
6646
|
-
|
|
6647
|
-
// We're going to need an api token to suggest data because those suggestions
|
|
6648
|
-
// must come from data we already know. Don't error on missing api token yet.
|
|
6649
|
-
// If the api-token is not set, ignore it for the sake of suggestions.
|
|
6650
|
-
const apiToken = shadowNpmInject.getDefaultToken();
|
|
6651
|
-
|
|
6652
|
-
// If the current cwd is unknown and is used as a repo slug anyways, we will
|
|
6653
|
-
// first need to register the slug before we can use it.
|
|
6654
|
-
let repoDefaultBranch = '';
|
|
6655
|
-
if (apiToken) {
|
|
6656
|
-
if (!orgSlug) {
|
|
6657
|
-
const suggestion = await suggestOrgSlug(socketSdk);
|
|
6658
|
-
if (suggestion) orgSlug = suggestion;
|
|
6659
|
-
updatedInput = true;
|
|
6660
|
-
}
|
|
6661
|
-
|
|
6662
|
-
// (Don't bother asking for the rest if we didn't get an org slug above)
|
|
6663
|
-
if (orgSlug && !repoName) {
|
|
6664
|
-
const suggestion = await suggestRepoSlug(socketSdk, orgSlug);
|
|
6665
|
-
if (suggestion) {
|
|
6666
|
-
repoDefaultBranch = suggestion.defaultBranch;
|
|
6667
|
-
repoName = suggestion.slug;
|
|
6668
|
-
}
|
|
6669
|
-
updatedInput = true;
|
|
6670
|
-
}
|
|
6671
|
-
|
|
6672
|
-
// (Don't bother asking for the rest if we didn't get an org/repo above)
|
|
6673
|
-
if (orgSlug && repoName && !branchName) {
|
|
6674
|
-
const suggestion = await suggestBranchSlug(repoDefaultBranch);
|
|
6675
|
-
if (suggestion) branchName = suggestion;
|
|
6676
|
-
updatedInput = true;
|
|
7041
|
+
slug: repoName,
|
|
7042
|
+
defaultBranch: repoDefaultBranch
|
|
7043
|
+
};
|
|
6677
7044
|
}
|
|
7045
|
+
} else {
|
|
7046
|
+
logger.logger.fail('Failed to lookup repo list from API, unable to suggest.');
|
|
6678
7047
|
}
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
6686
|
-
|
|
6687
|
-
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
6688
|
-
|
|
6689
|
-
- Repository name using --repo ${!repoName ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
6690
|
-
|
|
6691
|
-
- Branch name using --branch ${!branchName ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
6692
|
-
|
|
6693
|
-
- At least one TARGET (e.g. \`.\` or \`./package.json\`) ${!packagePaths.length ? colors.red(targets.length > 0 ? '(TARGET' + (targets.length ? 's' : '') + ' contained no matching/supported files!)' : '(missing)') : colors.green('(ok)')}
|
|
7048
|
+
}
|
|
7049
|
+
function dirNameToSlug(name) {
|
|
7050
|
+
// Uses slug specs asserted by our servers
|
|
7051
|
+
// Note: this can lead to collisions; eg. slug for `x--y` and `x---y` is `x-y`
|
|
7052
|
+
return name.toLowerCase().replace(/[^[a-zA-Z0-9_.-]/g, '_').replace(/--+/g, '-').replace(/__+/g, '_').replace(/\.\.+/g, '.').replace(/[._-]+$/, '');
|
|
7053
|
+
}
|
|
6694
7054
|
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6718
|
-
set_as_pending_head: String(pendingHead),
|
|
6719
|
-
tmp: String(tmp)
|
|
6720
|
-
}, packagePaths, cwd), 'Creating scan');
|
|
6721
|
-
if (!result.success) {
|
|
6722
|
-
handleUnsuccessfulApiResponse('CreateOrgFullScan', result);
|
|
6723
|
-
return;
|
|
7055
|
+
async function suggestBranchSlug(repoDefaultBranch) {
|
|
7056
|
+
const spawnResult = spawn.spawnSync('git', ['branch', '--show-current']);
|
|
7057
|
+
const currentBranch = spawnResult.stdout.toString('utf8').trim();
|
|
7058
|
+
if (currentBranch && spawnResult.status === 0) {
|
|
7059
|
+
const proceed = await prompts.select({
|
|
7060
|
+
message: 'Use the current git branch as target branch name?',
|
|
7061
|
+
choices: [{
|
|
7062
|
+
name: `Yes [${currentBranch}]`,
|
|
7063
|
+
value: currentBranch,
|
|
7064
|
+
description: 'Use the current git branch for branch name'
|
|
7065
|
+
}, ...(repoDefaultBranch && repoDefaultBranch !== currentBranch ? [{
|
|
7066
|
+
name: `No, use the default branch [${repoDefaultBranch}]`,
|
|
7067
|
+
value: repoDefaultBranch,
|
|
7068
|
+
description: 'Use the default branch for target repo as the target branch name'
|
|
7069
|
+
}] : []), {
|
|
7070
|
+
name: 'No',
|
|
7071
|
+
value: '',
|
|
7072
|
+
description: 'Do not use the current git branch as name (will end in a no-op)'
|
|
7073
|
+
}].filter(Boolean)
|
|
7074
|
+
});
|
|
7075
|
+
if (proceed) {
|
|
7076
|
+
return proceed;
|
|
7077
|
+
}
|
|
6724
7078
|
}
|
|
6725
|
-
|
|
6726
|
-
|
|
6727
|
-
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
|
|
7079
|
+
}
|
|
7080
|
+
|
|
7081
|
+
async function suggestTarget() {
|
|
7082
|
+
// We could prefill this with sub-dirs of the current
|
|
7083
|
+
// dir ... but is that going to be useful?
|
|
7084
|
+
const proceed = await prompts.select({
|
|
7085
|
+
message: 'No TARGET given. Do you want to use the current directory?',
|
|
7086
|
+
choices: [{
|
|
7087
|
+
name: 'Yes',
|
|
7088
|
+
value: true,
|
|
7089
|
+
description: 'Target the current directory'
|
|
7090
|
+
}, {
|
|
7091
|
+
name: 'No',
|
|
7092
|
+
value: false,
|
|
7093
|
+
description: 'Do not use the current directory (this will end in a no-op)'
|
|
7094
|
+
}]
|
|
6731
7095
|
});
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
await open(`${result.data.html_report_url}`);
|
|
7096
|
+
if (proceed) {
|
|
7097
|
+
return ['.'];
|
|
6735
7098
|
}
|
|
6736
|
-
rl.close();
|
|
6737
7099
|
}
|
|
6738
7100
|
|
|
6739
7101
|
const {
|
|
@@ -6857,18 +7219,66 @@ async function run$7(argv, importMeta, {
|
|
|
6857
7219
|
importMeta,
|
|
6858
7220
|
parentName
|
|
6859
7221
|
});
|
|
6860
|
-
const [orgSlug = '', ...targets] = cli.input;
|
|
6861
|
-
const cwd = cli.flags['cwd'] && cli.flags['cwd'] !== 'process.cwd()' ? String(cli.flags['cwd']) : process$1.cwd();
|
|
6862
7222
|
const {
|
|
7223
|
+
cwd: cwdOverride,
|
|
7224
|
+
dryRun
|
|
7225
|
+
} = cli.flags;
|
|
7226
|
+
const cwd = cwdOverride && cwdOverride !== 'process.cwd()' ? String(cwdOverride) : process$1.cwd();
|
|
7227
|
+
let {
|
|
6863
7228
|
branch: branchName,
|
|
6864
7229
|
repo: repoName
|
|
6865
7230
|
} = cli.flags;
|
|
6866
|
-
|
|
7231
|
+
let [orgSlug = '', ...targets] = cli.input;
|
|
6867
7232
|
|
|
6868
|
-
|
|
6869
|
-
|
|
6870
|
-
|
|
6871
|
-
|
|
7233
|
+
// We're going to need an api token to suggest data because those suggestions
|
|
7234
|
+
// must come from data we already know. Don't error on missing api token yet.
|
|
7235
|
+
// If the api-token is not set, ignore it for the sake of suggestions.
|
|
7236
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
7237
|
+
|
|
7238
|
+
// If we updated any inputs then we should print the command line to repeat
|
|
7239
|
+
// the command without requiring user input, as a suggestion.
|
|
7240
|
+
let updatedInput = false;
|
|
7241
|
+
if (!targets.length && !dryRun) {
|
|
7242
|
+
const received = await suggestTarget();
|
|
7243
|
+
targets = received ?? [];
|
|
7244
|
+
updatedInput = true;
|
|
7245
|
+
}
|
|
7246
|
+
|
|
7247
|
+
// If the current cwd is unknown and is used as a repo slug anyways, we will
|
|
7248
|
+
// first need to register the slug before we can use it.
|
|
7249
|
+
let repoDefaultBranch = '';
|
|
7250
|
+
// Only do suggestions with an apiToken and when not in dryRun mode
|
|
7251
|
+
if (apiToken && !dryRun) {
|
|
7252
|
+
if (!orgSlug) {
|
|
7253
|
+
const suggestion = await suggestOrgSlug();
|
|
7254
|
+
if (suggestion) orgSlug = suggestion;
|
|
7255
|
+
updatedInput = true;
|
|
7256
|
+
}
|
|
7257
|
+
|
|
7258
|
+
// (Don't bother asking for the rest if we didn't get an org slug above)
|
|
7259
|
+
if (orgSlug && !repoName) {
|
|
7260
|
+
const suggestion = await suggestRepoSlug(orgSlug);
|
|
7261
|
+
if (suggestion) {
|
|
7262
|
+
repoDefaultBranch = suggestion.defaultBranch;
|
|
7263
|
+
repoName = suggestion.slug;
|
|
7264
|
+
}
|
|
7265
|
+
updatedInput = true;
|
|
7266
|
+
}
|
|
7267
|
+
|
|
7268
|
+
// (Don't bother asking for the rest if we didn't get an org/repo above)
|
|
7269
|
+
if (orgSlug && repoName && !branchName) {
|
|
7270
|
+
const suggestion = await suggestBranchSlug(repoDefaultBranch);
|
|
7271
|
+
if (suggestion) branchName = suggestion;
|
|
7272
|
+
updatedInput = true;
|
|
7273
|
+
}
|
|
7274
|
+
}
|
|
7275
|
+
if (updatedInput && repoName && branchName && orgSlug && targets?.length) {
|
|
7276
|
+
logger.logger.error('Note: You can invoke this command next time to skip the interactive questions:');
|
|
7277
|
+
logger.logger.error('```');
|
|
7278
|
+
logger.logger.error(` socket scan create [other flags...] --repo ${repoName} --branch ${branchName} ${orgSlug} ${targets.join(' ')}`);
|
|
7279
|
+
logger.logger.error('```\n');
|
|
7280
|
+
}
|
|
7281
|
+
if (!orgSlug || !repoName || !branchName || !targets.length) {
|
|
6872
7282
|
// Use exit status of 2 to indicate incorrect usage, generally invalid
|
|
6873
7283
|
// options or missing arguments.
|
|
6874
7284
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
@@ -6882,28 +7292,25 @@ async function run$7(argv, importMeta, {
|
|
|
6882
7292
|
|
|
6883
7293
|
- Branch name using --branch ${!branchName ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
6884
7294
|
|
|
6885
|
-
- At least one TARGET (e.g. \`.\` or \`./package.json\`) ${!targets.length ? '(missing)' : colors.green('(ok)')}
|
|
7295
|
+
- At least one TARGET (e.g. \`.\` or \`./package.json\`) ${!targets.length ? colors.red('(missing)') : colors.green('(ok)')}
|
|
6886
7296
|
|
|
6887
|
-
|
|
7297
|
+
${!apiToken ? 'Note: was unable to make suggestions because no API Token was found; this would make the command fail regardless' : ''}
|
|
6888
7298
|
`);
|
|
6889
7299
|
return;
|
|
6890
7300
|
}
|
|
6891
7301
|
|
|
6892
7302
|
// Note exiting earlier to skirt a hidden auth requirement
|
|
6893
|
-
if (
|
|
7303
|
+
if (dryRun) {
|
|
6894
7304
|
logger.logger.log(DRY_RUN_BAIL_TEXT$7);
|
|
6895
7305
|
return;
|
|
6896
7306
|
}
|
|
6897
|
-
await
|
|
7307
|
+
await handleCreateNewScan({
|
|
6898
7308
|
branchName: branchName,
|
|
6899
|
-
commitHash: cli.flags['commitHash'] ?? '',
|
|
6900
7309
|
commitMessage: cli.flags['commitMessage'] ?? '',
|
|
6901
|
-
committers: cli.flags['committers'] ?? '',
|
|
6902
7310
|
cwd,
|
|
6903
7311
|
defaultBranch: Boolean(cli.flags['defaultBranch']),
|
|
6904
7312
|
orgSlug,
|
|
6905
7313
|
pendingHead: Boolean(cli.flags['pendingHead']),
|
|
6906
|
-
pullRequest: cli.flags['pullRequest'] ?? undefined,
|
|
6907
7314
|
readOnly: Boolean(cli.flags['readOnly']),
|
|
6908
7315
|
repoName: repoName,
|
|
6909
7316
|
targets,
|
|
@@ -6911,26 +7318,37 @@ async function run$7(argv, importMeta, {
|
|
|
6911
7318
|
});
|
|
6912
7319
|
}
|
|
6913
7320
|
|
|
6914
|
-
async function
|
|
7321
|
+
async function fetchDeleteOrgFullScan(orgSlug, scanId) {
|
|
6915
7322
|
const apiToken = shadowNpmInject.getDefaultToken();
|
|
6916
7323
|
if (!apiToken) {
|
|
6917
7324
|
throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
|
|
6918
7325
|
}
|
|
6919
|
-
await
|
|
7326
|
+
await fetchDeleteOrgFullScanWithToken(apiToken, orgSlug, scanId);
|
|
6920
7327
|
}
|
|
6921
|
-
async function
|
|
7328
|
+
async function fetchDeleteOrgFullScanWithToken(apiToken, orgSlug, scanId) {
|
|
6922
7329
|
// Lazily access constants.spinner.
|
|
6923
7330
|
const {
|
|
6924
7331
|
spinner
|
|
6925
7332
|
} = constants;
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
const result = await handleApiCall(
|
|
7333
|
+
const sockSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
7334
|
+
spinner.start('Requesting the scan to be deleted...');
|
|
7335
|
+
const result = await handleApiCall(sockSdk.deleteOrgFullScan(orgSlug, scanId), 'Deleting scan');
|
|
7336
|
+
spinner.successAndStop('Received response for deleting a scan.');
|
|
6929
7337
|
if (!result.success) {
|
|
6930
7338
|
handleUnsuccessfulApiResponse('deleteOrgFullScan', result);
|
|
6931
7339
|
return;
|
|
6932
7340
|
}
|
|
6933
|
-
|
|
7341
|
+
return result.data;
|
|
7342
|
+
}
|
|
7343
|
+
|
|
7344
|
+
async function outputDeleteScan(_data) {
|
|
7345
|
+
logger.logger.success('Scan deleted successfully');
|
|
7346
|
+
}
|
|
7347
|
+
|
|
7348
|
+
async function handleDeleteScan(orgSlug, scanId) {
|
|
7349
|
+
const data = await fetchDeleteOrgFullScan(orgSlug, scanId);
|
|
7350
|
+
if (!data) return;
|
|
7351
|
+
await outputDeleteScan();
|
|
6934
7352
|
}
|
|
6935
7353
|
|
|
6936
7354
|
const {
|
|
@@ -6969,8 +7387,8 @@ async function run$6(argv, importMeta, {
|
|
|
6969
7387
|
importMeta,
|
|
6970
7388
|
parentName
|
|
6971
7389
|
});
|
|
6972
|
-
const [orgSlug = '',
|
|
6973
|
-
if (!orgSlug || !
|
|
7390
|
+
const [orgSlug = '', scanId = ''] = cli.input;
|
|
7391
|
+
if (!orgSlug || !scanId) {
|
|
6974
7392
|
// Use exit status of 2 to indicate incorrect usage, generally invalid
|
|
6975
7393
|
// options or missing arguments.
|
|
6976
7394
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
@@ -6979,22 +7397,20 @@ async function run$6(argv, importMeta, {
|
|
|
6979
7397
|
|
|
6980
7398
|
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
6981
7399
|
|
|
6982
|
-
- Full Scan ID to delete as second argument ${!
|
|
7400
|
+
- Full Scan ID to delete as second argument ${!scanId ? colors.red('(missing!)') : colors.green('(ok)')}`);
|
|
6983
7401
|
return;
|
|
6984
7402
|
}
|
|
6985
7403
|
if (cli.flags['dryRun']) {
|
|
6986
7404
|
logger.logger.log(DRY_RUN_BAIL_TEXT$6);
|
|
6987
7405
|
return;
|
|
6988
7406
|
}
|
|
6989
|
-
await
|
|
7407
|
+
await handleDeleteScan(orgSlug, scanId);
|
|
6990
7408
|
}
|
|
6991
7409
|
|
|
6992
|
-
|
|
6993
|
-
async function listFullScans({
|
|
7410
|
+
async function fetchListScans({
|
|
6994
7411
|
direction,
|
|
6995
7412
|
from_time,
|
|
6996
7413
|
orgSlug,
|
|
6997
|
-
outputKind,
|
|
6998
7414
|
page,
|
|
6999
7415
|
per_page,
|
|
7000
7416
|
sort
|
|
@@ -7003,23 +7419,19 @@ async function listFullScans({
|
|
|
7003
7419
|
if (!apiToken) {
|
|
7004
7420
|
throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
|
|
7005
7421
|
}
|
|
7006
|
-
await
|
|
7007
|
-
apiToken,
|
|
7422
|
+
await fetchListScansWithToken(apiToken, {
|
|
7008
7423
|
direction,
|
|
7009
7424
|
from_time,
|
|
7010
7425
|
orgSlug,
|
|
7011
|
-
outputKind,
|
|
7012
7426
|
page,
|
|
7013
7427
|
per_page,
|
|
7014
7428
|
sort
|
|
7015
7429
|
});
|
|
7016
7430
|
}
|
|
7017
|
-
async function
|
|
7018
|
-
apiToken,
|
|
7431
|
+
async function fetchListScansWithToken(apiToken, {
|
|
7019
7432
|
direction,
|
|
7020
7433
|
from_time,
|
|
7021
7434
|
orgSlug,
|
|
7022
|
-
outputKind,
|
|
7023
7435
|
page,
|
|
7024
7436
|
per_page,
|
|
7025
7437
|
sort
|
|
@@ -7028,22 +7440,27 @@ async function listFullScansWithToken({
|
|
|
7028
7440
|
const {
|
|
7029
7441
|
spinner
|
|
7030
7442
|
} = constants;
|
|
7443
|
+
const sockSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
7031
7444
|
spinner.start('Fetching list of scans...');
|
|
7032
|
-
const
|
|
7033
|
-
const result = await handleApiCall(socketSdk.getOrgFullScanList(orgSlug, {
|
|
7445
|
+
const result = await handleApiCall(sockSdk.getOrgFullScanList(orgSlug, {
|
|
7034
7446
|
sort,
|
|
7035
7447
|
direction,
|
|
7036
7448
|
per_page: String(per_page),
|
|
7037
7449
|
page: String(page),
|
|
7038
7450
|
from: from_time
|
|
7039
7451
|
}), 'Listing scans');
|
|
7452
|
+
spinner.successAndStop(`Received response for list of scans.`);
|
|
7040
7453
|
if (!result.success) {
|
|
7041
7454
|
handleUnsuccessfulApiResponse('getOrgFullScanList', result);
|
|
7042
7455
|
return;
|
|
7043
7456
|
}
|
|
7044
|
-
|
|
7457
|
+
return result.data;
|
|
7458
|
+
}
|
|
7459
|
+
|
|
7460
|
+
// @ts-ignore
|
|
7461
|
+
async function outputListScans(data, outputKind) {
|
|
7045
7462
|
if (outputKind === 'json') {
|
|
7046
|
-
logger.logger.log(
|
|
7463
|
+
logger.logger.log(data);
|
|
7047
7464
|
return;
|
|
7048
7465
|
}
|
|
7049
7466
|
const options = {
|
|
@@ -7061,7 +7478,7 @@ async function listFullScansWithToken({
|
|
|
7061
7478
|
name: colors.magenta('Created at')
|
|
7062
7479
|
}]
|
|
7063
7480
|
};
|
|
7064
|
-
const formattedResults =
|
|
7481
|
+
const formattedResults = data.results.map(d => {
|
|
7065
7482
|
return {
|
|
7066
7483
|
id: d.id,
|
|
7067
7484
|
report_url: colors.underline(`${d.html_report_url}`),
|
|
@@ -7076,6 +7493,27 @@ async function listFullScansWithToken({
|
|
|
7076
7493
|
logger.logger.log(chalkTable(options, formattedResults));
|
|
7077
7494
|
}
|
|
7078
7495
|
|
|
7496
|
+
async function handleListScans({
|
|
7497
|
+
direction,
|
|
7498
|
+
from_time,
|
|
7499
|
+
orgSlug,
|
|
7500
|
+
outputKind,
|
|
7501
|
+
page,
|
|
7502
|
+
per_page,
|
|
7503
|
+
sort
|
|
7504
|
+
}) {
|
|
7505
|
+
const data = await fetchListScans({
|
|
7506
|
+
direction,
|
|
7507
|
+
from_time,
|
|
7508
|
+
orgSlug,
|
|
7509
|
+
page,
|
|
7510
|
+
per_page,
|
|
7511
|
+
sort
|
|
7512
|
+
});
|
|
7513
|
+
if (!data) return;
|
|
7514
|
+
await outputListScans(data, outputKind);
|
|
7515
|
+
}
|
|
7516
|
+
|
|
7079
7517
|
const {
|
|
7080
7518
|
DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$5
|
|
7081
7519
|
} = constants;
|
|
@@ -7163,7 +7601,7 @@ async function run$5(argv, importMeta, {
|
|
|
7163
7601
|
logger.logger.log(DRY_RUN_BAIL_TEXT$5);
|
|
7164
7602
|
return;
|
|
7165
7603
|
}
|
|
7166
|
-
await
|
|
7604
|
+
await handleListScans({
|
|
7167
7605
|
direction: String(cli.flags['direction'] || ''),
|
|
7168
7606
|
from_time: String(cli.flags['fromTime'] || ''),
|
|
7169
7607
|
orgSlug,
|
|
@@ -7174,46 +7612,56 @@ async function run$5(argv, importMeta, {
|
|
|
7174
7612
|
});
|
|
7175
7613
|
}
|
|
7176
7614
|
|
|
7177
|
-
async function
|
|
7615
|
+
async function fetchScanMetadata(orgSlug, scanId) {
|
|
7178
7616
|
const apiToken = shadowNpmInject.getDefaultToken();
|
|
7179
7617
|
if (!apiToken) {
|
|
7180
7618
|
throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
|
|
7181
7619
|
}
|
|
7182
|
-
await
|
|
7620
|
+
await fetchScanMetadataWithToken(apiToken, orgSlug, scanId);
|
|
7183
7621
|
}
|
|
7184
|
-
async function
|
|
7622
|
+
async function fetchScanMetadataWithToken(apiToken, orgSlug, scanId) {
|
|
7185
7623
|
// Lazily access constants.spinner.
|
|
7186
7624
|
const {
|
|
7187
7625
|
spinner
|
|
7188
7626
|
} = constants;
|
|
7627
|
+
const sockSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
7189
7628
|
spinner.start('Fetching meta data for a full scan...');
|
|
7190
|
-
const
|
|
7191
|
-
|
|
7629
|
+
const result = await handleApiCall(sockSdk.getOrgFullScanMetadata(orgSlug, scanId), 'Listing scans');
|
|
7630
|
+
spinner.successAndStop('Received response for scan meta data.');
|
|
7192
7631
|
if (!result.success) {
|
|
7193
7632
|
handleUnsuccessfulApiResponse('getOrgFullScanMetadata', result);
|
|
7194
7633
|
return;
|
|
7195
7634
|
}
|
|
7196
|
-
|
|
7635
|
+
return result.data;
|
|
7636
|
+
}
|
|
7637
|
+
|
|
7638
|
+
async function outputScanMetadata(data, scanId, outputKind) {
|
|
7197
7639
|
if (outputKind === 'json') {
|
|
7198
|
-
logger.logger.log(
|
|
7640
|
+
logger.logger.log(data);
|
|
7199
7641
|
} else {
|
|
7200
7642
|
// Markdown = print
|
|
7201
7643
|
if (outputKind === 'markdown') {
|
|
7202
7644
|
logger.logger.log('# Scan meta data\n');
|
|
7203
7645
|
}
|
|
7204
7646
|
logger.logger.log(`Scan ID: ${scanId}\n`);
|
|
7205
|
-
for (const [key, value] of Object.entries(
|
|
7647
|
+
for (const [key, value] of Object.entries(data)) {
|
|
7206
7648
|
if (['id', 'updated_at', 'organization_id', 'repository_id', 'commit_hash', 'html_report_url'].includes(key)) continue;
|
|
7207
7649
|
logger.logger.log(`- ${key}:`, value);
|
|
7208
7650
|
}
|
|
7209
7651
|
if (outputKind === 'markdown') {
|
|
7210
|
-
logger.logger.log(`\nYou can view this report at: [${
|
|
7652
|
+
logger.logger.log(`\nYou can view this report at: [${data.html_report_url}](${data.html_report_url})\n`);
|
|
7211
7653
|
} else {
|
|
7212
|
-
logger.logger.log(`\nYou can view this report at: ${
|
|
7654
|
+
logger.logger.log(`\nYou can view this report at: ${data.html_report_url}]\n`);
|
|
7213
7655
|
}
|
|
7214
7656
|
}
|
|
7215
7657
|
}
|
|
7216
7658
|
|
|
7659
|
+
async function handleOrgScanMetadata(orgSlug, scanId, outputKind) {
|
|
7660
|
+
const data = await fetchScanMetadata(orgSlug, scanId);
|
|
7661
|
+
if (!data) return;
|
|
7662
|
+
await outputScanMetadata(data, scanId, outputKind);
|
|
7663
|
+
}
|
|
7664
|
+
|
|
7217
7665
|
const {
|
|
7218
7666
|
DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$4
|
|
7219
7667
|
} = constants;
|
|
@@ -7250,8 +7698,8 @@ async function run$4(argv, importMeta, {
|
|
|
7250
7698
|
importMeta,
|
|
7251
7699
|
parentName
|
|
7252
7700
|
});
|
|
7253
|
-
const [orgSlug = '',
|
|
7254
|
-
if (!orgSlug || !
|
|
7701
|
+
const [orgSlug = '', scanId = ''] = cli.input;
|
|
7702
|
+
if (!orgSlug || !scanId) {
|
|
7255
7703
|
// Use exit status of 2 to indicate incorrect usage, generally invalid
|
|
7256
7704
|
// options or missing arguments.
|
|
7257
7705
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
@@ -7260,14 +7708,14 @@ async function run$4(argv, importMeta, {
|
|
|
7260
7708
|
|
|
7261
7709
|
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
7262
7710
|
|
|
7263
|
-
- Full Scan ID to inspect as second argument ${!
|
|
7711
|
+
- Full Scan ID to inspect as second argument ${!scanId ? colors.red('(missing!)') : colors.green('(ok)')}`);
|
|
7264
7712
|
return;
|
|
7265
7713
|
}
|
|
7266
7714
|
if (cli.flags['dryRun']) {
|
|
7267
7715
|
logger.logger.log(DRY_RUN_BAIL_TEXT$4);
|
|
7268
7716
|
return;
|
|
7269
7717
|
}
|
|
7270
|
-
await
|
|
7718
|
+
await handleOrgScanMetadata(orgSlug, scanId, cli.flags['json'] ? 'json' : cli.flags['markdown'] ? 'markdown' : 'print');
|
|
7271
7719
|
}
|
|
7272
7720
|
|
|
7273
7721
|
/**
|
|
@@ -7275,7 +7723,7 @@ async function run$4(argv, importMeta, {
|
|
|
7275
7723
|
* full scan ID.
|
|
7276
7724
|
* It can optionally only fetch the security or license side of things.
|
|
7277
7725
|
*/
|
|
7278
|
-
async function fetchReportData(orgSlug,
|
|
7726
|
+
async function fetchReportData(orgSlug, scanId,
|
|
7279
7727
|
// includeLicensePolicy: boolean,
|
|
7280
7728
|
includeSecurityPolicy) {
|
|
7281
7729
|
let haveScan = false;
|
|
@@ -7312,14 +7760,14 @@ includeSecurityPolicy) {
|
|
|
7312
7760
|
throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
|
|
7313
7761
|
}
|
|
7314
7762
|
updateProgress();
|
|
7315
|
-
const
|
|
7763
|
+
const sockSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
7316
7764
|
|
|
7317
7765
|
// @ts-ignore
|
|
7318
7766
|
const [scan,
|
|
7319
7767
|
// licensePolicyMaybe,
|
|
7320
7768
|
securityPolicyMaybe] = await Promise.all([(async () => {
|
|
7321
7769
|
try {
|
|
7322
|
-
const response = await queryApi(`orgs/${orgSlug}/full-scans/${encodeURIComponent(
|
|
7770
|
+
const response = await queryApi(`orgs/${orgSlug}/full-scans/${encodeURIComponent(scanId)}`, apiToken);
|
|
7323
7771
|
haveScan = true;
|
|
7324
7772
|
updateProgress();
|
|
7325
7773
|
if (!response.ok) {
|
|
@@ -7345,7 +7793,7 @@ includeSecurityPolicy) {
|
|
|
7345
7793
|
})(),
|
|
7346
7794
|
// includeLicensePolicy &&
|
|
7347
7795
|
// (async () => {
|
|
7348
|
-
// const r = await
|
|
7796
|
+
// const r = await sockSdk.getOrgSecurityPolicy(orgSlug)
|
|
7349
7797
|
// haveLicensePolicy = true
|
|
7350
7798
|
// updateProgress()
|
|
7351
7799
|
// return await handleApiCall(
|
|
@@ -7354,7 +7802,7 @@ includeSecurityPolicy) {
|
|
|
7354
7802
|
// )
|
|
7355
7803
|
// })(),
|
|
7356
7804
|
includeSecurityPolicy && (async () => {
|
|
7357
|
-
const r = await
|
|
7805
|
+
const r = await sockSdk.getOrgSecurityPolicy(orgSlug);
|
|
7358
7806
|
haveSecurityPolicy = true;
|
|
7359
7807
|
updateProgress();
|
|
7360
7808
|
return await handleApiCall(r, "looking up organization's security policy");
|
|
@@ -7600,40 +8048,31 @@ function* walkNestedMap(map, keys = []) {
|
|
|
7600
8048
|
}
|
|
7601
8049
|
}
|
|
7602
8050
|
|
|
7603
|
-
async function
|
|
8051
|
+
async function outputScanReport(scan,
|
|
8052
|
+
// licensePolicy: undefined | SocketSdkReturnType<'getOrgSecurityPolicy'>,
|
|
8053
|
+
securityPolicy, {
|
|
7604
8054
|
filePath,
|
|
7605
8055
|
fold,
|
|
7606
|
-
fullScanId,
|
|
7607
8056
|
includeLicensePolicy,
|
|
7608
8057
|
includeSecurityPolicy,
|
|
7609
8058
|
orgSlug,
|
|
7610
8059
|
outputKind,
|
|
7611
8060
|
reportLevel,
|
|
8061
|
+
scanId,
|
|
7612
8062
|
short
|
|
7613
8063
|
}) {
|
|
7614
|
-
logger.logger.error('output:', outputKind, ', file:', filePath, ', fold:', fold, ', reportLevel:', reportLevel);
|
|
7615
8064
|
if (!includeSecurityPolicy) {
|
|
8065
|
+
process.exitCode = 1;
|
|
7616
8066
|
return; // caller should assert
|
|
7617
8067
|
}
|
|
7618
|
-
const {
|
|
7619
|
-
// licensePolicy,
|
|
7620
|
-
ok,
|
|
7621
|
-
scan,
|
|
7622
|
-
securityPolicy
|
|
7623
|
-
} = await fetchReportData(orgSlug, fullScanId,
|
|
7624
|
-
// includeLicensePolicy
|
|
7625
|
-
includeSecurityPolicy);
|
|
7626
|
-
if (!ok) {
|
|
7627
|
-
return;
|
|
7628
|
-
}
|
|
7629
8068
|
const scanReport = generateReport(scan, undefined,
|
|
7630
8069
|
// licensePolicy,
|
|
7631
8070
|
securityPolicy, {
|
|
7632
8071
|
orgSlug,
|
|
7633
|
-
scanId
|
|
8072
|
+
scanId,
|
|
7634
8073
|
fold,
|
|
7635
|
-
|
|
7636
|
-
|
|
8074
|
+
reportLevel,
|
|
8075
|
+
short
|
|
7637
8076
|
});
|
|
7638
8077
|
if (!scanReport.healthy) {
|
|
7639
8078
|
process.exitCode = 1;
|
|
@@ -7720,6 +8159,43 @@ ${!report.alerts.size ? '' : mdTable(flatData, ['Policy', 'Alert Type', 'Package
|
|
|
7720
8159
|
return md;
|
|
7721
8160
|
}
|
|
7722
8161
|
|
|
8162
|
+
async function handleScanReport({
|
|
8163
|
+
filePath,
|
|
8164
|
+
fold,
|
|
8165
|
+
includeLicensePolicy,
|
|
8166
|
+
includeSecurityPolicy,
|
|
8167
|
+
orgSlug,
|
|
8168
|
+
outputKind,
|
|
8169
|
+
reportLevel,
|
|
8170
|
+
scanId,
|
|
8171
|
+
short
|
|
8172
|
+
}) {
|
|
8173
|
+
if (!includeSecurityPolicy) {
|
|
8174
|
+
process.exitCode = 1;
|
|
8175
|
+
return; // caller should assert
|
|
8176
|
+
}
|
|
8177
|
+
const {
|
|
8178
|
+
// licensePolicy,
|
|
8179
|
+
ok,
|
|
8180
|
+
scan,
|
|
8181
|
+
securityPolicy
|
|
8182
|
+
} = await fetchReportData(orgSlug, scanId,
|
|
8183
|
+
// includeLicensePolicy
|
|
8184
|
+
includeSecurityPolicy);
|
|
8185
|
+
if (!ok) return;
|
|
8186
|
+
await outputScanReport(scan, securityPolicy, {
|
|
8187
|
+
filePath,
|
|
8188
|
+
fold,
|
|
8189
|
+
scanId: scanId,
|
|
8190
|
+
includeLicensePolicy,
|
|
8191
|
+
includeSecurityPolicy,
|
|
8192
|
+
orgSlug,
|
|
8193
|
+
outputKind,
|
|
8194
|
+
reportLevel,
|
|
8195
|
+
short
|
|
8196
|
+
});
|
|
8197
|
+
}
|
|
8198
|
+
|
|
7723
8199
|
const {
|
|
7724
8200
|
DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$3
|
|
7725
8201
|
} = constants;
|
|
@@ -7806,8 +8282,8 @@ async function run$3(argv, importMeta, {
|
|
|
7806
8282
|
reportLevel = 'warn',
|
|
7807
8283
|
security
|
|
7808
8284
|
} = cli.flags;
|
|
7809
|
-
const [orgSlug = '',
|
|
7810
|
-
if (!orgSlug || !
|
|
8285
|
+
const [orgSlug = '', scanId = '', file = '-'] = cli.input;
|
|
8286
|
+
if (!orgSlug || !scanId ||
|
|
7811
8287
|
// (!license && !security) ||
|
|
7812
8288
|
json && markdown) {
|
|
7813
8289
|
// Use exit status of 2 to indicate incorrect usage, generally invalid
|
|
@@ -7819,7 +8295,7 @@ async function run$3(argv, importMeta, {
|
|
|
7819
8295
|
|
|
7820
8296
|
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
7821
8297
|
|
|
7822
|
-
- Full Scan ID to fetch as second argument ${!
|
|
8298
|
+
- Full Scan ID to fetch as second argument ${!scanId ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
7823
8299
|
|
|
7824
8300
|
- Not both the --json and --markdown flags ${json && markdown ? colors.red('(pick one!)') : colors.green('(ok)')}
|
|
7825
8301
|
`
|
|
@@ -7831,9 +8307,9 @@ async function run$3(argv, importMeta, {
|
|
|
7831
8307
|
logger.logger.log(DRY_RUN_BAIL_TEXT$3);
|
|
7832
8308
|
return;
|
|
7833
8309
|
}
|
|
7834
|
-
await
|
|
8310
|
+
await handleScanReport({
|
|
7835
8311
|
orgSlug,
|
|
7836
|
-
|
|
8312
|
+
scanId: scanId,
|
|
7837
8313
|
includeLicensePolicy: false,
|
|
7838
8314
|
// !!license,
|
|
7839
8315
|
includeSecurityPolicy: typeof security === 'boolean' ? security : true,
|
|
@@ -7845,29 +8321,7 @@ async function run$3(argv, importMeta, {
|
|
|
7845
8321
|
});
|
|
7846
8322
|
}
|
|
7847
8323
|
|
|
7848
|
-
async function
|
|
7849
|
-
// Lazily access constants.spinner.
|
|
7850
|
-
const {
|
|
7851
|
-
spinner
|
|
7852
|
-
} = constants;
|
|
7853
|
-
const apiToken = shadowNpmInject.getDefaultToken();
|
|
7854
|
-
if (!apiToken) {
|
|
7855
|
-
throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
|
|
7856
|
-
}
|
|
7857
|
-
spinner.start('Fetching scan...');
|
|
7858
|
-
const socketSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
7859
|
-
const data = await handleApiCall(socketSdk.getOrgFullScan(orgSlug, fullScanId, file === '-' ? undefined : file), 'Fetching a scan');
|
|
7860
|
-
if (!data?.success) {
|
|
7861
|
-
handleUnsuccessfulApiResponse('getOrgFullScan', data);
|
|
7862
|
-
return;
|
|
7863
|
-
}
|
|
7864
|
-
spinner?.successAndStop(file ? `Full scan details written to ${file}` : 'stdout');
|
|
7865
|
-
return data;
|
|
7866
|
-
}
|
|
7867
|
-
|
|
7868
|
-
async function viewFullScan(orgSlug, fullScanId, filePath) {
|
|
7869
|
-
const artifacts = await getFullScan(orgSlug, fullScanId);
|
|
7870
|
-
if (!artifacts) return;
|
|
8324
|
+
async function outputScanView(artifacts, orgSlug, scanId, filePath) {
|
|
7871
8325
|
const display = artifacts.map(art => {
|
|
7872
8326
|
const author = Array.isArray(art.author) ? `${art.author[0]}${art.author.length > 1 ? ' et.al.' : ''}` : art.author;
|
|
7873
8327
|
return {
|
|
@@ -7884,11 +8338,11 @@ async function viewFullScan(orgSlug, fullScanId, filePath) {
|
|
|
7884
8338
|
|
|
7885
8339
|
These are the artifacts and their scores found.
|
|
7886
8340
|
|
|
7887
|
-
|
|
8341
|
+
Scan ID: ${scanId}
|
|
7888
8342
|
|
|
7889
8343
|
${md}
|
|
7890
8344
|
|
|
7891
|
-
View this report at: https://socket.dev/dashboard/org/${orgSlug}/sbom/${
|
|
8345
|
+
View this report at: https://socket.dev/dashboard/org/${orgSlug}/sbom/${scanId}
|
|
7892
8346
|
`.trim() + '\n';
|
|
7893
8347
|
if (filePath && filePath !== '-') {
|
|
7894
8348
|
try {
|
|
@@ -7904,6 +8358,32 @@ View this report at: https://socket.dev/dashboard/org/${orgSlug}/sbom/${fullScan
|
|
|
7904
8358
|
}
|
|
7905
8359
|
}
|
|
7906
8360
|
|
|
8361
|
+
async function handleScanView(orgSlug, scanId, filePath) {
|
|
8362
|
+
const data = await fetchScan(orgSlug, scanId);
|
|
8363
|
+
if (!data) return;
|
|
8364
|
+
await outputScanView(data, orgSlug, scanId, filePath);
|
|
8365
|
+
}
|
|
8366
|
+
|
|
8367
|
+
async function streamScan(orgSlug, scanId, file) {
|
|
8368
|
+
// Lazily access constants.spinner.
|
|
8369
|
+
const {
|
|
8370
|
+
spinner
|
|
8371
|
+
} = constants;
|
|
8372
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
8373
|
+
if (!apiToken) {
|
|
8374
|
+
throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
|
|
8375
|
+
}
|
|
8376
|
+
const sockSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
8377
|
+
spinner.start('Fetching scan...');
|
|
8378
|
+
const data = await handleApiCall(sockSdk.getOrgFullScan(orgSlug, scanId, file === '-' ? undefined : file), 'Fetching a scan');
|
|
8379
|
+
spinner?.successAndStop(file ? `Full scan details written to ${file}` : 'stdout');
|
|
8380
|
+
if (!data?.success) {
|
|
8381
|
+
handleUnsuccessfulApiResponse('getOrgFullScan', data);
|
|
8382
|
+
return;
|
|
8383
|
+
}
|
|
8384
|
+
return data;
|
|
8385
|
+
}
|
|
8386
|
+
|
|
7907
8387
|
const {
|
|
7908
8388
|
DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$2
|
|
7909
8389
|
} = constants;
|
|
@@ -7942,8 +8422,8 @@ async function run$2(argv, importMeta, {
|
|
|
7942
8422
|
importMeta,
|
|
7943
8423
|
parentName
|
|
7944
8424
|
});
|
|
7945
|
-
const [orgSlug = '',
|
|
7946
|
-
if (!orgSlug || !
|
|
8425
|
+
const [orgSlug = '', scanId = '', file = '-'] = cli.input;
|
|
8426
|
+
if (!orgSlug || !scanId) {
|
|
7947
8427
|
// Use exit status of 2 to indicate incorrect usage, generally invalid
|
|
7948
8428
|
// options or missing arguments.
|
|
7949
8429
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
@@ -7953,7 +8433,7 @@ async function run$2(argv, importMeta, {
|
|
|
7953
8433
|
|
|
7954
8434
|
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
7955
8435
|
|
|
7956
|
-
- Full Scan ID to fetch as second argument ${!
|
|
8436
|
+
- Full Scan ID to fetch as second argument ${!scanId ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
7957
8437
|
`);
|
|
7958
8438
|
return;
|
|
7959
8439
|
}
|
|
@@ -7962,9 +8442,9 @@ async function run$2(argv, importMeta, {
|
|
|
7962
8442
|
return;
|
|
7963
8443
|
}
|
|
7964
8444
|
if (cli.flags['json']) {
|
|
7965
|
-
await
|
|
8445
|
+
await streamScan(orgSlug, scanId, file);
|
|
7966
8446
|
} else {
|
|
7967
|
-
await
|
|
8447
|
+
await handleScanView(orgSlug, scanId, file);
|
|
7968
8448
|
}
|
|
7969
8449
|
}
|
|
7970
8450
|
|
|
@@ -8460,12 +8940,13 @@ void (async () => {
|
|
|
8460
8940
|
await updateNotifier({
|
|
8461
8941
|
name: SOCKET_CLI_BIN_NAME,
|
|
8462
8942
|
// The '@rollup/plugin-replace' will replace "process.env['INLINED_SOCKET_CLI_VERSION']".
|
|
8463
|
-
version: "0.14.
|
|
8943
|
+
version: "0.14.67",
|
|
8464
8944
|
ttl: 86_400_000 /* 24 hours in milliseconds */
|
|
8465
8945
|
});
|
|
8466
8946
|
try {
|
|
8467
8947
|
await meowWithSubcommands({
|
|
8468
8948
|
cdxgen: cmdCdxgen,
|
|
8949
|
+
config: cmdConfig,
|
|
8469
8950
|
fix: cmdFix,
|
|
8470
8951
|
info: cmdInfo,
|
|
8471
8952
|
login: cmdLogin,
|
|
@@ -8527,5 +9008,5 @@ void (async () => {
|
|
|
8527
9008
|
await shadowNpmInject.captureException(e);
|
|
8528
9009
|
}
|
|
8529
9010
|
})();
|
|
8530
|
-
//# debugId=
|
|
9011
|
+
//# debugId=436bf807-b015-4a97-803d-9a1ae68db89f
|
|
8531
9012
|
//# sourceMappingURL=cli.js.map
|