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