@socketsecurity/cli-with-sentry 0.14.68 → 0.14.69
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 -2
- package/dist/instrument-with-sentry.js +2 -2
- package/dist/instrument-with-sentry.js.map +1 -1
- package/dist/module-sync/cli.js +685 -705
- package/dist/module-sync/cli.js.map +1 -1
- package/dist/module-sync/config.d.ts +13 -1
- package/dist/module-sync/shadow-npm-inject.js +70 -18
- package/dist/module-sync/shadow-npm-inject.js.map +1 -1
- package/dist/module-sync/shadow-npm-paths.js +25 -10
- package/dist/module-sync/shadow-npm-paths.js.map +1 -1
- package/dist/module-sync/vendor.js +3883 -9
- package/dist/module-sync/vendor.js.map +1 -1
- package/dist/require/cli.js +684 -705
- package/dist/require/cli.js.map +1 -1
- package/package.json +7 -5
- package/dist/module-sync/fs.d.ts +0 -61
package/dist/require/cli.js
CHANGED
|
@@ -19,6 +19,7 @@ const logger = require('@socketsecurity/registry/lib/logger')
|
|
|
19
19
|
const assert = require('node:assert')
|
|
20
20
|
const fs = require('node:fs/promises')
|
|
21
21
|
const commonTags = _socketInterop(require('common-tags'))
|
|
22
|
+
const debug = require('@socketsecurity/registry/lib/debug')
|
|
22
23
|
const strings = require('@socketsecurity/registry/lib/strings')
|
|
23
24
|
const shadowNpmInject = require('./shadow-npm-inject.js')
|
|
24
25
|
const constants = require('./constants.js')
|
|
@@ -27,22 +28,21 @@ const path$1 = require('node:path')
|
|
|
27
28
|
const objects = require('@socketsecurity/registry/lib/objects')
|
|
28
29
|
const path = require('@socketsecurity/registry/lib/path')
|
|
29
30
|
const regexps = require('@socketsecurity/registry/lib/regexps')
|
|
30
|
-
const prompts = require('@socketsecurity/registry/lib/prompts')
|
|
31
31
|
const yargsParse = _socketInterop(require('yargs-parser'))
|
|
32
32
|
const words = require('@socketsecurity/registry/lib/words')
|
|
33
33
|
const fs$1 = require('node:fs')
|
|
34
34
|
const shadowBin = require('./shadow-bin.js')
|
|
35
|
+
const prompts = require('@socketsecurity/registry/lib/prompts')
|
|
35
36
|
const chalkTable = _socketInterop(require('chalk-table'))
|
|
36
37
|
const require$$0$1 = require('node:util')
|
|
37
38
|
const registry = require('@socketsecurity/registry')
|
|
38
39
|
const npm = require('@socketsecurity/registry/lib/npm')
|
|
39
40
|
const packages = require('@socketsecurity/registry/lib/packages')
|
|
40
41
|
const lockfile_fs = _socketInterop(require('@pnpm/lockfile.fs'))
|
|
42
|
+
const spawn = require('@socketsecurity/registry/lib/spawn')
|
|
41
43
|
const lockfile_detectDepTypes = _socketInterop(
|
|
42
44
|
require('@pnpm/lockfile.detect-dep-types')
|
|
43
45
|
)
|
|
44
|
-
const debug = require('@socketsecurity/registry/lib/debug')
|
|
45
|
-
const spawn = require('@socketsecurity/registry/lib/spawn')
|
|
46
46
|
const shadowNpmPaths = require('./shadow-npm-paths.js')
|
|
47
47
|
const browserslist = _socketInterop(require('browserslist'))
|
|
48
48
|
const semver = _socketInterop(require('semver'))
|
|
@@ -56,8 +56,6 @@ const npa = _socketInterop(require('npm-package-arg'))
|
|
|
56
56
|
const tinyglobby = _socketInterop(require('tinyglobby'))
|
|
57
57
|
const promises = require('@socketsecurity/registry/lib/promises')
|
|
58
58
|
const yaml = _socketInterop(require('yaml'))
|
|
59
|
-
const betterAjvErrors = _socketInterop(require('@apideck/better-ajv-errors'))
|
|
60
|
-
const config$K = require('@socketsecurity/config')
|
|
61
59
|
|
|
62
60
|
function failMsgWithBadge(badge, msg) {
|
|
63
61
|
return `${colors.bgRed(colors.bold(colors.white(` ${badge}: `)))} ${colors.bold(msg)}`
|
|
@@ -72,7 +70,7 @@ function handleUnsuccessfulApiResponse(_name, sockSdkError) {
|
|
|
72
70
|
spinner.stop()
|
|
73
71
|
throw new shadowNpmInject.AuthError(message)
|
|
74
72
|
}
|
|
75
|
-
logger.logger.fail(failMsgWithBadge('API returned an error
|
|
73
|
+
logger.logger.fail(failMsgWithBadge('Socket API returned an error', message))
|
|
76
74
|
|
|
77
75
|
process$1.exit(1)
|
|
78
76
|
}
|
|
@@ -80,23 +78,25 @@ async function handleApiCall(value, description) {
|
|
|
80
78
|
let result
|
|
81
79
|
try {
|
|
82
80
|
result = await value
|
|
83
|
-
} catch (
|
|
81
|
+
} catch (e) {
|
|
82
|
+
debug.debugLog(`handleApiCall[${description}] error:\n`, e)
|
|
84
83
|
throw new Error(`Failed ${description}`, {
|
|
85
|
-
cause
|
|
84
|
+
cause: e
|
|
86
85
|
})
|
|
87
86
|
}
|
|
88
87
|
return result
|
|
89
88
|
}
|
|
90
89
|
async function handleApiError(code) {
|
|
91
90
|
if (code === 400) {
|
|
92
|
-
return 'One of the options passed might be incorrect
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
|
|
91
|
+
return 'One of the options passed might be incorrect'
|
|
92
|
+
}
|
|
93
|
+
if (code === 403) {
|
|
94
|
+
return 'Your API token may not have the required permissions for this command or you might be trying to access (data from) an organization that is not linked to the API key you are logged in with'
|
|
95
|
+
}
|
|
96
|
+
if (code === 404) {
|
|
96
97
|
return 'The requested Socket API endpoint was not found (404) or there was no result for the requested parameters. This could be a temporary problem caused by an incident or a bug in the CLI. If the problem persists please let us know.'
|
|
97
|
-
} else {
|
|
98
|
-
return `Server responded with status code ${code}`
|
|
99
98
|
}
|
|
99
|
+
return `Server responded with status code ${code}`
|
|
100
100
|
}
|
|
101
101
|
function getLastFiveOfApiToken(token) {
|
|
102
102
|
// Get the last 5 characters of the API token before the trailing "_api".
|
|
@@ -141,14 +141,13 @@ async function fetchOrgAnalyticsData(time, spinner) {
|
|
|
141
141
|
)
|
|
142
142
|
if (result.success === false) {
|
|
143
143
|
handleUnsuccessfulApiResponse('getOrgAnalytics', result)
|
|
144
|
-
return undefined
|
|
145
144
|
}
|
|
146
145
|
spinner.stop()
|
|
147
146
|
if (!result.data.length) {
|
|
148
147
|
logger.logger.log(
|
|
149
148
|
'No analytics data is available for this organization yet.'
|
|
150
149
|
)
|
|
151
|
-
return
|
|
150
|
+
return
|
|
152
151
|
}
|
|
153
152
|
return result.data
|
|
154
153
|
}
|
|
@@ -161,14 +160,13 @@ async function fetchRepoAnalyticsData(repo, time, spinner) {
|
|
|
161
160
|
)
|
|
162
161
|
if (result.success === false) {
|
|
163
162
|
handleUnsuccessfulApiResponse('getRepoAnalytics', result)
|
|
164
|
-
return undefined
|
|
165
163
|
}
|
|
166
164
|
spinner.stop()
|
|
167
165
|
if (!result.data.length) {
|
|
168
166
|
logger.logger.log(
|
|
169
167
|
'No analytics data is available for this organization yet.'
|
|
170
168
|
)
|
|
171
|
-
return
|
|
169
|
+
return
|
|
172
170
|
}
|
|
173
171
|
return result.data
|
|
174
172
|
}
|
|
@@ -730,7 +728,7 @@ function getHelpListOutput(
|
|
|
730
728
|
return result.trim() || '(none)'
|
|
731
729
|
}
|
|
732
730
|
|
|
733
|
-
const { DRY_RUN_LABEL:
|
|
731
|
+
const { DRY_RUN_LABEL, REDACTED: REDACTED$1 } = constants
|
|
734
732
|
async function meowWithSubcommands(subcommands, options) {
|
|
735
733
|
const {
|
|
736
734
|
aliases = {},
|
|
@@ -803,15 +801,43 @@ async function meowWithSubcommands(subcommands, options) {
|
|
|
803
801
|
// Hard override the config if instructed to do so.
|
|
804
802
|
// The env var overrides the --flag, which overrides the persisted config
|
|
805
803
|
// Also, when either of these are used, config updates won't persist.
|
|
804
|
+
let configOverrideResult
|
|
806
805
|
if (process$1.env['SOCKET_CLI_CONFIG']) {
|
|
807
|
-
shadowNpmInject.overrideCachedConfig(
|
|
808
|
-
|
|
806
|
+
configOverrideResult = shadowNpmInject.overrideCachedConfig(
|
|
807
|
+
process$1.env['SOCKET_CLI_CONFIG']
|
|
809
808
|
)
|
|
810
809
|
} else if (cli.flags['config']) {
|
|
811
|
-
shadowNpmInject.overrideCachedConfig(
|
|
812
|
-
|
|
810
|
+
configOverrideResult = shadowNpmInject.overrideCachedConfig(
|
|
811
|
+
String(cli.flags['config'] || '')
|
|
813
812
|
)
|
|
814
813
|
}
|
|
814
|
+
if (process$1.env['SOCKET_CLI_NO_API_TOKEN']) {
|
|
815
|
+
// This overrides the config override and even the explicit token env var.
|
|
816
|
+
// The config will be marked as readOnly to prevent persisting it.
|
|
817
|
+
shadowNpmInject.overrideConfigApiToken(undefined)
|
|
818
|
+
} else {
|
|
819
|
+
// Note: these are SOCKET_SECURITY prefixed because they're not specific to
|
|
820
|
+
// the CLI. For the sake of consistency we'll also support the env
|
|
821
|
+
// keys that do have the SOCKET_CLI prefix, it's an easy mistake.
|
|
822
|
+
// In case multiple are supplied, the tokens supersede the keys and the
|
|
823
|
+
// security prefix supersedes the cli prefix. "Adventure mode" ;)
|
|
824
|
+
const tokenOverride =
|
|
825
|
+
process$1.env['SOCKET_CLI_API_KEY'] ||
|
|
826
|
+
process$1.env['SOCKET_SECURITY_API_KEY'] ||
|
|
827
|
+
process$1.env['SOCKET_CLI_API_TOKEN'] ||
|
|
828
|
+
process$1.env['SOCKET_SECURITY_API_TOKEN']
|
|
829
|
+
if (tokenOverride) {
|
|
830
|
+
// This will set the token (even if there was a config override) and
|
|
831
|
+
// set it to readOnly, making sure the temp token won't be persisted.
|
|
832
|
+
shadowNpmInject.overrideConfigApiToken(tokenOverride)
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
if (configOverrideResult?.ok === false) {
|
|
836
|
+
emitBanner(name)
|
|
837
|
+
logger.logger.fail(configOverrideResult.message)
|
|
838
|
+
process$1.exitCode = 2
|
|
839
|
+
return
|
|
840
|
+
}
|
|
815
841
|
|
|
816
842
|
// If we got at least some args, then lets find out if we can find a command.
|
|
817
843
|
if (commandOrAliasName) {
|
|
@@ -836,7 +862,7 @@ async function meowWithSubcommands(subcommands, options) {
|
|
|
836
862
|
}
|
|
837
863
|
if (!cli.flags['help'] && cli.flags['dryRun']) {
|
|
838
864
|
process$1.exitCode = 0
|
|
839
|
-
logger.logger.log(`${DRY_RUN_LABEL
|
|
865
|
+
logger.logger.log(`${DRY_RUN_LABEL}: No-op, call a sub-command; ok`)
|
|
840
866
|
} else {
|
|
841
867
|
cli.showHelp()
|
|
842
868
|
}
|
|
@@ -885,9 +911,9 @@ function emitBanner(name) {
|
|
|
885
911
|
logger.logger.error(getAsciiHeader(name))
|
|
886
912
|
}
|
|
887
913
|
function getAsciiHeader(command) {
|
|
888
|
-
const cliVersion = '0.14.
|
|
914
|
+
const cliVersion = '0.14.69:2aebac3:e4bf0eac:pub' // The '@rollup/plugin-replace' will replace "process.env['INLINED_SOCKET_CLI_VERSION_HASH']".
|
|
889
915
|
const nodeVersion = process$1.version
|
|
890
|
-
const apiToken = shadowNpmInject.
|
|
916
|
+
const apiToken = shadowNpmInject.getDefaultToken()
|
|
891
917
|
const shownToken = apiToken ? getLastFiveOfApiToken(apiToken) : 'no'
|
|
892
918
|
const relCwd = path.normalizePath(
|
|
893
919
|
process$1
|
|
@@ -908,7 +934,7 @@ function getAsciiHeader(command) {
|
|
|
908
934
|
return ` ${body}\n`
|
|
909
935
|
}
|
|
910
936
|
|
|
911
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
937
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$G } = constants
|
|
912
938
|
const config$J = {
|
|
913
939
|
commandName: 'analytics',
|
|
914
940
|
description: `Look up analytics data`,
|
|
@@ -921,7 +947,7 @@ const config$J = {
|
|
|
921
947
|
shortFlag: 'f',
|
|
922
948
|
default: '-',
|
|
923
949
|
description:
|
|
924
|
-
'
|
|
950
|
+
'Filepath to save output. Only valid with --json/--markdown. Defaults to stdout.'
|
|
925
951
|
},
|
|
926
952
|
repo: {
|
|
927
953
|
type: 'string',
|
|
@@ -947,6 +973,10 @@ const config$J = {
|
|
|
947
973
|
Usage
|
|
948
974
|
$ ${command} --scope=<scope> --time=<time filter>
|
|
949
975
|
|
|
976
|
+
API Token Requirements
|
|
977
|
+
- Quota: 1 unit
|
|
978
|
+
- Permissions: report:write
|
|
979
|
+
|
|
950
980
|
Default parameters are set to show the organization-level analytics over the
|
|
951
981
|
last 7 days.
|
|
952
982
|
|
|
@@ -1022,7 +1052,7 @@ async function run$J(argv, importMeta, { parentName }) {
|
|
|
1022
1052
|
return
|
|
1023
1053
|
}
|
|
1024
1054
|
if (cli.flags['dryRun']) {
|
|
1025
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
1055
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$G)
|
|
1026
1056
|
return
|
|
1027
1057
|
}
|
|
1028
1058
|
assert(assertScope(scope))
|
|
@@ -1063,31 +1093,43 @@ async function fetchAuditLog({ logType, orgSlug, outputKind, page, perPage }) {
|
|
|
1063
1093
|
)
|
|
1064
1094
|
if (!result.success) {
|
|
1065
1095
|
handleUnsuccessfulApiResponse('getAuditLogEvents', result)
|
|
1066
|
-
return
|
|
1067
1096
|
}
|
|
1068
1097
|
spinner.stop()
|
|
1069
1098
|
return result.data
|
|
1070
1099
|
}
|
|
1071
1100
|
|
|
1101
|
+
const { REDACTED } = constants
|
|
1072
1102
|
async function outputAuditLog(
|
|
1073
1103
|
auditLogs,
|
|
1074
1104
|
{ logType, orgSlug, outputKind, page, perPage }
|
|
1075
1105
|
) {
|
|
1076
1106
|
if (outputKind === 'json') {
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1107
|
+
logger.logger.log(
|
|
1108
|
+
await outputAsJson(auditLogs.results, {
|
|
1109
|
+
logType,
|
|
1110
|
+
orgSlug,
|
|
1111
|
+
page,
|
|
1112
|
+
perPage
|
|
1113
|
+
})
|
|
1114
|
+
)
|
|
1080
1115
|
} else {
|
|
1081
|
-
|
|
1116
|
+
logger.logger.log(
|
|
1117
|
+
await outputAsMarkdown(auditLogs.results, {
|
|
1118
|
+
logType,
|
|
1119
|
+
orgSlug,
|
|
1120
|
+
page,
|
|
1121
|
+
perPage
|
|
1122
|
+
})
|
|
1123
|
+
)
|
|
1082
1124
|
}
|
|
1083
1125
|
}
|
|
1084
|
-
async function outputAsJson(auditLogs,
|
|
1126
|
+
async function outputAsJson(auditLogs, { logType, orgSlug, page, perPage }) {
|
|
1085
1127
|
let json
|
|
1086
1128
|
try {
|
|
1087
1129
|
json = JSON.stringify(
|
|
1088
1130
|
{
|
|
1089
1131
|
desc: 'Audit logs for given query',
|
|
1090
|
-
generated: new Date().toISOString(),
|
|
1132
|
+
generated: false ? REDACTED : new Date().toISOString(),
|
|
1091
1133
|
org: orgSlug,
|
|
1092
1134
|
logType,
|
|
1093
1135
|
page,
|
|
@@ -1116,15 +1158,21 @@ async function outputAsJson(auditLogs, orgSlug, logType, page, perPage) {
|
|
|
1116
1158
|
2
|
|
1117
1159
|
)
|
|
1118
1160
|
} catch (e) {
|
|
1119
|
-
process.exitCode = 1
|
|
1161
|
+
process$1.exitCode = 1
|
|
1120
1162
|
logger.logger.fail(
|
|
1121
1163
|
'There was a problem converting the logs to JSON, please try without the `--json` flag'
|
|
1122
1164
|
)
|
|
1123
|
-
|
|
1165
|
+
if (debug.isDebug()) {
|
|
1166
|
+
debug.debugLog('Error:\n', e)
|
|
1167
|
+
}
|
|
1168
|
+
return '{}'
|
|
1124
1169
|
}
|
|
1125
|
-
|
|
1170
|
+
return json
|
|
1126
1171
|
}
|
|
1127
|
-
async function outputAsMarkdown(
|
|
1172
|
+
async function outputAsMarkdown(
|
|
1173
|
+
auditLogs,
|
|
1174
|
+
{ logType, orgSlug, page, perPage }
|
|
1175
|
+
) {
|
|
1128
1176
|
try {
|
|
1129
1177
|
const table = mdTable(auditLogs, [
|
|
1130
1178
|
'event_id',
|
|
@@ -1134,7 +1182,7 @@ async function outputAsMarkdown(auditLogs, orgSlug, logType, page, perPage) {
|
|
|
1134
1182
|
'ip_address',
|
|
1135
1183
|
'user_agent'
|
|
1136
1184
|
])
|
|
1137
|
-
|
|
1185
|
+
return `
|
|
1138
1186
|
# Socket Audit Logs
|
|
1139
1187
|
|
|
1140
1188
|
These are the Socket.dev audit logs as per requested query.
|
|
@@ -1142,50 +1190,21 @@ These are the Socket.dev audit logs as per requested query.
|
|
|
1142
1190
|
- type filter: ${logType || '(none)'}
|
|
1143
1191
|
- page: ${page}
|
|
1144
1192
|
- per page: ${perPage}
|
|
1145
|
-
- generated: ${new Date().toISOString()}
|
|
1193
|
+
- generated: ${false ? REDACTED : new Date().toISOString()}
|
|
1146
1194
|
|
|
1147
1195
|
${table}
|
|
1148
|
-
`
|
|
1196
|
+
`
|
|
1149
1197
|
} catch (e) {
|
|
1150
|
-
process.exitCode = 1
|
|
1198
|
+
process$1.exitCode = 1
|
|
1151
1199
|
logger.logger.fail(
|
|
1152
|
-
'There was a problem converting the logs to
|
|
1200
|
+
'There was a problem converting the logs to Markdown, please try the `--json` flag'
|
|
1153
1201
|
)
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
}
|
|
1157
|
-
}
|
|
1158
|
-
async function outputAsPrint(auditLogs, orgSlug, logType) {
|
|
1159
|
-
const data = []
|
|
1160
|
-
const logDetails = {}
|
|
1161
|
-
for (const d of auditLogs) {
|
|
1162
|
-
const { created_at } = d
|
|
1163
|
-
if (created_at) {
|
|
1164
|
-
const name = `${new Date(created_at).toLocaleDateString('en-us', {
|
|
1165
|
-
year: 'numeric',
|
|
1166
|
-
month: 'numeric',
|
|
1167
|
-
day: 'numeric'
|
|
1168
|
-
})} - ${d.user_email} - ${d.type} - ${d.ip_address} - ${d.user_agent}`
|
|
1169
|
-
data.push(
|
|
1170
|
-
{
|
|
1171
|
-
name
|
|
1172
|
-
},
|
|
1173
|
-
new prompts.Separator()
|
|
1174
|
-
)
|
|
1175
|
-
logDetails[name] = JSON.stringify(d.payload)
|
|
1202
|
+
if (debug.isDebug()) {
|
|
1203
|
+
debug.debugLog('Error:\n', e)
|
|
1176
1204
|
}
|
|
1205
|
+
// logger.error(e)
|
|
1206
|
+
return ''
|
|
1177
1207
|
}
|
|
1178
|
-
logger.logger.log(
|
|
1179
|
-
logDetails[
|
|
1180
|
-
await prompts.select({
|
|
1181
|
-
message: logType
|
|
1182
|
-
? `\n Audit log for: ${orgSlug} with type: ${logType}\n`
|
|
1183
|
-
: `\n Audit log for: ${orgSlug}\n`,
|
|
1184
|
-
choices: data,
|
|
1185
|
-
pageSize: 30
|
|
1186
|
-
})
|
|
1187
|
-
]
|
|
1188
|
-
)
|
|
1189
1208
|
}
|
|
1190
1209
|
|
|
1191
1210
|
async function handleAuditLog({ logType, orgSlug, outputKind, page, perPage }) {
|
|
@@ -1208,7 +1227,7 @@ async function handleAuditLog({ logType, orgSlug, outputKind, page, perPage }) {
|
|
|
1208
1227
|
})
|
|
1209
1228
|
}
|
|
1210
1229
|
|
|
1211
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
1230
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$F } = constants
|
|
1212
1231
|
const config$I = {
|
|
1213
1232
|
commandName: 'audit-log',
|
|
1214
1233
|
description: 'Look up the audit log for an organization',
|
|
@@ -1239,6 +1258,10 @@ const config$I = {
|
|
|
1239
1258
|
Usage
|
|
1240
1259
|
$ ${command} <org slug>
|
|
1241
1260
|
|
|
1261
|
+
API Token Requirements
|
|
1262
|
+
- Quota: 1 unit
|
|
1263
|
+
- Permissions: audit-log:list
|
|
1264
|
+
|
|
1242
1265
|
This feature requires an Enterprise Plan. To learn more about getting access
|
|
1243
1266
|
to this feature and many more, please visit https://socket.dev/pricing
|
|
1244
1267
|
|
|
@@ -1294,7 +1317,7 @@ async function run$I(argv, importMeta, { parentName }) {
|
|
|
1294
1317
|
return
|
|
1295
1318
|
}
|
|
1296
1319
|
if (cli.flags['dryRun']) {
|
|
1297
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
1320
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$F)
|
|
1298
1321
|
return
|
|
1299
1322
|
}
|
|
1300
1323
|
await handleAuditLog({
|
|
@@ -1422,7 +1445,7 @@ function isHelpFlag(cmdArg) {
|
|
|
1422
1445
|
}
|
|
1423
1446
|
|
|
1424
1447
|
// import { meowOrExit } from '../../utils/meow-with-subcommands'
|
|
1425
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
1448
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$E } = constants
|
|
1426
1449
|
|
|
1427
1450
|
// TODO: convert yargs to meow. Or convert all the other things to yargs.
|
|
1428
1451
|
const toLower = arg => arg.toLowerCase()
|
|
@@ -1585,7 +1608,7 @@ async function run$H(argv, importMeta, { parentName }) {
|
|
|
1585
1608
|
return
|
|
1586
1609
|
}
|
|
1587
1610
|
if (cli.flags['dryRun']) {
|
|
1588
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
1611
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$E)
|
|
1589
1612
|
return
|
|
1590
1613
|
}
|
|
1591
1614
|
if (yargv.output === undefined) {
|
|
@@ -1621,7 +1644,7 @@ async function discoverConfigValue(key) {
|
|
|
1621
1644
|
success: false,
|
|
1622
1645
|
value: undefined,
|
|
1623
1646
|
message:
|
|
1624
|
-
'When uncertain, unset this key. Otherwise ask your network administrator
|
|
1647
|
+
'When uncertain, unset this key. Otherwise ask your network administrator'
|
|
1625
1648
|
}
|
|
1626
1649
|
}
|
|
1627
1650
|
if (key === 'apiToken') {
|
|
@@ -1835,7 +1858,7 @@ async function handleConfigAuto({ key, outputKind }) {
|
|
|
1835
1858
|
await outputConfigAuto(key, result, outputKind)
|
|
1836
1859
|
}
|
|
1837
1860
|
|
|
1838
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
1861
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$D } = constants
|
|
1839
1862
|
const config$G = {
|
|
1840
1863
|
commandName: 'auto',
|
|
1841
1864
|
description: 'Automatically discover and set the correct value config item',
|
|
@@ -1900,7 +1923,7 @@ async function run$G(argv, importMeta, { parentName }) {
|
|
|
1900
1923
|
return
|
|
1901
1924
|
}
|
|
1902
1925
|
if (cli.flags['dryRun']) {
|
|
1903
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
1926
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$D)
|
|
1904
1927
|
return
|
|
1905
1928
|
}
|
|
1906
1929
|
await handleConfigAuto({
|
|
@@ -1909,7 +1932,13 @@ async function run$G(argv, importMeta, { parentName }) {
|
|
|
1909
1932
|
})
|
|
1910
1933
|
}
|
|
1911
1934
|
|
|
1912
|
-
async function outputConfigGet(
|
|
1935
|
+
async function outputConfigGet(
|
|
1936
|
+
key,
|
|
1937
|
+
value,
|
|
1938
|
+
readOnly,
|
|
1939
|
+
// Is config in read-only mode? (Overrides applied)
|
|
1940
|
+
outputKind
|
|
1941
|
+
) {
|
|
1913
1942
|
if (outputKind === 'json') {
|
|
1914
1943
|
logger.logger.log(
|
|
1915
1944
|
JSON.stringify({
|
|
@@ -1917,24 +1946,38 @@ async function outputConfigGet(key, value, outputKind) {
|
|
|
1917
1946
|
result: {
|
|
1918
1947
|
key,
|
|
1919
1948
|
value
|
|
1920
|
-
}
|
|
1949
|
+
},
|
|
1950
|
+
readOnly
|
|
1921
1951
|
})
|
|
1922
1952
|
)
|
|
1923
1953
|
} else if (outputKind === 'markdown') {
|
|
1924
1954
|
logger.logger.log(`# Config Value`)
|
|
1925
1955
|
logger.logger.log('')
|
|
1926
1956
|
logger.logger.log(`Config key '${key}' has value '${value}`)
|
|
1957
|
+
if (readOnly) {
|
|
1958
|
+
logger.logger.log('')
|
|
1959
|
+
logger.logger.log(
|
|
1960
|
+
'Note: the config is in read-only mode, meaning at least one key was temporarily\n overridden from an env var or command flag.'
|
|
1961
|
+
)
|
|
1962
|
+
}
|
|
1927
1963
|
} else {
|
|
1928
1964
|
logger.logger.log(`${key}: ${value}`)
|
|
1965
|
+
if (readOnly) {
|
|
1966
|
+
logger.logger.log('')
|
|
1967
|
+
logger.logger.log(
|
|
1968
|
+
'Note: the config is in read-only mode, meaning at least one key was temporarily overridden from an env var or command flag.'
|
|
1969
|
+
)
|
|
1970
|
+
}
|
|
1929
1971
|
}
|
|
1930
1972
|
}
|
|
1931
1973
|
|
|
1932
1974
|
async function handleConfigGet({ key, outputKind }) {
|
|
1933
1975
|
const value = shadowNpmInject.getConfigValue(key)
|
|
1934
|
-
|
|
1976
|
+
const readOnly = shadowNpmInject.isReadOnlyConfig()
|
|
1977
|
+
await outputConfigGet(key, value, readOnly, outputKind)
|
|
1935
1978
|
}
|
|
1936
1979
|
|
|
1937
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
1980
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$C } = constants
|
|
1938
1981
|
const config$F = {
|
|
1939
1982
|
commandName: 'get',
|
|
1940
1983
|
description: 'Get the value of a local CLI config item',
|
|
@@ -1994,7 +2037,7 @@ async function run$F(argv, importMeta, { parentName }) {
|
|
|
1994
2037
|
return
|
|
1995
2038
|
}
|
|
1996
2039
|
if (cli.flags['dryRun']) {
|
|
1997
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
2040
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$C)
|
|
1998
2041
|
return
|
|
1999
2042
|
}
|
|
2000
2043
|
await handleConfigGet({
|
|
@@ -2004,6 +2047,7 @@ async function run$F(argv, importMeta, { parentName }) {
|
|
|
2004
2047
|
}
|
|
2005
2048
|
|
|
2006
2049
|
async function outputConfigList({ full, outputKind }) {
|
|
2050
|
+
const readOnly = shadowNpmInject.isReadOnlyConfig()
|
|
2007
2051
|
if (outputKind === 'json') {
|
|
2008
2052
|
const obj = {}
|
|
2009
2053
|
for (const key of shadowNpmInject.supportedConfigKeys.keys()) {
|
|
@@ -2020,7 +2064,8 @@ async function outputConfigList({ full, outputKind }) {
|
|
|
2020
2064
|
{
|
|
2021
2065
|
success: true,
|
|
2022
2066
|
full,
|
|
2023
|
-
config: obj
|
|
2067
|
+
config: obj,
|
|
2068
|
+
readOnly
|
|
2024
2069
|
},
|
|
2025
2070
|
null,
|
|
2026
2071
|
2
|
|
@@ -2045,10 +2090,16 @@ async function outputConfigList({ full, outputKind }) {
|
|
|
2045
2090
|
)
|
|
2046
2091
|
}
|
|
2047
2092
|
}
|
|
2093
|
+
if (readOnly) {
|
|
2094
|
+
logger.logger.log('')
|
|
2095
|
+
logger.logger.log(
|
|
2096
|
+
'Note: the config is in read-only mode, meaning at least one key was temporarily\n overridden from an env var or command flag.'
|
|
2097
|
+
)
|
|
2098
|
+
}
|
|
2048
2099
|
}
|
|
2049
2100
|
}
|
|
2050
2101
|
|
|
2051
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
2102
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$B } = constants
|
|
2052
2103
|
const config$E = {
|
|
2053
2104
|
commandName: 'list',
|
|
2054
2105
|
description: 'Show all local CLI config items and their values',
|
|
@@ -2104,7 +2155,7 @@ async function run$E(argv, importMeta, { parentName }) {
|
|
|
2104
2155
|
return
|
|
2105
2156
|
}
|
|
2106
2157
|
if (cli.flags['dryRun']) {
|
|
2107
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
2158
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$B)
|
|
2108
2159
|
return
|
|
2109
2160
|
}
|
|
2110
2161
|
await outputConfigList({
|
|
@@ -2113,29 +2164,43 @@ async function run$E(argv, importMeta, { parentName }) {
|
|
|
2113
2164
|
})
|
|
2114
2165
|
}
|
|
2115
2166
|
|
|
2116
|
-
async function outputConfigSet(key, _value, outputKind) {
|
|
2167
|
+
async function outputConfigSet(key, _value, readOnly, outputKind) {
|
|
2117
2168
|
if (outputKind === 'json') {
|
|
2118
2169
|
logger.logger.log(
|
|
2119
2170
|
JSON.stringify({
|
|
2120
2171
|
success: true,
|
|
2121
|
-
message: `Config key '${key}' was updated
|
|
2172
|
+
message: `Config key '${key}' was updated${readOnly ? ' (Note: since at least one value was overridden from flag/env, the config was not persisted)' : ''}`,
|
|
2173
|
+
readOnly
|
|
2122
2174
|
})
|
|
2123
2175
|
)
|
|
2124
2176
|
} else if (outputKind === 'markdown') {
|
|
2125
2177
|
logger.logger.log(`# Update config`)
|
|
2126
2178
|
logger.logger.log('')
|
|
2127
2179
|
logger.logger.log(`Config key '${key}' was updated`)
|
|
2180
|
+
if (readOnly) {
|
|
2181
|
+
logger.logger.log('')
|
|
2182
|
+
logger.logger.log(
|
|
2183
|
+
'Note: The change was not persisted because the config is in read-only mode,\n meaning at least one key was temporarily overridden from an env var or\n command flag.'
|
|
2184
|
+
)
|
|
2185
|
+
}
|
|
2128
2186
|
} else {
|
|
2129
2187
|
logger.logger.log(`OK`)
|
|
2188
|
+
if (readOnly) {
|
|
2189
|
+
logger.logger.log('')
|
|
2190
|
+
logger.logger.log(
|
|
2191
|
+
'Note: The change was not persisted because the config is in read-only mode, meaning at least one key was temporarily overridden from an env var or command flag.'
|
|
2192
|
+
)
|
|
2193
|
+
}
|
|
2130
2194
|
}
|
|
2131
2195
|
}
|
|
2132
2196
|
|
|
2133
2197
|
async function handleConfigSet({ key, outputKind, value }) {
|
|
2134
2198
|
shadowNpmInject.updateConfigValue(key, value)
|
|
2135
|
-
|
|
2199
|
+
const readOnly = shadowNpmInject.isReadOnlyConfig()
|
|
2200
|
+
await outputConfigSet(key, value, readOnly, outputKind)
|
|
2136
2201
|
}
|
|
2137
2202
|
|
|
2138
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
2203
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$A } = constants
|
|
2139
2204
|
const config$D = {
|
|
2140
2205
|
commandName: 'set',
|
|
2141
2206
|
description: 'Update the value of a local CLI config item',
|
|
@@ -2209,7 +2274,7 @@ async function run$D(argv, importMeta, { parentName }) {
|
|
|
2209
2274
|
return
|
|
2210
2275
|
}
|
|
2211
2276
|
if (cli.flags['dryRun']) {
|
|
2212
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
2277
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$A)
|
|
2213
2278
|
return
|
|
2214
2279
|
}
|
|
2215
2280
|
await handleConfigSet({
|
|
@@ -2241,7 +2306,7 @@ async function handleConfigUnset({ key, outputKind }) {
|
|
|
2241
2306
|
await outputConfigUnset(key, outputKind)
|
|
2242
2307
|
}
|
|
2243
2308
|
|
|
2244
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
2309
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$z } = constants
|
|
2245
2310
|
const config$C = {
|
|
2246
2311
|
commandName: 'unset',
|
|
2247
2312
|
description: 'Clear the value of a local CLI config item',
|
|
@@ -2301,7 +2366,7 @@ async function run$C(argv, importMeta, { parentName }) {
|
|
|
2301
2366
|
return
|
|
2302
2367
|
}
|
|
2303
2368
|
if (cli.flags['dryRun']) {
|
|
2304
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
2369
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$z)
|
|
2305
2370
|
return
|
|
2306
2371
|
}
|
|
2307
2372
|
await handleConfigUnset({
|
|
@@ -2350,7 +2415,6 @@ async function fetchDependencies({ limit, offset }) {
|
|
|
2350
2415
|
spinner.successAndStop('Received organization dependencies response.')
|
|
2351
2416
|
if (!result.success) {
|
|
2352
2417
|
handleUnsuccessfulApiResponse('searchDependencies', result)
|
|
2353
|
-
return
|
|
2354
2418
|
}
|
|
2355
2419
|
return result.data
|
|
2356
2420
|
}
|
|
@@ -2429,7 +2493,7 @@ async function handleDependencies({ limit, offset, outputKind }) {
|
|
|
2429
2493
|
})
|
|
2430
2494
|
}
|
|
2431
2495
|
|
|
2432
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
2496
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$y } = constants
|
|
2433
2497
|
const config$B = {
|
|
2434
2498
|
commandName: 'dependencies',
|
|
2435
2499
|
description:
|
|
@@ -2455,6 +2519,10 @@ const config$B = {
|
|
|
2455
2519
|
Usage
|
|
2456
2520
|
${command}
|
|
2457
2521
|
|
|
2522
|
+
API Token Requirements
|
|
2523
|
+
- Quota: 1 unit
|
|
2524
|
+
- Permissions: none (does need token with access to target org)
|
|
2525
|
+
|
|
2458
2526
|
Options
|
|
2459
2527
|
${getFlagListOutput(config.flags, 6)}
|
|
2460
2528
|
|
|
@@ -2498,7 +2566,7 @@ async function run$B(argv, importMeta, { parentName }) {
|
|
|
2498
2566
|
return
|
|
2499
2567
|
}
|
|
2500
2568
|
if (cli.flags['dryRun']) {
|
|
2501
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
2569
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$y)
|
|
2502
2570
|
return
|
|
2503
2571
|
}
|
|
2504
2572
|
await handleDependencies({
|
|
@@ -2612,7 +2680,7 @@ async function handleDiffScan({
|
|
|
2612
2680
|
})
|
|
2613
2681
|
}
|
|
2614
2682
|
|
|
2615
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
2683
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$x } = constants
|
|
2616
2684
|
const config$A = {
|
|
2617
2685
|
commandName: 'get',
|
|
2618
2686
|
description: 'Get a diff scan for an organization',
|
|
@@ -2656,6 +2724,10 @@ const config$A = {
|
|
|
2656
2724
|
Usage
|
|
2657
2725
|
$ ${command} <org slug> --before=<before> --after=<after>
|
|
2658
2726
|
|
|
2727
|
+
API Token Requirements
|
|
2728
|
+
- Quota: 1 unit
|
|
2729
|
+
- Permissions: full-scans:list
|
|
2730
|
+
|
|
2659
2731
|
This command displays the package changes between two scans. The full output
|
|
2660
2732
|
can be pretty large depending on the size of your repo and time range. It is
|
|
2661
2733
|
best stored to disk to be further analyzed by other tools.
|
|
@@ -2687,7 +2759,7 @@ async function run$A(argv, importMeta, { parentName }) {
|
|
|
2687
2759
|
{
|
|
2688
2760
|
test: !!(before && after),
|
|
2689
2761
|
message:
|
|
2690
|
-
'Specify a before and after scan ID
|
|
2762
|
+
'Specify a before and after scan ID.\nThe args are expecting a full `aaa0aa0a-aaaa-0000-0a0a-0000000a00a0` scan ID.',
|
|
2691
2763
|
pass: 'ok',
|
|
2692
2764
|
fail:
|
|
2693
2765
|
!before && !after
|
|
@@ -2724,7 +2796,7 @@ async function run$A(argv, importMeta, { parentName }) {
|
|
|
2724
2796
|
return
|
|
2725
2797
|
}
|
|
2726
2798
|
if (cli.flags['dryRun']) {
|
|
2727
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
2799
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$x)
|
|
2728
2800
|
return
|
|
2729
2801
|
}
|
|
2730
2802
|
await handleDiffScan({
|
|
@@ -2764,8 +2836,13 @@ const { NPM: NPM$f } = constants
|
|
|
2764
2836
|
function isTopLevel(tree, node) {
|
|
2765
2837
|
return tree.children.get(node.name) === node
|
|
2766
2838
|
}
|
|
2767
|
-
async function npmFix(_pkgEnvDetails,
|
|
2768
|
-
const {
|
|
2839
|
+
async function npmFix(_pkgEnvDetails, options) {
|
|
2840
|
+
const {
|
|
2841
|
+
cwd = process.cwd(),
|
|
2842
|
+
spinner,
|
|
2843
|
+
test = false,
|
|
2844
|
+
testScript = 'test'
|
|
2845
|
+
} = {
|
|
2769
2846
|
__proto__: null,
|
|
2770
2847
|
...options
|
|
2771
2848
|
}
|
|
@@ -2781,7 +2858,8 @@ async function npmFix(_pkgEnvDetails, cwd, options) {
|
|
|
2781
2858
|
existing: true,
|
|
2782
2859
|
unfixable: false,
|
|
2783
2860
|
upgradable: false
|
|
2784
|
-
}
|
|
2861
|
+
},
|
|
2862
|
+
nothrow: true
|
|
2785
2863
|
})
|
|
2786
2864
|
const infoByPkg = shadowNpmInject.getCveInfoByAlertsMap(alertsMap)
|
|
2787
2865
|
if (!infoByPkg) {
|
|
@@ -2826,11 +2904,13 @@ async function npmFix(_pkgEnvDetails, cwd, options) {
|
|
|
2826
2904
|
shadowNpmInject.updateNode(node, packument, vulnerableVersionRange)
|
|
2827
2905
|
) {
|
|
2828
2906
|
try {
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2907
|
+
if (test) {
|
|
2908
|
+
// eslint-disable-next-line no-await-in-loop
|
|
2909
|
+
await npm.runScript(testScript, [], {
|
|
2910
|
+
spinner,
|
|
2911
|
+
stdio: 'ignore'
|
|
2912
|
+
})
|
|
2913
|
+
}
|
|
2834
2914
|
spinner?.info(`Patched ${name} ${oldVersion} -> ${node.version}`)
|
|
2835
2915
|
if (isTopLevel(tree, node)) {
|
|
2836
2916
|
for (const depField of [
|
|
@@ -2866,16 +2946,24 @@ async function npmFix(_pkgEnvDetails, cwd, options) {
|
|
|
2866
2946
|
spinner?.stop()
|
|
2867
2947
|
}
|
|
2868
2948
|
|
|
2869
|
-
async function getAlertsMapFromPnpmLockfile(lockfile,
|
|
2870
|
-
const
|
|
2949
|
+
async function getAlertsMapFromPnpmLockfile(lockfile, options_) {
|
|
2950
|
+
const options = {
|
|
2871
2951
|
__proto__: null,
|
|
2872
|
-
|
|
2952
|
+
consolidate: false,
|
|
2953
|
+
nothrow: false,
|
|
2954
|
+
...options_
|
|
2873
2955
|
}
|
|
2874
2956
|
const include = {
|
|
2875
2957
|
__proto__: null,
|
|
2958
|
+
blocked: true,
|
|
2959
|
+
critical: true,
|
|
2960
|
+
cve: true,
|
|
2961
|
+
existing: false,
|
|
2876
2962
|
unfixable: true,
|
|
2877
|
-
|
|
2963
|
+
upgradable: false,
|
|
2964
|
+
...options.include
|
|
2878
2965
|
}
|
|
2966
|
+
const { spinner } = options
|
|
2879
2967
|
const depTypes = lockfile_detectDepTypes.detectDepTypes(lockfile)
|
|
2880
2968
|
const pkgIds = Object.keys(depTypes)
|
|
2881
2969
|
let { length: remaining } = pkgIds
|
|
@@ -2890,9 +2978,11 @@ async function getAlertsMapFromPnpmLockfile(lockfile, options) {
|
|
|
2890
2978
|
)
|
|
2891
2979
|
const toAlertsMapOptions = {
|
|
2892
2980
|
overrides: lockfile.overrides,
|
|
2893
|
-
|
|
2981
|
+
consolidate: options.consolidate,
|
|
2982
|
+
include,
|
|
2983
|
+
spinner
|
|
2894
2984
|
}
|
|
2895
|
-
for await (const
|
|
2985
|
+
for await (const batchResult of sockSdk.batchPackageStream(
|
|
2896
2986
|
{
|
|
2897
2987
|
alerts: 'true',
|
|
2898
2988
|
compact: 'true',
|
|
@@ -2904,12 +2994,18 @@ async function getAlertsMapFromPnpmLockfile(lockfile, options) {
|
|
|
2904
2994
|
}))
|
|
2905
2995
|
}
|
|
2906
2996
|
)) {
|
|
2907
|
-
if (
|
|
2997
|
+
if (batchResult.success) {
|
|
2908
2998
|
await shadowNpmInject.addArtifactToAlertsMap(
|
|
2909
|
-
|
|
2999
|
+
batchResult.data,
|
|
2910
3000
|
alertsByPkgId,
|
|
2911
3001
|
toAlertsMapOptions
|
|
2912
3002
|
)
|
|
3003
|
+
} else if (!options.nothrow) {
|
|
3004
|
+
const statusCode = batchResult.status ?? 'unknown'
|
|
3005
|
+
const statusMessage = batchResult.error ?? 'No status message'
|
|
3006
|
+
throw new Error(
|
|
3007
|
+
`Socket API server error (${statusCode}): ${statusMessage}`
|
|
3008
|
+
)
|
|
2913
3009
|
}
|
|
2914
3010
|
remaining -= 1
|
|
2915
3011
|
if (spinner && remaining > 0) {
|
|
@@ -3041,12 +3137,99 @@ function runAgentInstall(pkgEnvDetails, options) {
|
|
|
3041
3137
|
}
|
|
3042
3138
|
|
|
3043
3139
|
const { NPM: NPM$c, OVERRIDES: OVERRIDES$2, PNPM: PNPM$9 } = constants
|
|
3044
|
-
async function
|
|
3045
|
-
|
|
3140
|
+
async function branchExists(branchName, cwd) {
|
|
3141
|
+
try {
|
|
3142
|
+
await spawn.spawn('git', ['rev-parse', '--verify', branchName], {
|
|
3143
|
+
cwd,
|
|
3144
|
+
stdio: 'ignore'
|
|
3145
|
+
})
|
|
3146
|
+
return true
|
|
3147
|
+
} catch {
|
|
3148
|
+
return false
|
|
3149
|
+
}
|
|
3150
|
+
}
|
|
3151
|
+
async function remoteBranchExists(branchName, cwd) {
|
|
3152
|
+
try {
|
|
3153
|
+
const result = await spawn.spawn(
|
|
3154
|
+
'git',
|
|
3155
|
+
['ls-remote', '--heads', 'origin', branchName],
|
|
3156
|
+
{
|
|
3157
|
+
cwd,
|
|
3158
|
+
stdio: 'pipe'
|
|
3159
|
+
}
|
|
3160
|
+
)
|
|
3161
|
+
return !!result.stdout.trim()
|
|
3162
|
+
} catch {
|
|
3163
|
+
return false
|
|
3164
|
+
}
|
|
3165
|
+
}
|
|
3166
|
+
async function commitAndPushFix(branchName, commitMsg, cwd) {
|
|
3167
|
+
const localExists = await branchExists(branchName, cwd)
|
|
3168
|
+
const remoteExists = await remoteBranchExists(branchName, cwd)
|
|
3169
|
+
if (localExists || remoteExists) {
|
|
3170
|
+
logger.logger.warn(
|
|
3171
|
+
`Branch "${branchName}" already exists. Skipping creation.`
|
|
3172
|
+
)
|
|
3173
|
+
return
|
|
3174
|
+
}
|
|
3175
|
+
await spawn.spawn('git', ['checkout', '-b', branchName], {
|
|
3176
|
+
cwd
|
|
3177
|
+
})
|
|
3178
|
+
await spawn.spawn('git', ['add', 'package.json', 'pnpm-lock.yaml'], {
|
|
3179
|
+
cwd
|
|
3180
|
+
})
|
|
3181
|
+
await spawn.spawn('git', ['commit', '-m', commitMsg], {
|
|
3182
|
+
cwd
|
|
3183
|
+
})
|
|
3184
|
+
await spawn.spawn('git', ['push', '--set-upstream', 'origin', branchName], {
|
|
3185
|
+
cwd
|
|
3186
|
+
})
|
|
3187
|
+
}
|
|
3188
|
+
async function createPullRequest({
|
|
3189
|
+
base = 'main',
|
|
3190
|
+
body,
|
|
3191
|
+
head,
|
|
3192
|
+
owner,
|
|
3193
|
+
repo,
|
|
3194
|
+
title
|
|
3195
|
+
}) {
|
|
3196
|
+
const octokit = new vendor.Octokit({
|
|
3197
|
+
auth: process.env['GITHUB_TOKEN']
|
|
3198
|
+
})
|
|
3199
|
+
await octokit.pulls.create({
|
|
3200
|
+
owner,
|
|
3201
|
+
repo,
|
|
3202
|
+
title,
|
|
3203
|
+
head,
|
|
3204
|
+
base,
|
|
3205
|
+
...(body
|
|
3206
|
+
? {
|
|
3207
|
+
body
|
|
3208
|
+
}
|
|
3209
|
+
: {})
|
|
3210
|
+
})
|
|
3211
|
+
}
|
|
3212
|
+
function getRepoInfo() {
|
|
3213
|
+
const repoString = process.env['GITHUB_REPOSITORY']
|
|
3214
|
+
if (!repoString || !repoString.includes('/')) {
|
|
3215
|
+
throw new Error('GITHUB_REPOSITORY is not set or invalid')
|
|
3216
|
+
}
|
|
3217
|
+
const { 0: owner, 1: repo } = repoString.split('/')
|
|
3218
|
+
return {
|
|
3219
|
+
owner,
|
|
3220
|
+
repo
|
|
3221
|
+
}
|
|
3222
|
+
}
|
|
3223
|
+
async function pnpmFix(pkgEnvDetails, options) {
|
|
3224
|
+
const {
|
|
3225
|
+
cwd = process.cwd(),
|
|
3226
|
+
spinner,
|
|
3227
|
+
test = false,
|
|
3228
|
+
testScript = 'test'
|
|
3229
|
+
} = {
|
|
3046
3230
|
__proto__: null,
|
|
3047
3231
|
...options
|
|
3048
3232
|
}
|
|
3049
|
-
spinner?.start()
|
|
3050
3233
|
const lockfile = await lockfile_fs.readWantedLockfile(cwd, {
|
|
3051
3234
|
ignoreIncompatible: false
|
|
3052
3235
|
})
|
|
@@ -3060,7 +3243,8 @@ async function pnpmFix(pkgEnvDetails, cwd, options) {
|
|
|
3060
3243
|
existing: true,
|
|
3061
3244
|
unfixable: false,
|
|
3062
3245
|
upgradable: false
|
|
3063
|
-
}
|
|
3246
|
+
},
|
|
3247
|
+
nothrow: true
|
|
3064
3248
|
})
|
|
3065
3249
|
const infoByPkg = shadowNpmInject.getCveInfoByAlertsMap(alertsMap)
|
|
3066
3250
|
if (!infoByPkg) {
|
|
@@ -3076,11 +3260,12 @@ async function pnpmFix(pkgEnvDetails, cwd, options) {
|
|
|
3076
3260
|
editable: true
|
|
3077
3261
|
})
|
|
3078
3262
|
const { content: pkgJson } = editablePkgJson
|
|
3263
|
+
spinner?.stop()
|
|
3079
3264
|
for (const { 0: name, 1: infos } of infoByPkg) {
|
|
3080
3265
|
const tree = arb.actualTree
|
|
3081
3266
|
const hasUpgrade = !!registry.getManifestData(NPM$c, name)
|
|
3082
3267
|
if (hasUpgrade) {
|
|
3083
|
-
|
|
3268
|
+
logger.logger.info(`Skipping ${name}. Socket Optimize package exists.`)
|
|
3084
3269
|
continue
|
|
3085
3270
|
}
|
|
3086
3271
|
const nodes = shadowNpmInject.findPackageNodes(tree, name)
|
|
@@ -3102,6 +3287,7 @@ async function pnpmFix(pkgEnvDetails, cwd, options) {
|
|
|
3102
3287
|
const { firstPatchedVersionIdentifier, vulnerableVersionRange } =
|
|
3103
3288
|
infos[j]
|
|
3104
3289
|
const { version: oldVersion } = node
|
|
3290
|
+
const oldSpec = `${name}@${oldVersion}`
|
|
3105
3291
|
const availableVersions = Object.keys(packument.versions)
|
|
3106
3292
|
// Find the highest non-vulnerable version within the same major range
|
|
3107
3293
|
const targetVersion = shadowNpmInject.findBestPatchVersion(
|
|
@@ -3112,20 +3298,28 @@ async function pnpmFix(pkgEnvDetails, cwd, options) {
|
|
|
3112
3298
|
const targetPackument = targetVersion
|
|
3113
3299
|
? packument.versions[targetVersion]
|
|
3114
3300
|
: undefined
|
|
3115
|
-
|
|
3301
|
+
spinner?.stop()
|
|
3302
|
+
|
|
3303
|
+
// Check targetVersion to make TypeScript happy.
|
|
3304
|
+
if (targetVersion && targetPackument) {
|
|
3116
3305
|
const oldPnpm = pkgJson[PNPM$9]
|
|
3117
3306
|
const oldOverrides = oldPnpm?.[OVERRIDES$2]
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3307
|
+
const overrideKey = `${node.name}@${vulnerableVersionRange}`
|
|
3308
|
+
const overrideRange = `^${targetVersion}`
|
|
3309
|
+
const fixSpec = `${name}@${overrideRange}`
|
|
3310
|
+
const data = {
|
|
3311
|
+
[PNPM$9]: {
|
|
3312
|
+
...oldPnpm,
|
|
3313
|
+
[OVERRIDES$2]: {
|
|
3314
|
+
[overrideKey]: overrideRange,
|
|
3315
|
+
...oldOverrides
|
|
3126
3316
|
}
|
|
3127
|
-
}
|
|
3128
|
-
|
|
3317
|
+
}
|
|
3318
|
+
}
|
|
3319
|
+
try {
|
|
3320
|
+
editablePkgJson.update(data)
|
|
3321
|
+
spinner?.start()
|
|
3322
|
+
spinner?.info(`Installing ${fixSpec}`)
|
|
3129
3323
|
|
|
3130
3324
|
// eslint-disable-next-line no-await-in-loop
|
|
3131
3325
|
await editablePkgJson.save()
|
|
@@ -3133,11 +3327,70 @@ async function pnpmFix(pkgEnvDetails, cwd, options) {
|
|
|
3133
3327
|
await runAgentInstall(pkgEnvDetails, {
|
|
3134
3328
|
spinner
|
|
3135
3329
|
})
|
|
3330
|
+
if (test) {
|
|
3331
|
+
spinner?.info(`Testing ${fixSpec}`)
|
|
3332
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3333
|
+
await npm.runScript(testScript, [], {
|
|
3334
|
+
spinner,
|
|
3335
|
+
stdio: 'ignore'
|
|
3336
|
+
})
|
|
3337
|
+
}
|
|
3338
|
+
try {
|
|
3339
|
+
const branchName = `fix-${name}-${targetVersion.replace(/\./g, '-')}`
|
|
3340
|
+
const commitMsg = `fix: upgrade ${name} to ${targetVersion}`
|
|
3341
|
+
const { owner, repo } = getRepoInfo()
|
|
3342
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3343
|
+
await commitAndPushFix(branchName, commitMsg, cwd)
|
|
3344
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3345
|
+
await createPullRequest({
|
|
3346
|
+
owner,
|
|
3347
|
+
repo,
|
|
3348
|
+
title: commitMsg,
|
|
3349
|
+
head: branchName,
|
|
3350
|
+
base: process.env['GITHUB_REF_NAME'] ?? 'master',
|
|
3351
|
+
body: `This PR fixes a security issue in \`${name}\` by upgrading to \`${targetVersion}\`.`
|
|
3352
|
+
})
|
|
3353
|
+
} catch (e) {
|
|
3354
|
+
console.log(e)
|
|
3355
|
+
}
|
|
3356
|
+
logger.logger.success(`Fixed ${name}`)
|
|
3136
3357
|
} catch {
|
|
3137
|
-
spinner?.error(`Reverting ${
|
|
3358
|
+
spinner?.error(`Reverting ${fixSpec}`)
|
|
3359
|
+
const pnpmKeyCount = Object.keys(data[PNPM$9]).length
|
|
3360
|
+
const pnpmOverridesKeyCount = Object.keys(
|
|
3361
|
+
data[PNPM$9][OVERRIDES$2]
|
|
3362
|
+
).length
|
|
3363
|
+
if (pnpmKeyCount === 1 && pnpmOverridesKeyCount === 1) {
|
|
3364
|
+
editablePkgJson.update({
|
|
3365
|
+
// Setting to `undefined` will remove the property.
|
|
3366
|
+
[PNPM$9]: undefined
|
|
3367
|
+
})
|
|
3368
|
+
} else {
|
|
3369
|
+
editablePkgJson.update({
|
|
3370
|
+
[PNPM$9]: {
|
|
3371
|
+
...oldPnpm,
|
|
3372
|
+
[OVERRIDES$2]:
|
|
3373
|
+
pnpmOverridesKeyCount === 1
|
|
3374
|
+
? undefined
|
|
3375
|
+
: {
|
|
3376
|
+
[overrideKey]: undefined,
|
|
3377
|
+
...oldOverrides
|
|
3378
|
+
}
|
|
3379
|
+
}
|
|
3380
|
+
})
|
|
3381
|
+
}
|
|
3382
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3383
|
+
await editablePkgJson.save()
|
|
3384
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3385
|
+
await runAgentInstall(pkgEnvDetails, {
|
|
3386
|
+
spinner
|
|
3387
|
+
})
|
|
3388
|
+
spinner?.stop()
|
|
3389
|
+
logger.logger.error(`Failed to fix ${oldSpec}`)
|
|
3138
3390
|
}
|
|
3139
3391
|
} else {
|
|
3140
|
-
spinner?.
|
|
3392
|
+
spinner?.stop()
|
|
3393
|
+
logger.logger.error(`Could not patch ${oldSpec}`)
|
|
3141
3394
|
}
|
|
3142
3395
|
}
|
|
3143
3396
|
}
|
|
@@ -3543,39 +3796,59 @@ async function detectAndValidatePackageEnvironment(cwd, options) {
|
|
|
3543
3796
|
|
|
3544
3797
|
const { NPM: NPM$a, PNPM: PNPM$7 } = constants
|
|
3545
3798
|
const CMD_NAME$2 = 'socket fix'
|
|
3546
|
-
async function runFix(
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3799
|
+
async function runFix({
|
|
3800
|
+
cwd = process.cwd(),
|
|
3801
|
+
spinner,
|
|
3802
|
+
test = false,
|
|
3803
|
+
testScript = 'test'
|
|
3804
|
+
}) {
|
|
3551
3805
|
const pkgEnvDetails = await detectAndValidatePackageEnvironment(cwd, {
|
|
3552
3806
|
cmdName: CMD_NAME$2,
|
|
3553
3807
|
logger: logger.logger
|
|
3554
3808
|
})
|
|
3555
3809
|
if (!pkgEnvDetails) {
|
|
3556
|
-
spinner
|
|
3810
|
+
spinner?.stop()
|
|
3557
3811
|
return
|
|
3558
3812
|
}
|
|
3813
|
+
logger.logger.info(`Fixing packages for ${pkgEnvDetails.agent}`)
|
|
3559
3814
|
switch (pkgEnvDetails.agent) {
|
|
3560
3815
|
case NPM$a: {
|
|
3561
|
-
await npmFix(pkgEnvDetails,
|
|
3816
|
+
await npmFix(pkgEnvDetails, {
|
|
3817
|
+
spinner,
|
|
3818
|
+
test,
|
|
3819
|
+
testScript
|
|
3820
|
+
})
|
|
3562
3821
|
break
|
|
3563
3822
|
}
|
|
3564
3823
|
case PNPM$7: {
|
|
3565
|
-
await pnpmFix(pkgEnvDetails,
|
|
3824
|
+
await pnpmFix(pkgEnvDetails, {
|
|
3825
|
+
spinner,
|
|
3826
|
+
test,
|
|
3827
|
+
testScript
|
|
3828
|
+
})
|
|
3566
3829
|
break
|
|
3567
3830
|
}
|
|
3568
3831
|
}
|
|
3569
|
-
spinner.successAndStop('Socket.dev fix successful')
|
|
3832
|
+
// spinner.successAndStop('Socket.dev fix successful')
|
|
3570
3833
|
}
|
|
3571
3834
|
|
|
3572
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
3835
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$w } = constants
|
|
3573
3836
|
const config$z = {
|
|
3574
3837
|
commandName: 'fix',
|
|
3575
3838
|
description: 'Fix "fixable" Socket alerts',
|
|
3576
3839
|
hidden: true,
|
|
3577
3840
|
flags: {
|
|
3578
|
-
...commonFlags
|
|
3841
|
+
...commonFlags,
|
|
3842
|
+
test: {
|
|
3843
|
+
type: 'boolean',
|
|
3844
|
+
default: true,
|
|
3845
|
+
description: 'Very the fix by running unit tests'
|
|
3846
|
+
},
|
|
3847
|
+
testScript: {
|
|
3848
|
+
type: 'string',
|
|
3849
|
+
default: 'test',
|
|
3850
|
+
description: 'The test script to run for each fix attempt'
|
|
3851
|
+
}
|
|
3579
3852
|
},
|
|
3580
3853
|
help: (command, config) => `
|
|
3581
3854
|
Usage
|
|
@@ -3598,10 +3871,17 @@ async function run$z(argv, importMeta, { parentName }) {
|
|
|
3598
3871
|
parentName
|
|
3599
3872
|
})
|
|
3600
3873
|
if (cli.flags['dryRun']) {
|
|
3601
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
3874
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$w)
|
|
3602
3875
|
return
|
|
3603
3876
|
}
|
|
3604
|
-
|
|
3877
|
+
|
|
3878
|
+
// Lazily access constants.spinner.
|
|
3879
|
+
const { spinner } = constants
|
|
3880
|
+
await runFix({
|
|
3881
|
+
spinner,
|
|
3882
|
+
test: Boolean(cli.flags['test']),
|
|
3883
|
+
testScript: cli.flags['testScript']
|
|
3884
|
+
})
|
|
3605
3885
|
}
|
|
3606
3886
|
|
|
3607
3887
|
async function fetchPackageInfo(pkgName, pkgVersion, includeAllIssues) {
|
|
@@ -3626,10 +3906,10 @@ async function fetchPackageInfo(pkgName, pkgVersion, includeAllIssues) {
|
|
|
3626
3906
|
)
|
|
3627
3907
|
spinner.successAndStop('Data fetched')
|
|
3628
3908
|
if (result.success === false) {
|
|
3629
|
-
|
|
3909
|
+
handleUnsuccessfulApiResponse('getIssuesByNPMPackage', result)
|
|
3630
3910
|
}
|
|
3631
3911
|
if (scoreResult.success === false) {
|
|
3632
|
-
|
|
3912
|
+
handleUnsuccessfulApiResponse('getScoreByNPMPackage', scoreResult)
|
|
3633
3913
|
}
|
|
3634
3914
|
const severityCount = shadowNpmInject.getSeverityCount(
|
|
3635
3915
|
result.data,
|
|
@@ -3790,7 +4070,7 @@ async function handlePackageInfo({
|
|
|
3790
4070
|
}
|
|
3791
4071
|
}
|
|
3792
4072
|
|
|
3793
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4073
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$v } = constants
|
|
3794
4074
|
const config$y = {
|
|
3795
4075
|
commandName: 'info',
|
|
3796
4076
|
description: 'Look up info regarding a package',
|
|
@@ -3858,7 +4138,7 @@ async function run$y(argv, importMeta, { parentName }) {
|
|
|
3858
4138
|
const pkgVersion =
|
|
3859
4139
|
versionSeparator < 1 ? 'latest' : rawPkgName.slice(versionSeparator + 1)
|
|
3860
4140
|
if (cli.flags['dryRun']) {
|
|
3861
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4141
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$v)
|
|
3862
4142
|
return
|
|
3863
4143
|
}
|
|
3864
4144
|
await handlePackageInfo({
|
|
@@ -3895,7 +4175,6 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
|
|
|
3895
4175
|
if (!result.success) {
|
|
3896
4176
|
logger.logger.fail('Authentication failed...')
|
|
3897
4177
|
handleUnsuccessfulApiResponse('getOrganizations', result)
|
|
3898
|
-
return
|
|
3899
4178
|
}
|
|
3900
4179
|
logger.logger.success('API key verified')
|
|
3901
4180
|
const orgs = result.data
|
|
@@ -3933,16 +4212,24 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
|
|
|
3933
4212
|
}
|
|
3934
4213
|
}
|
|
3935
4214
|
spinner.stop()
|
|
3936
|
-
const
|
|
4215
|
+
const previousPersistedToken = shadowNpmInject.getConfigValue('apiToken')
|
|
3937
4216
|
try {
|
|
3938
4217
|
applyLogin(apiToken, enforcedOrgs, apiBaseUrl, apiProxy)
|
|
3939
|
-
logger.logger.success(
|
|
4218
|
+
logger.logger.success(
|
|
4219
|
+
`API credentials ${previousPersistedToken === apiToken ? 'refreshed' : previousPersistedToken ? 'updated' : 'set'}`
|
|
4220
|
+
)
|
|
4221
|
+
if (!shadowNpmInject.isReadOnlyConfig()) {
|
|
4222
|
+
logger.logger.log('')
|
|
4223
|
+
logger.logger.warn(
|
|
4224
|
+
'Note: config is in read-only mode, at least one key was overridden through flag/env, so the login was not persisted!'
|
|
4225
|
+
)
|
|
4226
|
+
}
|
|
3940
4227
|
} catch {
|
|
3941
4228
|
logger.logger.fail(`API login failed`)
|
|
3942
4229
|
}
|
|
3943
4230
|
}
|
|
3944
4231
|
|
|
3945
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4232
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$u } = constants
|
|
3946
4233
|
const config$x = {
|
|
3947
4234
|
commandName: 'login',
|
|
3948
4235
|
description: 'Socket API login',
|
|
@@ -3962,6 +4249,9 @@ const config$x = {
|
|
|
3962
4249
|
Usage
|
|
3963
4250
|
$ ${command}
|
|
3964
4251
|
|
|
4252
|
+
API Token Requirements
|
|
4253
|
+
- Quota: 1 unit
|
|
4254
|
+
|
|
3965
4255
|
Logs into the Socket API by prompting for an API key
|
|
3966
4256
|
|
|
3967
4257
|
Options
|
|
@@ -3987,7 +4277,7 @@ async function run$x(argv, importMeta, { parentName }) {
|
|
|
3987
4277
|
const apiBaseUrl = cli.flags['apiBaseUrl']
|
|
3988
4278
|
const apiProxy = cli.flags['apiProxy']
|
|
3989
4279
|
if (cli.flags['dryRun']) {
|
|
3990
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4280
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$u)
|
|
3991
4281
|
return
|
|
3992
4282
|
}
|
|
3993
4283
|
if (!isInteractive()) {
|
|
@@ -4009,12 +4299,18 @@ function attemptLogout() {
|
|
|
4009
4299
|
try {
|
|
4010
4300
|
applyLogout()
|
|
4011
4301
|
logger.logger.success('Successfully logged out')
|
|
4302
|
+
if (!shadowNpmInject.isReadOnlyConfig()) {
|
|
4303
|
+
logger.logger.log('')
|
|
4304
|
+
logger.logger.warn(
|
|
4305
|
+
'Note: config is in read-only mode, at least one key was overridden through flag/env, so the logout was not persisted!'
|
|
4306
|
+
)
|
|
4307
|
+
}
|
|
4012
4308
|
} catch {
|
|
4013
4309
|
logger.logger.fail('Failed to complete logout steps')
|
|
4014
4310
|
}
|
|
4015
4311
|
}
|
|
4016
4312
|
|
|
4017
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4313
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$t } = constants
|
|
4018
4314
|
const config$w = {
|
|
4019
4315
|
commandName: 'logout',
|
|
4020
4316
|
description: 'Socket API logout',
|
|
@@ -4042,7 +4338,7 @@ async function run$w(argv, importMeta, { parentName }) {
|
|
|
4042
4338
|
parentName
|
|
4043
4339
|
})
|
|
4044
4340
|
if (cli.flags['dryRun']) {
|
|
4045
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4341
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$t)
|
|
4046
4342
|
return
|
|
4047
4343
|
}
|
|
4048
4344
|
attemptLogout()
|
|
@@ -4150,7 +4446,7 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
|
|
|
4150
4446
|
}
|
|
4151
4447
|
}
|
|
4152
4448
|
|
|
4153
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4449
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$s } = constants
|
|
4154
4450
|
const config$v = {
|
|
4155
4451
|
commandName: 'gradle',
|
|
4156
4452
|
description:
|
|
@@ -4297,7 +4593,7 @@ async function run$v(argv, importMeta, { parentName }) {
|
|
|
4297
4593
|
.filter(Boolean)
|
|
4298
4594
|
}
|
|
4299
4595
|
if (cli.flags['dryRun']) {
|
|
4300
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4596
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$s)
|
|
4301
4597
|
return
|
|
4302
4598
|
}
|
|
4303
4599
|
await convertGradleToMaven(target, bin, out, verbose, gradleOpts)
|
|
@@ -4406,7 +4702,7 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
|
|
|
4406
4702
|
}
|
|
4407
4703
|
}
|
|
4408
4704
|
|
|
4409
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4705
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$r } = constants
|
|
4410
4706
|
const config$u = {
|
|
4411
4707
|
commandName: 'scala',
|
|
4412
4708
|
description:
|
|
@@ -4551,13 +4847,13 @@ async function run$u(argv, importMeta, { parentName }) {
|
|
|
4551
4847
|
.filter(Boolean)
|
|
4552
4848
|
}
|
|
4553
4849
|
if (cli.flags['dryRun']) {
|
|
4554
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4850
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$r)
|
|
4555
4851
|
return
|
|
4556
4852
|
}
|
|
4557
4853
|
await convertSbtToMaven(target, bin, out, verbose, sbtOpts)
|
|
4558
4854
|
}
|
|
4559
4855
|
|
|
4560
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4856
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$q } = constants
|
|
4561
4857
|
const config$t = {
|
|
4562
4858
|
commandName: 'auto',
|
|
4563
4859
|
description: 'Auto-detect build and attempt to generate manifest file',
|
|
@@ -4623,7 +4919,7 @@ async function run$t(argv, importMeta, { parentName }) {
|
|
|
4623
4919
|
}
|
|
4624
4920
|
subArgs.push(dir)
|
|
4625
4921
|
if (cli.flags['dryRun']) {
|
|
4626
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4922
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$q)
|
|
4627
4923
|
return
|
|
4628
4924
|
}
|
|
4629
4925
|
await cmdManifestScala.run(subArgs, importMeta, {
|
|
@@ -4640,7 +4936,7 @@ async function run$t(argv, importMeta, { parentName }) {
|
|
|
4640
4936
|
subArgs.push(cwd)
|
|
4641
4937
|
}
|
|
4642
4938
|
if (cli.flags['dryRun']) {
|
|
4643
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4939
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$q)
|
|
4644
4940
|
return
|
|
4645
4941
|
}
|
|
4646
4942
|
await cmdManifestGradle.run(subArgs, importMeta, {
|
|
@@ -4649,7 +4945,7 @@ async function run$t(argv, importMeta, { parentName }) {
|
|
|
4649
4945
|
return
|
|
4650
4946
|
}
|
|
4651
4947
|
if (cli.flags['dryRun']) {
|
|
4652
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4948
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$q)
|
|
4653
4949
|
return
|
|
4654
4950
|
}
|
|
4655
4951
|
|
|
@@ -4678,7 +4974,7 @@ async function run$t(argv, importMeta, { parentName }) {
|
|
|
4678
4974
|
.showHelp()
|
|
4679
4975
|
}
|
|
4680
4976
|
|
|
4681
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4977
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$p } = constants
|
|
4682
4978
|
|
|
4683
4979
|
// TODO: we may want to dedupe some pieces for all gradle languages. I think it
|
|
4684
4980
|
// makes sense to have separate commands for them and I think it makes
|
|
@@ -4831,7 +5127,7 @@ async function run$s(argv, importMeta, { parentName }) {
|
|
|
4831
5127
|
.filter(Boolean)
|
|
4832
5128
|
}
|
|
4833
5129
|
if (cli.flags['dryRun']) {
|
|
4834
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
5130
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$p)
|
|
4835
5131
|
return
|
|
4836
5132
|
}
|
|
4837
5133
|
await convertGradleToMaven(target, bin, out, verbose, gradleOpts)
|
|
@@ -4882,7 +5178,7 @@ async function wrapNpm(argv) {
|
|
|
4882
5178
|
await shadowBin(NPM$8, argv)
|
|
4883
5179
|
}
|
|
4884
5180
|
|
|
4885
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
5181
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$o, NPM: NPM$7 } = constants
|
|
4886
5182
|
const config$q = {
|
|
4887
5183
|
commandName: 'npm',
|
|
4888
5184
|
description: `${NPM$7} wrapper functionality`,
|
|
@@ -4909,7 +5205,7 @@ async function run$q(argv, importMeta, { parentName }) {
|
|
|
4909
5205
|
parentName
|
|
4910
5206
|
})
|
|
4911
5207
|
if (cli.flags['dryRun']) {
|
|
4912
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
5208
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$o)
|
|
4913
5209
|
return
|
|
4914
5210
|
}
|
|
4915
5211
|
await wrapNpm(argv)
|
|
@@ -4922,7 +5218,7 @@ async function wrapNpx(argv) {
|
|
|
4922
5218
|
await shadowBin(NPX$2, argv)
|
|
4923
5219
|
}
|
|
4924
5220
|
|
|
4925
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
5221
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$n, NPX: NPX$1 } = constants
|
|
4926
5222
|
const config$p = {
|
|
4927
5223
|
commandName: 'npx',
|
|
4928
5224
|
description: `${NPX$1} wrapper functionality`,
|
|
@@ -4949,13 +5245,13 @@ async function run$p(argv, importMeta, { parentName }) {
|
|
|
4949
5245
|
parentName
|
|
4950
5246
|
})
|
|
4951
5247
|
if (cli.flags['dryRun']) {
|
|
4952
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
5248
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$n)
|
|
4953
5249
|
return
|
|
4954
5250
|
}
|
|
4955
5251
|
await wrapNpx(argv)
|
|
4956
5252
|
}
|
|
4957
5253
|
|
|
4958
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
5254
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$m } = constants
|
|
4959
5255
|
const config$o = {
|
|
4960
5256
|
commandName: 'oops',
|
|
4961
5257
|
description: 'Trigger an intentional error (for development)',
|
|
@@ -4983,7 +5279,7 @@ async function run$o(argv, importMeta, { parentName }) {
|
|
|
4983
5279
|
parentName
|
|
4984
5280
|
})
|
|
4985
5281
|
if (cli.flags['dryRun']) {
|
|
4986
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
5282
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$m)
|
|
4987
5283
|
return
|
|
4988
5284
|
}
|
|
4989
5285
|
throw new Error('This error was intentionally left blank')
|
|
@@ -5872,7 +6168,7 @@ async function applyOptimization(cwd, pin, prod) {
|
|
|
5872
6168
|
}
|
|
5873
6169
|
}
|
|
5874
6170
|
|
|
5875
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
6171
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$l } = constants
|
|
5876
6172
|
const config$n = {
|
|
5877
6173
|
commandName: 'optimize',
|
|
5878
6174
|
description: 'Optimize dependencies with @socketregistry overrides',
|
|
@@ -5916,7 +6212,7 @@ async function run$n(argv, importMeta, { parentName }) {
|
|
|
5916
6212
|
})
|
|
5917
6213
|
const cwd = process.cwd()
|
|
5918
6214
|
if (cli.flags['dryRun']) {
|
|
5919
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
6215
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$l)
|
|
5920
6216
|
return
|
|
5921
6217
|
}
|
|
5922
6218
|
await applyOptimization(
|
|
@@ -5939,7 +6235,6 @@ async function fetchOrganization() {
|
|
|
5939
6235
|
spinner.successAndStop('Received organization list response.')
|
|
5940
6236
|
if (!result.success) {
|
|
5941
6237
|
handleUnsuccessfulApiResponse('getOrganizations', result)
|
|
5942
|
-
return
|
|
5943
6238
|
}
|
|
5944
6239
|
return result.data
|
|
5945
6240
|
}
|
|
@@ -6018,7 +6313,7 @@ async function handleOrganizationList(outputKind = 'text') {
|
|
|
6018
6313
|
await outputOrganizationList(data, outputKind)
|
|
6019
6314
|
}
|
|
6020
6315
|
|
|
6021
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
6316
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$k } = constants
|
|
6022
6317
|
const config$m = {
|
|
6023
6318
|
commandName: 'list',
|
|
6024
6319
|
description: 'List organizations associated with the API key used',
|
|
@@ -6031,6 +6326,10 @@ const config$m = {
|
|
|
6031
6326
|
Usage
|
|
6032
6327
|
$ ${command}
|
|
6033
6328
|
|
|
6329
|
+
API Token Requirements
|
|
6330
|
+
- Quota: 1 unit
|
|
6331
|
+
- Permissions: none (does need a token)
|
|
6332
|
+
|
|
6034
6333
|
Options
|
|
6035
6334
|
${getFlagListOutput(config$m.flags, 6)}
|
|
6036
6335
|
`
|
|
@@ -6071,7 +6370,7 @@ async function run$m(argv, importMeta, { parentName }) {
|
|
|
6071
6370
|
return
|
|
6072
6371
|
}
|
|
6073
6372
|
if (cli.flags['dryRun']) {
|
|
6074
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
6373
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$k)
|
|
6075
6374
|
return
|
|
6076
6375
|
}
|
|
6077
6376
|
await handleOrganizationList(json ? 'json' : markdown ? 'markdown' : 'text')
|
|
@@ -6090,7 +6389,6 @@ async function fetchLicensePolicy(orgSlug) {
|
|
|
6090
6389
|
spinner.successAndStop('Received organization license policy response.')
|
|
6091
6390
|
if (!result.success) {
|
|
6092
6391
|
handleUnsuccessfulApiResponse('getOrgLicensePolicy', result)
|
|
6093
|
-
return
|
|
6094
6392
|
}
|
|
6095
6393
|
return result.data
|
|
6096
6394
|
}
|
|
@@ -6135,7 +6433,7 @@ async function handleLicensePolicy(orgSlug, outputKind) {
|
|
|
6135
6433
|
await outputLicensePolicy(data, outputKind)
|
|
6136
6434
|
}
|
|
6137
6435
|
|
|
6138
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
6436
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$j } = constants
|
|
6139
6437
|
|
|
6140
6438
|
// TODO: secret toplevel alias `socket license policy`?
|
|
6141
6439
|
const config$l = {
|
|
@@ -6150,6 +6448,10 @@ const config$l = {
|
|
|
6150
6448
|
Usage
|
|
6151
6449
|
$ ${command} <org slug>
|
|
6152
6450
|
|
|
6451
|
+
API Token Requirements
|
|
6452
|
+
- Quota: 1 unit
|
|
6453
|
+
- Permissions: license-policy:read
|
|
6454
|
+
|
|
6153
6455
|
Options
|
|
6154
6456
|
${getFlagListOutput(config$l.flags, 6)}
|
|
6155
6457
|
|
|
@@ -6206,7 +6508,7 @@ async function run$l(argv, importMeta, { parentName }) {
|
|
|
6206
6508
|
return
|
|
6207
6509
|
}
|
|
6208
6510
|
if (cli.flags['dryRun']) {
|
|
6209
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
6511
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$j)
|
|
6210
6512
|
return
|
|
6211
6513
|
}
|
|
6212
6514
|
await handleLicensePolicy(
|
|
@@ -6228,7 +6530,6 @@ async function fetchSecurityPolicy(orgSlug) {
|
|
|
6228
6530
|
spinner.successAndStop('Received organization security policy response.')
|
|
6229
6531
|
if (!result.success) {
|
|
6230
6532
|
handleUnsuccessfulApiResponse('getOrgSecurityPolicy', result)
|
|
6231
|
-
return
|
|
6232
6533
|
}
|
|
6233
6534
|
return result.data
|
|
6234
6535
|
}
|
|
@@ -6274,7 +6575,7 @@ async function handleSecurityPolicy(orgSlug, outputKind) {
|
|
|
6274
6575
|
await outputSecurityPolicy(data, outputKind)
|
|
6275
6576
|
}
|
|
6276
6577
|
|
|
6277
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
6578
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$i } = constants
|
|
6278
6579
|
|
|
6279
6580
|
// TODO: secret toplevel alias `socket security policy`?
|
|
6280
6581
|
const config$k = {
|
|
@@ -6289,6 +6590,10 @@ const config$k = {
|
|
|
6289
6590
|
Usage
|
|
6290
6591
|
$ ${command} <org slug>
|
|
6291
6592
|
|
|
6593
|
+
API Token Requirements
|
|
6594
|
+
- Quota: 1 unit
|
|
6595
|
+
- Permissions: security-policy:read
|
|
6596
|
+
|
|
6292
6597
|
Options
|
|
6293
6598
|
${getFlagListOutput(config$k.flags, 6)}
|
|
6294
6599
|
|
|
@@ -6345,7 +6650,7 @@ async function run$k(argv, importMeta, { parentName }) {
|
|
|
6345
6650
|
return
|
|
6346
6651
|
}
|
|
6347
6652
|
if (cli.flags['dryRun']) {
|
|
6348
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
6653
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$i)
|
|
6349
6654
|
return
|
|
6350
6655
|
}
|
|
6351
6656
|
await handleSecurityPolicy(
|
|
@@ -6393,7 +6698,6 @@ async function fetchQuota() {
|
|
|
6393
6698
|
spinner.successAndStop('Received organization quota response.')
|
|
6394
6699
|
if (!result.success) {
|
|
6395
6700
|
handleUnsuccessfulApiResponse('getQuota', result)
|
|
6396
|
-
return
|
|
6397
6701
|
}
|
|
6398
6702
|
return result.data
|
|
6399
6703
|
}
|
|
@@ -6432,7 +6736,7 @@ async function handleQuota(outputKind = 'text') {
|
|
|
6432
6736
|
await outputQuota(data, outputKind)
|
|
6433
6737
|
}
|
|
6434
6738
|
|
|
6435
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
6739
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$h } = constants
|
|
6436
6740
|
const config$j = {
|
|
6437
6741
|
commandName: 'quota',
|
|
6438
6742
|
description: 'List organizations associated with the API key used',
|
|
@@ -6485,7 +6789,7 @@ async function run$j(argv, importMeta, { parentName }) {
|
|
|
6485
6789
|
return
|
|
6486
6790
|
}
|
|
6487
6791
|
if (cli.flags['dryRun']) {
|
|
6488
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
6792
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$h)
|
|
6489
6793
|
return
|
|
6490
6794
|
}
|
|
6491
6795
|
await handleQuota(json ? 'json' : markdown ? 'markdown' : 'text')
|
|
@@ -6518,6 +6822,7 @@ const cmdOrganization = {
|
|
|
6518
6822
|
}
|
|
6519
6823
|
}
|
|
6520
6824
|
|
|
6825
|
+
const { SOCKET_CLI_ISSUES_URL } = constants
|
|
6521
6826
|
async function fetchPurlDeepScore(purl) {
|
|
6522
6827
|
const apiToken = shadowNpmInject.getDefaultToken()
|
|
6523
6828
|
if (!apiToken) {
|
|
@@ -6559,7 +6864,7 @@ async function fetchPurlDeepScore(purl) {
|
|
|
6559
6864
|
return JSON.parse(data)
|
|
6560
6865
|
} catch (e) {
|
|
6561
6866
|
throw new Error(
|
|
6562
|
-
|
|
6867
|
+
`Unable to parse JSON response from the Socket API.\nPlease report to ${SOCKET_CLI_ISSUES_URL}`
|
|
6563
6868
|
)
|
|
6564
6869
|
}
|
|
6565
6870
|
}
|
|
@@ -6752,7 +7057,7 @@ async function outputPurlScore(purl, data, outputKind) {
|
|
|
6752
7057
|
)
|
|
6753
7058
|
} else {
|
|
6754
7059
|
logger.logger.log(
|
|
6755
|
-
'This package had no alerts and neither did any of its direct/transitive dependencies
|
|
7060
|
+
'This package had no alerts and neither did any of its direct/transitive dependencies'
|
|
6756
7061
|
)
|
|
6757
7062
|
}
|
|
6758
7063
|
logger.logger.log('')
|
|
@@ -6827,7 +7132,7 @@ function parsePackageSpecifiers(ecosystem, pkgs) {
|
|
|
6827
7132
|
}
|
|
6828
7133
|
}
|
|
6829
7134
|
|
|
6830
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
7135
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$g } = constants
|
|
6831
7136
|
const config$i = {
|
|
6832
7137
|
commandName: 'score',
|
|
6833
7138
|
description:
|
|
@@ -6841,13 +7146,13 @@ const config$i = {
|
|
|
6841
7146
|
Usage
|
|
6842
7147
|
$ ${command} <<ecosystem> <name> | <purl>>
|
|
6843
7148
|
|
|
7149
|
+
API Token Requirements
|
|
7150
|
+
- Quota: 100 units
|
|
7151
|
+
- Permissions: packages:list
|
|
7152
|
+
|
|
6844
7153
|
Options
|
|
6845
7154
|
${getFlagListOutput(config.flags, 6)}
|
|
6846
7155
|
|
|
6847
|
-
Requirements
|
|
6848
|
-
- quota: 100
|
|
6849
|
-
- scope: \`packages:list\`
|
|
6850
|
-
|
|
6851
7156
|
Show deep scoring details for one package. The score will reflect the package
|
|
6852
7157
|
itself, any of its dependencies, and any of its transitive dependencies.
|
|
6853
7158
|
|
|
@@ -6919,7 +7224,7 @@ async function run$i(argv, importMeta, { parentName }) {
|
|
|
6919
7224
|
return
|
|
6920
7225
|
}
|
|
6921
7226
|
if (cli.flags['dryRun']) {
|
|
6922
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
7227
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$g)
|
|
6923
7228
|
return
|
|
6924
7229
|
}
|
|
6925
7230
|
await handlePurlDeepScore(
|
|
@@ -6943,10 +7248,6 @@ async function fetchPurlsShallowScore(purls) {
|
|
|
6943
7248
|
sockSdk.batchPackageFetch(
|
|
6944
7249
|
{
|
|
6945
7250
|
alerts: 'true'
|
|
6946
|
-
// compact: false,
|
|
6947
|
-
// fixable: false,
|
|
6948
|
-
// licenseattrib: false,
|
|
6949
|
-
// licensedetails: false
|
|
6950
7251
|
},
|
|
6951
7252
|
{
|
|
6952
7253
|
components: purls.map(purl => ({
|
|
@@ -6959,7 +7260,6 @@ async function fetchPurlsShallowScore(purls) {
|
|
|
6959
7260
|
spinner.successAndStop('Request completed')
|
|
6960
7261
|
if (!result.success) {
|
|
6961
7262
|
handleUnsuccessfulApiResponse('batchPackageFetch', result)
|
|
6962
|
-
return
|
|
6963
7263
|
}
|
|
6964
7264
|
return result
|
|
6965
7265
|
}
|
|
@@ -7116,7 +7416,7 @@ async function handlePurlsShallowScore({ outputKind, purls }) {
|
|
|
7116
7416
|
outputPurlsShallowScore(purls, packageData.data, outputKind)
|
|
7117
7417
|
}
|
|
7118
7418
|
|
|
7119
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
7419
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$f } = constants
|
|
7120
7420
|
const config$h = {
|
|
7121
7421
|
commandName: 'shallow',
|
|
7122
7422
|
description:
|
|
@@ -7130,13 +7430,13 @@ const config$h = {
|
|
|
7130
7430
|
Usage
|
|
7131
7431
|
$ ${command} <<ecosystem> <name> [<name> ...] | <purl> [<purl> ...]>
|
|
7132
7432
|
|
|
7433
|
+
API Token Requirements
|
|
7434
|
+
- Quota: 100 units
|
|
7435
|
+
- Permissions: packages:list
|
|
7436
|
+
|
|
7133
7437
|
Options
|
|
7134
7438
|
${getFlagListOutput(config.flags, 6)}
|
|
7135
7439
|
|
|
7136
|
-
Requirements
|
|
7137
|
-
- quota: 100
|
|
7138
|
-
- scope: \`packages:list\`
|
|
7139
|
-
|
|
7140
7440
|
Show scoring details for one or more packages purely based on their own package.
|
|
7141
7441
|
This means that any dependency scores are not reflected by the score. You can
|
|
7142
7442
|
use the \`socket package score <pkg>\` command to get its full transitive score.
|
|
@@ -7207,7 +7507,7 @@ async function run$h(argv, importMeta, { parentName }) {
|
|
|
7207
7507
|
return
|
|
7208
7508
|
}
|
|
7209
7509
|
if (cli.flags['dryRun']) {
|
|
7210
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
7510
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$f)
|
|
7211
7511
|
return
|
|
7212
7512
|
}
|
|
7213
7513
|
await handlePurlsShallowScore({
|
|
@@ -7260,7 +7560,7 @@ async function runRawNpm(argv) {
|
|
|
7260
7560
|
await spawnPromise
|
|
7261
7561
|
}
|
|
7262
7562
|
|
|
7263
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
7563
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$e, NPM } = constants
|
|
7264
7564
|
const config$g = {
|
|
7265
7565
|
commandName: 'raw-npm',
|
|
7266
7566
|
description: `Temporarily disable the Socket ${NPM} wrapper`,
|
|
@@ -7288,7 +7588,7 @@ async function run$g(argv, importMeta, { parentName }) {
|
|
|
7288
7588
|
parentName
|
|
7289
7589
|
})
|
|
7290
7590
|
if (cli.flags['dryRun']) {
|
|
7291
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
7591
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$e)
|
|
7292
7592
|
return
|
|
7293
7593
|
}
|
|
7294
7594
|
await runRawNpm(argv)
|
|
@@ -7310,7 +7610,7 @@ async function runRawNpx(argv) {
|
|
|
7310
7610
|
await spawnPromise
|
|
7311
7611
|
}
|
|
7312
7612
|
|
|
7313
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
7613
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$d, NPX } = constants
|
|
7314
7614
|
const config$f = {
|
|
7315
7615
|
commandName: 'raw-npx',
|
|
7316
7616
|
description: `Temporarily disable the Socket ${NPX} wrapper`,
|
|
@@ -7338,242 +7638,12 @@ async function run$f(argv, importMeta, { parentName }) {
|
|
|
7338
7638
|
parentName
|
|
7339
7639
|
})
|
|
7340
7640
|
if (cli.flags['dryRun']) {
|
|
7341
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
7641
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$d)
|
|
7342
7642
|
return
|
|
7343
7643
|
}
|
|
7344
7644
|
await runRawNpx(argv)
|
|
7345
7645
|
}
|
|
7346
7646
|
|
|
7347
|
-
const { DRY_RUN_LABEL } = constants
|
|
7348
|
-
async function createReport(socketConfig, inputPaths, { cwd, dryRun }) {
|
|
7349
|
-
// Lazily access constants.spinner.
|
|
7350
|
-
const { spinner } = constants
|
|
7351
|
-
const sockSdk = await shadowNpmInject.setupSdk()
|
|
7352
|
-
const supportedFiles = await sockSdk
|
|
7353
|
-
.getReportSupportedFiles()
|
|
7354
|
-
.then(res => {
|
|
7355
|
-
if (!res.success) {
|
|
7356
|
-
handleUnsuccessfulApiResponse('getReportSupportedFiles', res)
|
|
7357
|
-
}
|
|
7358
|
-
return res.data
|
|
7359
|
-
})
|
|
7360
|
-
.catch(cause => {
|
|
7361
|
-
throw new Error('Failed getting supported files for report', {
|
|
7362
|
-
cause
|
|
7363
|
-
})
|
|
7364
|
-
})
|
|
7365
|
-
const packagePaths = await shadowNpmPaths.getPackageFilesForScan(
|
|
7366
|
-
cwd,
|
|
7367
|
-
inputPaths,
|
|
7368
|
-
supportedFiles,
|
|
7369
|
-
socketConfig
|
|
7370
|
-
)
|
|
7371
|
-
const packagePathsCount = packagePaths.length
|
|
7372
|
-
if (packagePathsCount && debug.isDebug()) {
|
|
7373
|
-
for (const pkgPath of packagePaths) {
|
|
7374
|
-
debug.debugLog(`Uploading: ${pkgPath}`)
|
|
7375
|
-
}
|
|
7376
|
-
}
|
|
7377
|
-
if (dryRun) {
|
|
7378
|
-
debug.debugLog(`${DRY_RUN_LABEL}: Skipped actual upload`)
|
|
7379
|
-
return undefined
|
|
7380
|
-
}
|
|
7381
|
-
spinner.start(
|
|
7382
|
-
`Creating report with ${packagePathsCount} package ${words.pluralize('file', packagePathsCount)}`
|
|
7383
|
-
)
|
|
7384
|
-
const apiCall = sockSdk.createReportFromFilePaths(
|
|
7385
|
-
packagePaths,
|
|
7386
|
-
cwd,
|
|
7387
|
-
socketConfig?.issueRules
|
|
7388
|
-
)
|
|
7389
|
-
const result = await handleApiCall(apiCall, 'creating report')
|
|
7390
|
-
if (!result.success) {
|
|
7391
|
-
handleUnsuccessfulApiResponse('createReport', result)
|
|
7392
|
-
return undefined
|
|
7393
|
-
}
|
|
7394
|
-
spinner.successAndStop()
|
|
7395
|
-
return result
|
|
7396
|
-
}
|
|
7397
|
-
|
|
7398
|
-
async function getSocketConfig(absoluteConfigPath) {
|
|
7399
|
-
const socketConfig = await config$K
|
|
7400
|
-
.readSocketConfig(absoluteConfigPath)
|
|
7401
|
-
.catch(cause => {
|
|
7402
|
-
if (
|
|
7403
|
-
cause &&
|
|
7404
|
-
typeof cause === 'object' &&
|
|
7405
|
-
cause instanceof config$K.SocketValidationError
|
|
7406
|
-
) {
|
|
7407
|
-
// Inspired by workbox-build:
|
|
7408
|
-
// https://github.com/GoogleChrome/workbox/blob/95f97a207fd51efb3f8a653f6e3e58224183a778/packages/workbox-build/src/lib/validate-options.ts#L68-L71
|
|
7409
|
-
const betterErrors = betterAjvErrors.betterAjvErrors({
|
|
7410
|
-
basePath: 'config',
|
|
7411
|
-
data: cause.data,
|
|
7412
|
-
errors: cause.validationErrors,
|
|
7413
|
-
schema: cause.schema
|
|
7414
|
-
})
|
|
7415
|
-
throw new shadowNpmInject.InputError(
|
|
7416
|
-
'The socket.yml config is not valid',
|
|
7417
|
-
betterErrors
|
|
7418
|
-
.map(
|
|
7419
|
-
err =>
|
|
7420
|
-
`[${err.path}] ${err.message}.${err.suggestion ? err.suggestion : ''}`
|
|
7421
|
-
)
|
|
7422
|
-
.join('\n')
|
|
7423
|
-
)
|
|
7424
|
-
} else {
|
|
7425
|
-
throw new Error('Failed to read socket.yml config', {
|
|
7426
|
-
cause
|
|
7427
|
-
})
|
|
7428
|
-
}
|
|
7429
|
-
})
|
|
7430
|
-
return socketConfig
|
|
7431
|
-
}
|
|
7432
|
-
|
|
7433
|
-
const MAX_TIMEOUT_RETRY = 5
|
|
7434
|
-
const HTTP_CODE_TIMEOUT = 524
|
|
7435
|
-
async function fetchReportData$1(reportId, includeAllIssues, strict) {
|
|
7436
|
-
// Lazily access constants.spinner.
|
|
7437
|
-
const { spinner } = constants
|
|
7438
|
-
spinner.log('Fetching report with ID ${reportId} (this could take a while)')
|
|
7439
|
-
spinner.start(`Fetch started... (this could take a while)`)
|
|
7440
|
-
const sockSdk = await shadowNpmInject.setupSdk()
|
|
7441
|
-
let result
|
|
7442
|
-
for (let retry = 1; !result; ++retry) {
|
|
7443
|
-
try {
|
|
7444
|
-
// eslint-disable-next-line no-await-in-loop
|
|
7445
|
-
result = await handleApiCall(
|
|
7446
|
-
sockSdk.getReport(reportId),
|
|
7447
|
-
'fetching report'
|
|
7448
|
-
)
|
|
7449
|
-
} catch (err) {
|
|
7450
|
-
if (
|
|
7451
|
-
retry >= MAX_TIMEOUT_RETRY ||
|
|
7452
|
-
!(err instanceof Error) ||
|
|
7453
|
-
err.cause?.cause?.response?.statusCode !== HTTP_CODE_TIMEOUT
|
|
7454
|
-
) {
|
|
7455
|
-
spinner.stop(`Failed to fetch report`)
|
|
7456
|
-
throw err
|
|
7457
|
-
}
|
|
7458
|
-
spinner.fail(`Retrying report fetch ${retry} / ${MAX_TIMEOUT_RETRY}`)
|
|
7459
|
-
}
|
|
7460
|
-
}
|
|
7461
|
-
if (!result.success) {
|
|
7462
|
-
return handleUnsuccessfulApiResponse('getReport', result)
|
|
7463
|
-
}
|
|
7464
|
-
|
|
7465
|
-
// Conclude the status of the API call.
|
|
7466
|
-
if (strict) {
|
|
7467
|
-
if (result.data.healthy) {
|
|
7468
|
-
spinner.success('Report result is healthy and great!')
|
|
7469
|
-
} else {
|
|
7470
|
-
spinner.error('Report result deemed unhealthy for project')
|
|
7471
|
-
}
|
|
7472
|
-
} else if (!result.data.healthy) {
|
|
7473
|
-
const severityCount = shadowNpmInject.getSeverityCount(
|
|
7474
|
-
result.data.issues,
|
|
7475
|
-
includeAllIssues ? undefined : 'high'
|
|
7476
|
-
)
|
|
7477
|
-
const issueSummary = shadowNpmInject.formatSeverityCount(severityCount)
|
|
7478
|
-
spinner.success(`Report has these issues: ${issueSummary}`)
|
|
7479
|
-
} else {
|
|
7480
|
-
spinner.success('Report has no issues')
|
|
7481
|
-
}
|
|
7482
|
-
spinner.stop()
|
|
7483
|
-
return result.data
|
|
7484
|
-
}
|
|
7485
|
-
|
|
7486
|
-
function formatReportDataOutput(
|
|
7487
|
-
reportId,
|
|
7488
|
-
data,
|
|
7489
|
-
commandName,
|
|
7490
|
-
outputKind,
|
|
7491
|
-
strict,
|
|
7492
|
-
artifacts
|
|
7493
|
-
) {
|
|
7494
|
-
if (outputKind === 'json') {
|
|
7495
|
-
logger.logger.log(JSON.stringify(data, undefined, 2))
|
|
7496
|
-
} else {
|
|
7497
|
-
const format = new shadowNpmInject.ColorOrMarkdown(
|
|
7498
|
-
outputKind === 'markdown'
|
|
7499
|
-
)
|
|
7500
|
-
logger.logger.log(commonTags.stripIndents`
|
|
7501
|
-
Detailed info on socket.dev: ${format.hyperlink(reportId, data.url, {
|
|
7502
|
-
fallbackToUrl: true
|
|
7503
|
-
})}`)
|
|
7504
|
-
if (outputKind === 'print') {
|
|
7505
|
-
logger.logger.log(data)
|
|
7506
|
-
logger.logger.log(
|
|
7507
|
-
colors.dim(
|
|
7508
|
-
`Or rerun ${colors.italic(commandName)} using the ${colors.italic('--json')} flag to get full JSON output`
|
|
7509
|
-
)
|
|
7510
|
-
)
|
|
7511
|
-
logger.logger.log('The scan:')
|
|
7512
|
-
logger.logger.log(artifacts)
|
|
7513
|
-
}
|
|
7514
|
-
}
|
|
7515
|
-
if (strict && !data.healthy) {
|
|
7516
|
-
|
|
7517
|
-
process$1.exit(1)
|
|
7518
|
-
}
|
|
7519
|
-
}
|
|
7520
|
-
|
|
7521
|
-
async function fetchScan(orgSlug, scanId) {
|
|
7522
|
-
const apiToken = shadowNpmInject.getDefaultToken()
|
|
7523
|
-
if (!apiToken) {
|
|
7524
|
-
throw new shadowNpmInject.AuthError(
|
|
7525
|
-
'User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.'
|
|
7526
|
-
)
|
|
7527
|
-
}
|
|
7528
|
-
|
|
7529
|
-
// Lazily access constants.spinner.
|
|
7530
|
-
const { spinner } = constants
|
|
7531
|
-
spinner.start('Fetching scan data...')
|
|
7532
|
-
const response = await queryApi(
|
|
7533
|
-
`orgs/${orgSlug}/full-scans/${encodeURIComponent(scanId)}`,
|
|
7534
|
-
apiToken
|
|
7535
|
-
)
|
|
7536
|
-
spinner.successAndStop('Received response while fetching scan data.')
|
|
7537
|
-
if (!response.ok) {
|
|
7538
|
-
const err = await handleApiError(response.status)
|
|
7539
|
-
logger.logger.fail(
|
|
7540
|
-
failMsgWithBadge(response.statusText, `Fetch error: ${err}`)
|
|
7541
|
-
)
|
|
7542
|
-
return
|
|
7543
|
-
}
|
|
7544
|
-
|
|
7545
|
-
// This is nd-json; each line is a json object
|
|
7546
|
-
const jsons = await response.text()
|
|
7547
|
-
const lines = jsons.split('\n').filter(Boolean)
|
|
7548
|
-
const data = lines.map(line => {
|
|
7549
|
-
try {
|
|
7550
|
-
return JSON.parse(line)
|
|
7551
|
-
} catch {
|
|
7552
|
-
console.error(
|
|
7553
|
-
'At least one line item was returned that could not be parsed as JSON...'
|
|
7554
|
-
)
|
|
7555
|
-
return {}
|
|
7556
|
-
}
|
|
7557
|
-
})
|
|
7558
|
-
return data
|
|
7559
|
-
}
|
|
7560
|
-
|
|
7561
|
-
async function viewReport(reportId, { all, commandName, outputKind, strict }) {
|
|
7562
|
-
const result = await fetchReportData$1(reportId, all, strict)
|
|
7563
|
-
const artifacts = await fetchScan('socketdev', reportId)
|
|
7564
|
-
if (result) {
|
|
7565
|
-
formatReportDataOutput(
|
|
7566
|
-
reportId,
|
|
7567
|
-
result,
|
|
7568
|
-
commandName,
|
|
7569
|
-
outputKind,
|
|
7570
|
-
strict,
|
|
7571
|
-
artifacts
|
|
7572
|
-
)
|
|
7573
|
-
}
|
|
7574
|
-
}
|
|
7575
|
-
|
|
7576
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$e } = constants
|
|
7577
7647
|
const config$e = {
|
|
7578
7648
|
commandName: 'create',
|
|
7579
7649
|
description: '[Deprecated] Create a project report',
|
|
@@ -7605,57 +7675,17 @@ const cmdReportCreate = {
|
|
|
7605
7675
|
run: run$e
|
|
7606
7676
|
}
|
|
7607
7677
|
async function run$e(argv, importMeta, { parentName }) {
|
|
7608
|
-
|
|
7678
|
+
meowOrExit({
|
|
7609
7679
|
argv,
|
|
7610
7680
|
config: config$e,
|
|
7611
7681
|
importMeta,
|
|
7612
7682
|
parentName
|
|
7613
7683
|
})
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
const absoluteConfigPath = path$1.join(cwd, 'socket.yml')
|
|
7618
|
-
const dryRun = Boolean(cli.flags['dryRun'])
|
|
7619
|
-
const json = Boolean(cli.flags['json'])
|
|
7620
|
-
const markdown = Boolean(cli.flags['markdown'])
|
|
7621
|
-
const strict = Boolean(cli.flags['strict'])
|
|
7622
|
-
const includeAllIssues = Boolean(cli.flags['all'])
|
|
7623
|
-
const view = Boolean(cli.flags['view'])
|
|
7624
|
-
|
|
7625
|
-
// Note exiting earlier to skirt a hidden auth requirement
|
|
7626
|
-
if (cli.flags['dryRun']) {
|
|
7627
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$e)
|
|
7628
|
-
return
|
|
7629
|
-
}
|
|
7630
|
-
const socketConfig = await getSocketConfig(absoluteConfigPath)
|
|
7631
|
-
const result = await createReport(socketConfig, cli.input, {
|
|
7632
|
-
cwd,
|
|
7633
|
-
dryRun
|
|
7634
|
-
})
|
|
7635
|
-
const commandName = `${parentName} ${config$e.commandName}`
|
|
7636
|
-
if (result?.success) {
|
|
7637
|
-
if (view) {
|
|
7638
|
-
const reportId = result.data.id
|
|
7639
|
-
await viewReport(reportId, {
|
|
7640
|
-
all: includeAllIssues,
|
|
7641
|
-
commandName,
|
|
7642
|
-
outputKind: json ? 'json' : markdown ? 'markdown' : 'print',
|
|
7643
|
-
strict
|
|
7644
|
-
})
|
|
7645
|
-
} else if (json) {
|
|
7646
|
-
logger.logger.log(JSON.stringify(result.data, undefined, 2))
|
|
7647
|
-
} else {
|
|
7648
|
-
const format = new shadowNpmInject.ColorOrMarkdown(markdown)
|
|
7649
|
-
logger.logger.log(
|
|
7650
|
-
`New report: ${format.hyperlink(result.data.id, result.data.url, {
|
|
7651
|
-
fallbackToUrl: true
|
|
7652
|
-
})}`
|
|
7653
|
-
)
|
|
7654
|
-
}
|
|
7655
|
-
}
|
|
7684
|
+
logger.logger.fail(
|
|
7685
|
+
'This command has been sunset. Instead, please look at `socket scan create` to create scans and `socket scan report` to view a report of your scans.'
|
|
7686
|
+
)
|
|
7656
7687
|
}
|
|
7657
7688
|
|
|
7658
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$d } = constants
|
|
7659
7689
|
const config$d = {
|
|
7660
7690
|
commandName: 'view',
|
|
7661
7691
|
description: '[Deprecated] View a project report',
|
|
@@ -7676,49 +7706,15 @@ const cmdReportView = {
|
|
|
7676
7706
|
run: run$d
|
|
7677
7707
|
}
|
|
7678
7708
|
async function run$d(argv, importMeta, { parentName }) {
|
|
7679
|
-
|
|
7709
|
+
meowOrExit({
|
|
7680
7710
|
argv,
|
|
7681
7711
|
config: config$d,
|
|
7682
7712
|
importMeta,
|
|
7683
7713
|
parentName
|
|
7684
7714
|
})
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
const wasBadInput = handleBadInput(
|
|
7688
|
-
{
|
|
7689
|
-
test: reportId,
|
|
7690
|
-
message: 'Need at least one report ID',
|
|
7691
|
-
pass: 'ok',
|
|
7692
|
-
fail: 'missing'
|
|
7693
|
-
},
|
|
7694
|
-
{
|
|
7695
|
-
nook: true,
|
|
7696
|
-
test: extraInput.length === 0,
|
|
7697
|
-
message: 'Can only handle a single report ID',
|
|
7698
|
-
pass: 'ok',
|
|
7699
|
-
fail: 'received ' + (extraInput.length + 1)
|
|
7700
|
-
},
|
|
7701
|
-
{
|
|
7702
|
-
nook: true,
|
|
7703
|
-
test: !json || !markdown,
|
|
7704
|
-
message: 'The json and markdown flags cannot be both set, pick one',
|
|
7705
|
-
pass: 'ok',
|
|
7706
|
-
fail: 'omit one'
|
|
7707
|
-
}
|
|
7715
|
+
logger.logger.fail(
|
|
7716
|
+
'This command has been sunset. Instead, please look at `socket scan create` to create scans and `socket scan report` to view a report of your scans.'
|
|
7708
7717
|
)
|
|
7709
|
-
if (wasBadInput) {
|
|
7710
|
-
return
|
|
7711
|
-
}
|
|
7712
|
-
if (cli.flags['dryRun']) {
|
|
7713
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$d)
|
|
7714
|
-
return
|
|
7715
|
-
}
|
|
7716
|
-
await viewReport(reportId, {
|
|
7717
|
-
all: Boolean(cli.flags['all']),
|
|
7718
|
-
commandName: `${parentName} ${config$d.commandName}`,
|
|
7719
|
-
outputKind: json ? 'json' : markdown ? 'markdown' : 'print',
|
|
7720
|
-
strict: Boolean(cli.flags['strict'])
|
|
7721
|
-
})
|
|
7722
7718
|
}
|
|
7723
7719
|
|
|
7724
7720
|
const description$2 = '[Deprecated] Project report related commands'
|
|
@@ -7768,7 +7764,6 @@ async function fetchCreateRepo({
|
|
|
7768
7764
|
spinner.successAndStop('Received response requesting to create a repository.')
|
|
7769
7765
|
if (!result.success) {
|
|
7770
7766
|
handleUnsuccessfulApiResponse('createOrgRepo', result)
|
|
7771
|
-
return
|
|
7772
7767
|
}
|
|
7773
7768
|
return result.data
|
|
7774
7769
|
}
|
|
@@ -7841,6 +7836,10 @@ const config$c = {
|
|
|
7841
7836
|
Usage
|
|
7842
7837
|
$ ${command} <org slug>
|
|
7843
7838
|
|
|
7839
|
+
API Token Requirements
|
|
7840
|
+
- Quota: 1 unit
|
|
7841
|
+
- Permissions: repo:create
|
|
7842
|
+
|
|
7844
7843
|
Options
|
|
7845
7844
|
${getFlagListOutput(config.flags, 6)}
|
|
7846
7845
|
|
|
@@ -7916,7 +7915,6 @@ async function handleDeleteRepo(orgSlug, repoName) {
|
|
|
7916
7915
|
)
|
|
7917
7916
|
if (!result.success) {
|
|
7918
7917
|
handleUnsuccessfulApiResponse('deleteOrgRepo', result)
|
|
7919
|
-
return
|
|
7920
7918
|
}
|
|
7921
7919
|
spinner.successAndStop('Repository deleted successfully')
|
|
7922
7920
|
}
|
|
@@ -7933,6 +7931,10 @@ const config$b = {
|
|
|
7933
7931
|
Usage
|
|
7934
7932
|
$ ${command} <org slug> <repo slug>
|
|
7935
7933
|
|
|
7934
|
+
API Token Requirements
|
|
7935
|
+
- Quota: 1 unit
|
|
7936
|
+
- Permissions: repo:delete
|
|
7937
|
+
|
|
7936
7938
|
Options
|
|
7937
7939
|
${getFlagListOutput(config.flags, 6)}
|
|
7938
7940
|
|
|
@@ -8007,7 +8009,6 @@ async function fetchListRepos({ direction, orgSlug, page, per_page, sort }) {
|
|
|
8007
8009
|
spinner.successAndStop('Received response for repository list.')
|
|
8008
8010
|
if (!result.success) {
|
|
8009
8011
|
handleUnsuccessfulApiResponse('getOrgRepoList', result)
|
|
8010
|
-
return
|
|
8011
8012
|
}
|
|
8012
8013
|
return result.data
|
|
8013
8014
|
}
|
|
@@ -8109,6 +8110,10 @@ const config$a = {
|
|
|
8109
8110
|
Usage
|
|
8110
8111
|
$ ${command} <org slug>
|
|
8111
8112
|
|
|
8113
|
+
API Token Requirements
|
|
8114
|
+
- Quota: 1 unit
|
|
8115
|
+
- Permissions: repo:list
|
|
8116
|
+
|
|
8112
8117
|
Options
|
|
8113
8118
|
${getFlagListOutput(config.flags, 6)}
|
|
8114
8119
|
|
|
@@ -8201,7 +8206,6 @@ async function fetchUpdateRepo({
|
|
|
8201
8206
|
spinner.successAndStop('Received response trying to update a repository')
|
|
8202
8207
|
if (!result.success) {
|
|
8203
8208
|
handleUnsuccessfulApiResponse('updateOrgRepo', result)
|
|
8204
|
-
return
|
|
8205
8209
|
}
|
|
8206
8210
|
return result.data
|
|
8207
8211
|
}
|
|
@@ -8274,6 +8278,10 @@ const config$9 = {
|
|
|
8274
8278
|
Usage
|
|
8275
8279
|
$ ${command} <org slug>
|
|
8276
8280
|
|
|
8281
|
+
API Token Requirements
|
|
8282
|
+
- Quota: 1 unit
|
|
8283
|
+
- Permissions: repo:update
|
|
8284
|
+
|
|
8277
8285
|
Options
|
|
8278
8286
|
${getFlagListOutput(config.flags, 6)}
|
|
8279
8287
|
|
|
@@ -8350,7 +8358,6 @@ async function fetchViewRepo(orgSlug, repoName) {
|
|
|
8350
8358
|
spinner.successAndStop('Received response while fetched repository data.')
|
|
8351
8359
|
if (!result.success) {
|
|
8352
8360
|
handleUnsuccessfulApiResponse('getOrgRepo', result)
|
|
8353
|
-
return
|
|
8354
8361
|
}
|
|
8355
8362
|
return result.data
|
|
8356
8363
|
}
|
|
@@ -8445,6 +8452,10 @@ const config$8 = {
|
|
|
8445
8452
|
Usage
|
|
8446
8453
|
$ ${command} <org slug>
|
|
8447
8454
|
|
|
8455
|
+
API Token Requirements
|
|
8456
|
+
- Quota: 1 unit
|
|
8457
|
+
- Permissions: repo:list
|
|
8458
|
+
|
|
8448
8459
|
Options
|
|
8449
8460
|
${getFlagListOutput(config.flags, 6)}
|
|
8450
8461
|
|
|
@@ -8550,7 +8561,9 @@ async function fetchCreateOrgFullScan(
|
|
|
8550
8561
|
|
|
8551
8562
|
// Lazily access constants.spinner.
|
|
8552
8563
|
const { spinner } = constants
|
|
8553
|
-
spinner.start(
|
|
8564
|
+
spinner.start(
|
|
8565
|
+
`Sending request to create a scan with ${packagePaths.length} packages...`
|
|
8566
|
+
)
|
|
8554
8567
|
const result = await handleApiCall(
|
|
8555
8568
|
sockSdk.createOrgFullScan(
|
|
8556
8569
|
orgSlug,
|
|
@@ -8567,10 +8580,9 @@ async function fetchCreateOrgFullScan(
|
|
|
8567
8580
|
),
|
|
8568
8581
|
'Creating scan'
|
|
8569
8582
|
)
|
|
8570
|
-
spinner.successAndStop('
|
|
8583
|
+
spinner.successAndStop('Completed request to create a new scan.')
|
|
8571
8584
|
if (!result.success) {
|
|
8572
8585
|
handleUnsuccessfulApiResponse('CreateOrgFullScan', result)
|
|
8573
|
-
return
|
|
8574
8586
|
}
|
|
8575
8587
|
return result.data
|
|
8576
8588
|
}
|
|
@@ -8585,12 +8597,12 @@ async function fetchSupportedScanFileNames() {
|
|
|
8585
8597
|
sockSdk.getReportSupportedFiles(),
|
|
8586
8598
|
'fetching supported scan file types'
|
|
8587
8599
|
)
|
|
8588
|
-
spinner.
|
|
8600
|
+
spinner.stop()
|
|
8601
|
+
logger.logger.success(
|
|
8589
8602
|
'Received response while fetched supported scan file types.'
|
|
8590
8603
|
)
|
|
8591
8604
|
if (!result.success) {
|
|
8592
8605
|
handleUnsuccessfulApiResponse('getReportSupportedFiles', result)
|
|
8593
|
-
return
|
|
8594
8606
|
}
|
|
8595
8607
|
return result.data
|
|
8596
8608
|
}
|
|
@@ -8628,7 +8640,6 @@ async function handleCreateNewScan({
|
|
|
8628
8640
|
cwd,
|
|
8629
8641
|
targets,
|
|
8630
8642
|
supportedFileNames
|
|
8631
|
-
// socketConfig
|
|
8632
8643
|
)
|
|
8633
8644
|
handleBadInput({
|
|
8634
8645
|
nook: true,
|
|
@@ -8692,7 +8703,7 @@ async function suggestOrgSlug() {
|
|
|
8692
8703
|
}
|
|
8693
8704
|
} else {
|
|
8694
8705
|
logger.logger.fail(
|
|
8695
|
-
'Failed to lookup organization list from API, unable to suggest
|
|
8706
|
+
'Failed to lookup organization list from API, unable to suggest'
|
|
8696
8707
|
)
|
|
8697
8708
|
}
|
|
8698
8709
|
}
|
|
@@ -8947,6 +8958,10 @@ const config$7 = {
|
|
|
8947
8958
|
Usage
|
|
8948
8959
|
$ ${command} [...options] <org> <TARGET> [TARGET...]
|
|
8949
8960
|
|
|
8961
|
+
API Token Requirements
|
|
8962
|
+
- Quota: 1 unit
|
|
8963
|
+
- Permissions: full-scans:create
|
|
8964
|
+
|
|
8950
8965
|
Uploads the specified "package.json" and lock files for JavaScript, Python,
|
|
8951
8966
|
Go, Scala, Gradle, and Kotlin dependency manifests.
|
|
8952
8967
|
If any folder is specified, the ones found in there recursively are uploaded.
|
|
@@ -8988,7 +9003,7 @@ async function run$7(argv, importMeta, { parentName }) {
|
|
|
8988
9003
|
cwdOverride && cwdOverride !== 'process.cwd()'
|
|
8989
9004
|
? String(cwdOverride)
|
|
8990
9005
|
: process.cwd()
|
|
8991
|
-
let { branch: branchName, repo: repoName } = cli.flags
|
|
9006
|
+
let { branch: branchName = '', repo: repoName = '' } = cli.flags
|
|
8992
9007
|
|
|
8993
9008
|
// We're going to need an api token to suggest data because those suggestions
|
|
8994
9009
|
// must come from data we already know. Don't error on missing api token yet.
|
|
@@ -9116,7 +9131,6 @@ async function fetchDeleteOrgFullScan(orgSlug, scanId) {
|
|
|
9116
9131
|
spinner.successAndStop('Received response for deleting a scan.')
|
|
9117
9132
|
if (!result.success) {
|
|
9118
9133
|
handleUnsuccessfulApiResponse('deleteOrgFullScan', result)
|
|
9119
|
-
return
|
|
9120
9134
|
}
|
|
9121
9135
|
return result.data
|
|
9122
9136
|
}
|
|
@@ -9146,6 +9160,10 @@ const config$6 = {
|
|
|
9146
9160
|
Usage
|
|
9147
9161
|
$ ${command} <org slug> <scan ID>
|
|
9148
9162
|
|
|
9163
|
+
API Token Requirements
|
|
9164
|
+
- Quota: 1 unit
|
|
9165
|
+
- Permissions: full-scans:delete
|
|
9166
|
+
|
|
9149
9167
|
Options
|
|
9150
9168
|
${getFlagListOutput(config.flags, 6)}
|
|
9151
9169
|
|
|
@@ -9228,7 +9246,6 @@ async function fetchListScans({
|
|
|
9228
9246
|
spinner.successAndStop(`Received response for list of scans.`)
|
|
9229
9247
|
if (!result.success) {
|
|
9230
9248
|
handleUnsuccessfulApiResponse('getOrgFullScanList', result)
|
|
9231
|
-
return
|
|
9232
9249
|
}
|
|
9233
9250
|
return result.data
|
|
9234
9251
|
}
|
|
@@ -9349,6 +9366,10 @@ const config$5 = {
|
|
|
9349
9366
|
Usage
|
|
9350
9367
|
$ ${command} <org slug>
|
|
9351
9368
|
|
|
9369
|
+
API Token Requirements
|
|
9370
|
+
- Quota: 1 unit
|
|
9371
|
+
- Permissions: full-scans:list
|
|
9372
|
+
|
|
9352
9373
|
Options
|
|
9353
9374
|
${getFlagListOutput(config.flags, 6)}
|
|
9354
9375
|
|
|
@@ -9427,7 +9448,6 @@ async function fetchScanMetadata(orgSlug, scanId) {
|
|
|
9427
9448
|
spinner.successAndStop('Received response for scan meta data.')
|
|
9428
9449
|
if (!result.success) {
|
|
9429
9450
|
handleUnsuccessfulApiResponse('getOrgFullScanMetadata', result)
|
|
9430
|
-
return
|
|
9431
9451
|
}
|
|
9432
9452
|
return result.data
|
|
9433
9453
|
}
|
|
@@ -9489,6 +9509,10 @@ const config$4 = {
|
|
|
9489
9509
|
Usage
|
|
9490
9510
|
$ ${command} <org slug> <scan id>
|
|
9491
9511
|
|
|
9512
|
+
API Token Requirements
|
|
9513
|
+
- Quota: 1 unit
|
|
9514
|
+
- Permissions: full-scans:list
|
|
9515
|
+
|
|
9492
9516
|
Options
|
|
9493
9517
|
${getFlagListOutput(config.flags, 6)}
|
|
9494
9518
|
|
|
@@ -9560,14 +9584,8 @@ async function run$4(argv, importMeta, { parentName }) {
|
|
|
9560
9584
|
/**
|
|
9561
9585
|
* This fetches all the relevant pieces of data to generate a report, given a
|
|
9562
9586
|
* full scan ID.
|
|
9563
|
-
* It can optionally only fetch the security or license side of things.
|
|
9564
9587
|
*/
|
|
9565
|
-
async function fetchReportData(
|
|
9566
|
-
orgSlug,
|
|
9567
|
-
scanId,
|
|
9568
|
-
// includeLicensePolicy: boolean,
|
|
9569
|
-
includeSecurityPolicy
|
|
9570
|
-
) {
|
|
9588
|
+
async function fetchReportData(orgSlug, scanId, includeLicensePolicy) {
|
|
9571
9589
|
const apiToken = shadowNpmInject.getDefaultToken()
|
|
9572
9590
|
if (!apiToken) {
|
|
9573
9591
|
throw new shadowNpmInject.AuthError(
|
|
@@ -9576,7 +9594,6 @@ async function fetchReportData(
|
|
|
9576
9594
|
}
|
|
9577
9595
|
const sockSdk = await shadowNpmInject.setupSdk(apiToken)
|
|
9578
9596
|
let haveScan = false
|
|
9579
|
-
// let haveLicensePolicy = false
|
|
9580
9597
|
let haveSecurityPolicy = false
|
|
9581
9598
|
|
|
9582
9599
|
// Lazily access constants.spinner.
|
|
@@ -9584,48 +9601,26 @@ async function fetchReportData(
|
|
|
9584
9601
|
function updateProgress() {
|
|
9585
9602
|
const needs = [
|
|
9586
9603
|
!haveScan ? 'scan' : undefined,
|
|
9587
|
-
|
|
9588
|
-
includeSecurityPolicy && !haveSecurityPolicy
|
|
9589
|
-
? 'security policy'
|
|
9590
|
-
: undefined
|
|
9604
|
+
!haveSecurityPolicy ? 'security policy' : undefined
|
|
9591
9605
|
].filter(Boolean)
|
|
9592
|
-
if (needs.length > 2) {
|
|
9593
|
-
// .toOxford()
|
|
9594
|
-
needs[needs.length - 1] = `and ${needs[needs.length - 1]}`
|
|
9595
|
-
}
|
|
9596
9606
|
const haves = [
|
|
9597
9607
|
haveScan ? 'scan' : undefined,
|
|
9598
|
-
|
|
9599
|
-
includeSecurityPolicy && haveSecurityPolicy
|
|
9600
|
-
? 'security policy'
|
|
9601
|
-
: undefined
|
|
9608
|
+
haveSecurityPolicy ? 'security policy' : undefined
|
|
9602
9609
|
].filter(Boolean)
|
|
9603
|
-
if (haves.length > 2) {
|
|
9604
|
-
// .toOxford()
|
|
9605
|
-
haves[haves.length - 1] = `and ${haves[haves.length - 1]}`
|
|
9606
|
-
}
|
|
9607
9610
|
if (needs.length) {
|
|
9608
9611
|
spinner.start(
|
|
9609
|
-
`Fetching ${needs.join(
|
|
9612
|
+
`Fetching ${needs.join(' and ')}...${haves.length ? ` Completed fetching ${haves.join(' and ')}.` : ''}`
|
|
9610
9613
|
)
|
|
9611
9614
|
} else {
|
|
9612
|
-
spinner.successAndStop(
|
|
9613
|
-
`Completed fetching ${haves.join(haves.length > 2 ? ', ' : ' and ')}.`
|
|
9614
|
-
)
|
|
9615
|
+
spinner.successAndStop(`Completed fetching ${haves.join(' and ')}.`)
|
|
9615
9616
|
}
|
|
9616
9617
|
}
|
|
9617
9618
|
updateProgress()
|
|
9618
|
-
|
|
9619
|
-
// @ts-ignore
|
|
9620
|
-
const [
|
|
9621
|
-
scan,
|
|
9622
|
-
// licensePolicyMaybe,
|
|
9623
|
-
securityPolicyMaybe
|
|
9624
|
-
] = await Promise.all([
|
|
9619
|
+
const [scan, securityPolicyMaybe] = await Promise.all([
|
|
9625
9620
|
(async () => {
|
|
9626
9621
|
try {
|
|
9627
9622
|
const response = await queryApi(
|
|
9628
|
-
`orgs/${orgSlug}/full-scans/${encodeURIComponent(scanId)}`,
|
|
9623
|
+
`orgs/${orgSlug}/full-scans/${encodeURIComponent(scanId)}${includeLicensePolicy ? '?include_license_details=true' : ''}`,
|
|
9629
9624
|
apiToken
|
|
9630
9625
|
)
|
|
9631
9626
|
haveScan = true
|
|
@@ -9651,32 +9646,16 @@ async function fetchReportData(
|
|
|
9651
9646
|
})
|
|
9652
9647
|
return data
|
|
9653
9648
|
} catch (e) {
|
|
9654
|
-
spinner.errorAndStop(
|
|
9655
|
-
'There was an issue while fetching full scan data.'
|
|
9656
|
-
)
|
|
9649
|
+
spinner.errorAndStop('There was an issue while fetching full scan data')
|
|
9657
9650
|
throw e
|
|
9658
9651
|
}
|
|
9659
9652
|
})(),
|
|
9660
|
-
|
|
9661
|
-
|
|
9662
|
-
|
|
9663
|
-
|
|
9664
|
-
|
|
9665
|
-
|
|
9666
|
-
// r,
|
|
9667
|
-
// "looking up organization's license policy"
|
|
9668
|
-
// )
|
|
9669
|
-
// })(),
|
|
9670
|
-
includeSecurityPolicy &&
|
|
9671
|
-
(async () => {
|
|
9672
|
-
const r = await sockSdk.getOrgSecurityPolicy(orgSlug)
|
|
9673
|
-
haveSecurityPolicy = true
|
|
9674
|
-
updateProgress()
|
|
9675
|
-
return await handleApiCall(
|
|
9676
|
-
r,
|
|
9677
|
-
"looking up organization's security policy"
|
|
9678
|
-
)
|
|
9679
|
-
})()
|
|
9653
|
+
(async () => {
|
|
9654
|
+
const r = await sockSdk.getOrgSecurityPolicy(orgSlug)
|
|
9655
|
+
haveSecurityPolicy = true
|
|
9656
|
+
updateProgress()
|
|
9657
|
+
return await handleApiCall(r, "looking up organization's security policy")
|
|
9658
|
+
})()
|
|
9680
9659
|
]).finally(() => spinner.stop())
|
|
9681
9660
|
if (!Array.isArray(scan)) {
|
|
9682
9661
|
logger.logger.error('Was unable to fetch scan, bailing')
|
|
@@ -9684,55 +9663,30 @@ async function fetchReportData(
|
|
|
9684
9663
|
return {
|
|
9685
9664
|
ok: false,
|
|
9686
9665
|
scan: undefined,
|
|
9687
|
-
// licensePolicy: undefined,
|
|
9688
9666
|
securityPolicy: undefined
|
|
9689
9667
|
}
|
|
9690
9668
|
}
|
|
9691
|
-
|
|
9692
|
-
// // Note: security->license once the api ships in the sdk
|
|
9693
|
-
// let licensePolicy: undefined | SocketSdkReturnType<'getOrgSecurityPolicy'> =
|
|
9694
|
-
// undefined
|
|
9695
|
-
// if (includeLicensePolicy) {
|
|
9696
|
-
// if (licensePolicyMaybe && licensePolicyMaybe.success) {
|
|
9697
|
-
// licensePolicy = licensePolicyMaybe
|
|
9698
|
-
// } else {
|
|
9699
|
-
// logger.error('Was unable to fetch license policy, bailing')
|
|
9700
|
-
// process.exitCode = 1
|
|
9701
|
-
// return {
|
|
9702
|
-
// ok: false,
|
|
9703
|
-
// scan: undefined,
|
|
9704
|
-
// licensePolicy: undefined,
|
|
9705
|
-
// securityPolicy: undefined
|
|
9706
|
-
// }
|
|
9707
|
-
// }
|
|
9708
|
-
// }
|
|
9709
|
-
|
|
9710
9669
|
let securityPolicy = undefined
|
|
9711
|
-
if (
|
|
9712
|
-
|
|
9713
|
-
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
|
|
9718
|
-
|
|
9719
|
-
|
|
9720
|
-
// licensePolicy: undefined,
|
|
9721
|
-
securityPolicy: undefined
|
|
9722
|
-
}
|
|
9670
|
+
if (securityPolicyMaybe && securityPolicyMaybe.success) {
|
|
9671
|
+
securityPolicy = securityPolicyMaybe
|
|
9672
|
+
} else {
|
|
9673
|
+
logger.logger.error('Was unable to fetch security policy, bailing')
|
|
9674
|
+
process.exitCode = 1
|
|
9675
|
+
return {
|
|
9676
|
+
ok: false,
|
|
9677
|
+
scan: undefined,
|
|
9678
|
+
securityPolicy: undefined
|
|
9723
9679
|
}
|
|
9724
9680
|
}
|
|
9725
9681
|
return {
|
|
9726
9682
|
ok: true,
|
|
9727
9683
|
scan,
|
|
9728
|
-
// licensePolicy,
|
|
9729
9684
|
securityPolicy
|
|
9730
9685
|
}
|
|
9731
9686
|
}
|
|
9732
9687
|
|
|
9733
9688
|
function generateReport(
|
|
9734
9689
|
scan,
|
|
9735
|
-
_licensePolicy,
|
|
9736
9690
|
securityPolicy,
|
|
9737
9691
|
{ fold, orgSlug, reportLevel, scanId, short, spinner }
|
|
9738
9692
|
) {
|
|
@@ -9758,6 +9712,14 @@ function generateReport(
|
|
|
9758
9712
|
// - monitor/ignore: no action
|
|
9759
9713
|
// - defer: unknown (no action)
|
|
9760
9714
|
|
|
9715
|
+
// Note: the server will emit alerts for license policy violations but
|
|
9716
|
+
// those are only included if you set the flag when requesting the scan
|
|
9717
|
+
// data. The alerts map to a single security policy key that determines
|
|
9718
|
+
// what to do with any violation, regardless of the concrete license.
|
|
9719
|
+
// That rule is called "License Policy Violation".
|
|
9720
|
+
// The license policy part is implicitly handled here. Either they are
|
|
9721
|
+
// included and may show up, or they are not and won't show up.
|
|
9722
|
+
|
|
9761
9723
|
const violations = new Map()
|
|
9762
9724
|
let healthy = true
|
|
9763
9725
|
const securityRules = securityPolicy?.data.securityPolicyRules
|
|
@@ -10004,13 +9966,11 @@ function* walkNestedMap(map, keys = []) {
|
|
|
10004
9966
|
|
|
10005
9967
|
async function outputScanReport(
|
|
10006
9968
|
scan,
|
|
10007
|
-
// licensePolicy: undefined | SocketSdkReturnType<'getOrgSecurityPolicy'>,
|
|
10008
9969
|
securityPolicy,
|
|
10009
9970
|
{
|
|
10010
9971
|
filePath,
|
|
10011
9972
|
fold,
|
|
10012
9973
|
includeLicensePolicy,
|
|
10013
|
-
includeSecurityPolicy,
|
|
10014
9974
|
orgSlug,
|
|
10015
9975
|
outputKind,
|
|
10016
9976
|
reportLevel,
|
|
@@ -10018,25 +9978,15 @@ async function outputScanReport(
|
|
|
10018
9978
|
short
|
|
10019
9979
|
}
|
|
10020
9980
|
) {
|
|
10021
|
-
|
|
10022
|
-
|
|
10023
|
-
|
|
10024
|
-
|
|
10025
|
-
|
|
10026
|
-
|
|
10027
|
-
|
|
10028
|
-
|
|
10029
|
-
|
|
10030
|
-
{
|
|
10031
|
-
orgSlug,
|
|
10032
|
-
scanId,
|
|
10033
|
-
fold,
|
|
10034
|
-
reportLevel,
|
|
10035
|
-
short,
|
|
10036
|
-
// Lazily access constants.spinner.
|
|
10037
|
-
spinner: constants.spinner
|
|
10038
|
-
}
|
|
10039
|
-
)
|
|
9981
|
+
const scanReport = generateReport(scan, securityPolicy, {
|
|
9982
|
+
orgSlug,
|
|
9983
|
+
scanId,
|
|
9984
|
+
fold,
|
|
9985
|
+
reportLevel,
|
|
9986
|
+
short,
|
|
9987
|
+
// Lazily access constants.spinner.
|
|
9988
|
+
spinner: constants.spinner
|
|
9989
|
+
})
|
|
10040
9990
|
if (!scanReport.healthy) {
|
|
10041
9991
|
process.exitCode = 1
|
|
10042
9992
|
}
|
|
@@ -10044,7 +9994,9 @@ async function outputScanReport(
|
|
|
10044
9994
|
outputKind === 'json' ||
|
|
10045
9995
|
(outputKind === 'text' && filePath && filePath.endsWith('.json'))
|
|
10046
9996
|
) {
|
|
10047
|
-
const json = short
|
|
9997
|
+
const json = short
|
|
9998
|
+
? JSON.stringify(scanReport)
|
|
9999
|
+
: toJsonReport(scanReport, includeLicensePolicy)
|
|
10048
10000
|
if (filePath !== '-') {
|
|
10049
10001
|
logger.logger.log('Writing json report to', filePath)
|
|
10050
10002
|
return await fs.writeFile(filePath, json)
|
|
@@ -10055,7 +10007,7 @@ async function outputScanReport(
|
|
|
10055
10007
|
if (outputKind === 'markdown' || filePath.endsWith('.md')) {
|
|
10056
10008
|
const md = short
|
|
10057
10009
|
? `healthy = ${scanReport.healthy}`
|
|
10058
|
-
: toMarkdownReport(scanReport)
|
|
10010
|
+
: toMarkdownReport(scanReport, includeLicensePolicy)
|
|
10059
10011
|
if (filePath !== '-') {
|
|
10060
10012
|
logger.logger.log('Writing markdown report to', filePath)
|
|
10061
10013
|
return await fs.writeFile(filePath, md)
|
|
@@ -10071,10 +10023,11 @@ async function outputScanReport(
|
|
|
10071
10023
|
})
|
|
10072
10024
|
}
|
|
10073
10025
|
}
|
|
10074
|
-
function toJsonReport(report) {
|
|
10026
|
+
function toJsonReport(report, includeLicensePolicy) {
|
|
10075
10027
|
const obj = mapToObject(report.alerts)
|
|
10076
10028
|
const json = JSON.stringify(
|
|
10077
10029
|
{
|
|
10030
|
+
includeLicensePolicy,
|
|
10078
10031
|
...report,
|
|
10079
10032
|
alerts: obj
|
|
10080
10033
|
},
|
|
@@ -10083,7 +10036,7 @@ function toJsonReport(report) {
|
|
|
10083
10036
|
)
|
|
10084
10037
|
return json
|
|
10085
10038
|
}
|
|
10086
|
-
function toMarkdownReport(report) {
|
|
10039
|
+
function toMarkdownReport(report, includeLicensePolicy) {
|
|
10087
10040
|
const flatData = Array.from(walkNestedMap(report.alerts)).map(
|
|
10088
10041
|
({ keys, value }) => {
|
|
10089
10042
|
const { manifest, policy, type, url } = value
|
|
@@ -10102,11 +10055,11 @@ function toMarkdownReport(report) {
|
|
|
10102
10055
|
# Scan Policy Report
|
|
10103
10056
|
|
|
10104
10057
|
This report tells you whether the results of a Socket scan results violate the
|
|
10105
|
-
security or license policy set by your organization.
|
|
10058
|
+
security${includeLicensePolicy ? ' or license' : ''} policy set by your organization.
|
|
10106
10059
|
|
|
10107
10060
|
## Health status
|
|
10108
10061
|
|
|
10109
|
-
${report.healthy ?
|
|
10062
|
+
${report.healthy ? `The scan *PASSES* all requirements set by your security${includeLicensePolicy ? ' and license' : ''} policy.` : 'The scan *VIOLATES* one or more policies set to the "error" level.'}
|
|
10110
10063
|
|
|
10111
10064
|
## Settings
|
|
10112
10065
|
|
|
@@ -10116,6 +10069,7 @@ Configuration used to generate this report:
|
|
|
10116
10069
|
- Scan ID: ${report.scanId}
|
|
10117
10070
|
- Alert folding: ${report.options.fold === 'none' ? 'none' : `up to ${report.options.fold}`}
|
|
10118
10071
|
- Minimal policy level for alert to be included in report: ${report.options.reportLevel === 'defer' ? 'everything' : report.options.reportLevel}
|
|
10072
|
+
- Include license alerts: ${includeLicensePolicy ? 'yes' : 'no'}
|
|
10119
10073
|
|
|
10120
10074
|
## Alerts
|
|
10121
10075
|
|
|
@@ -10130,27 +10084,16 @@ async function handleScanReport({
|
|
|
10130
10084
|
filePath,
|
|
10131
10085
|
fold,
|
|
10132
10086
|
includeLicensePolicy,
|
|
10133
|
-
includeSecurityPolicy,
|
|
10134
10087
|
orgSlug,
|
|
10135
10088
|
outputKind,
|
|
10136
10089
|
reportLevel,
|
|
10137
10090
|
scanId,
|
|
10138
10091
|
short
|
|
10139
10092
|
}) {
|
|
10140
|
-
|
|
10141
|
-
process.exitCode = 1
|
|
10142
|
-
return // caller should assert
|
|
10143
|
-
}
|
|
10144
|
-
const {
|
|
10145
|
-
// licensePolicy,
|
|
10146
|
-
ok,
|
|
10147
|
-
scan,
|
|
10148
|
-
securityPolicy
|
|
10149
|
-
} = await fetchReportData(
|
|
10093
|
+
const { ok, scan, securityPolicy } = await fetchReportData(
|
|
10150
10094
|
orgSlug,
|
|
10151
10095
|
scanId,
|
|
10152
|
-
|
|
10153
|
-
includeSecurityPolicy
|
|
10096
|
+
includeLicensePolicy
|
|
10154
10097
|
)
|
|
10155
10098
|
if (!ok) {
|
|
10156
10099
|
return
|
|
@@ -10160,7 +10103,6 @@ async function handleScanReport({
|
|
|
10160
10103
|
fold,
|
|
10161
10104
|
scanId: scanId,
|
|
10162
10105
|
includeLicensePolicy,
|
|
10163
|
-
includeSecurityPolicy,
|
|
10164
10106
|
orgSlug,
|
|
10165
10107
|
outputKind,
|
|
10166
10108
|
reportLevel,
|
|
@@ -10173,8 +10115,7 @@ const config$3 = {
|
|
|
10173
10115
|
commandName: 'report',
|
|
10174
10116
|
description:
|
|
10175
10117
|
'Check whether a scan result passes the organizational policies (security, license)',
|
|
10176
|
-
hidden:
|
|
10177
|
-
// [beta]
|
|
10118
|
+
hidden: false,
|
|
10178
10119
|
flags: {
|
|
10179
10120
|
...commonFlags,
|
|
10180
10121
|
...outputFlags,
|
|
@@ -10193,31 +10134,23 @@ const config$3 = {
|
|
|
10193
10134
|
default: false,
|
|
10194
10135
|
description: 'Report only the healthy status'
|
|
10195
10136
|
},
|
|
10196
|
-
|
|
10197
|
-
// type: 'boolean',
|
|
10198
|
-
// default: true,
|
|
10199
|
-
// description: 'Report the license policy status. Default: true'
|
|
10200
|
-
// },
|
|
10201
|
-
security: {
|
|
10137
|
+
license: {
|
|
10202
10138
|
type: 'boolean',
|
|
10203
|
-
default:
|
|
10204
|
-
description: '
|
|
10139
|
+
default: false,
|
|
10140
|
+
description: 'Also report the license policy status. Default: false'
|
|
10205
10141
|
}
|
|
10206
10142
|
},
|
|
10207
10143
|
help: (command, config) => `
|
|
10208
10144
|
Usage
|
|
10209
10145
|
$ ${command} <org slug> <scan ID> [path to output file]
|
|
10210
10146
|
|
|
10147
|
+
API Token Requirements
|
|
10148
|
+
- Quota: 2 units
|
|
10149
|
+
- Permissions: full-scans:list security-policy:read
|
|
10150
|
+
|
|
10211
10151
|
Options
|
|
10212
10152
|
${getFlagListOutput(config.flags, 6)}
|
|
10213
10153
|
|
|
10214
|
-
This consumes 1 quota unit plus 1 for each of the requested policy types.
|
|
10215
|
-
|
|
10216
|
-
Note: By default it reports both so by default it consumes 3 quota units.
|
|
10217
|
-
|
|
10218
|
-
Your API token will need the \`full-scans:list\` scope regardless. Additionally
|
|
10219
|
-
it needs \`security-policy:read\` to report on the security policy.
|
|
10220
|
-
|
|
10221
10154
|
By default the result is a nested object that looks like this:
|
|
10222
10155
|
\`{[ecosystem]: {[pkgName]: {[version]: {[file]: {[type:loc]: policy}}}}\`
|
|
10223
10156
|
You can fold this up to given level: 'pkg', 'version', 'file', and 'none'.
|
|
@@ -10229,6 +10162,7 @@ const config$3 = {
|
|
|
10229
10162
|
|
|
10230
10163
|
Examples
|
|
10231
10164
|
$ ${command} FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 --json --fold=version
|
|
10165
|
+
$ ${command} FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 --license --markdown --short
|
|
10232
10166
|
`
|
|
10233
10167
|
}
|
|
10234
10168
|
const cmdScanReport = {
|
|
@@ -10246,10 +10180,9 @@ async function run$3(argv, importMeta, { parentName }) {
|
|
|
10246
10180
|
const {
|
|
10247
10181
|
fold = 'none',
|
|
10248
10182
|
json,
|
|
10249
|
-
|
|
10183
|
+
license,
|
|
10250
10184
|
markdown,
|
|
10251
|
-
reportLevel = 'warn'
|
|
10252
|
-
security
|
|
10185
|
+
reportLevel = 'warn'
|
|
10253
10186
|
} = cli.flags
|
|
10254
10187
|
const defaultOrgSlug = shadowNpmInject.getConfigValue('defaultOrg')
|
|
10255
10188
|
const orgSlug = defaultOrgSlug || cli.input[0] || ''
|
|
@@ -10296,9 +10229,7 @@ async function run$3(argv, importMeta, { parentName }) {
|
|
|
10296
10229
|
await handleScanReport({
|
|
10297
10230
|
orgSlug,
|
|
10298
10231
|
scanId: scanId,
|
|
10299
|
-
includeLicensePolicy:
|
|
10300
|
-
// !!license,
|
|
10301
|
-
includeSecurityPolicy: typeof security === 'boolean' ? security : true,
|
|
10232
|
+
includeLicensePolicy: !!license,
|
|
10302
10233
|
outputKind: json ? 'json' : markdown ? 'markdown' : 'text',
|
|
10303
10234
|
filePath: file,
|
|
10304
10235
|
fold: fold,
|
|
@@ -10307,6 +10238,46 @@ async function run$3(argv, importMeta, { parentName }) {
|
|
|
10307
10238
|
})
|
|
10308
10239
|
}
|
|
10309
10240
|
|
|
10241
|
+
async function fetchScan(orgSlug, scanId) {
|
|
10242
|
+
const apiToken = shadowNpmInject.getDefaultToken()
|
|
10243
|
+
if (!apiToken) {
|
|
10244
|
+
throw new shadowNpmInject.AuthError(
|
|
10245
|
+
'User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.'
|
|
10246
|
+
)
|
|
10247
|
+
}
|
|
10248
|
+
|
|
10249
|
+
// Lazily access constants.spinner.
|
|
10250
|
+
const { spinner } = constants
|
|
10251
|
+
spinner.start('Fetching scan data...')
|
|
10252
|
+
const response = await queryApi(
|
|
10253
|
+
`orgs/${orgSlug}/full-scans/${encodeURIComponent(scanId)}`,
|
|
10254
|
+
apiToken
|
|
10255
|
+
)
|
|
10256
|
+
spinner.successAndStop('Received response while fetching scan data.')
|
|
10257
|
+
if (!response.ok) {
|
|
10258
|
+
const err = await handleApiError(response.status)
|
|
10259
|
+
logger.logger.fail(
|
|
10260
|
+
failMsgWithBadge(response.statusText, `Fetch error: ${err}`)
|
|
10261
|
+
)
|
|
10262
|
+
return
|
|
10263
|
+
}
|
|
10264
|
+
|
|
10265
|
+
// This is nd-json; each line is a json object
|
|
10266
|
+
const jsons = await response.text()
|
|
10267
|
+
const lines = jsons.split('\n').filter(Boolean)
|
|
10268
|
+
const data = lines.map(line => {
|
|
10269
|
+
try {
|
|
10270
|
+
return JSON.parse(line)
|
|
10271
|
+
} catch {
|
|
10272
|
+
console.error(
|
|
10273
|
+
'At least one line item was returned that could not be parsed as JSON...'
|
|
10274
|
+
)
|
|
10275
|
+
return {}
|
|
10276
|
+
}
|
|
10277
|
+
})
|
|
10278
|
+
return data
|
|
10279
|
+
}
|
|
10280
|
+
|
|
10310
10281
|
async function outputScanView(artifacts, orgSlug, scanId, filePath) {
|
|
10311
10282
|
const display = artifacts.map(art => {
|
|
10312
10283
|
const author = Array.isArray(art.author)
|
|
@@ -10367,7 +10338,6 @@ async function streamScan(orgSlug, scanId, file) {
|
|
|
10367
10338
|
spinner.successAndStop(`Full scan details written to ${file}`)
|
|
10368
10339
|
if (!data?.success) {
|
|
10369
10340
|
handleUnsuccessfulApiResponse('getOrgFullScan', data)
|
|
10370
|
-
return
|
|
10371
10341
|
}
|
|
10372
10342
|
return data
|
|
10373
10343
|
}
|
|
@@ -10385,6 +10355,10 @@ const config$2 = {
|
|
|
10385
10355
|
Usage
|
|
10386
10356
|
$ ${command} <org slug> <scan ID> [path to output file]
|
|
10387
10357
|
|
|
10358
|
+
API Token Requirements
|
|
10359
|
+
- Quota: 1 unit
|
|
10360
|
+
- Permissions: full-scans:list
|
|
10361
|
+
|
|
10388
10362
|
When no output path is given the contents is sent to stdout.
|
|
10389
10363
|
|
|
10390
10364
|
Options
|
|
@@ -10734,6 +10708,11 @@ const config$1 = {
|
|
|
10734
10708
|
Usage
|
|
10735
10709
|
$ ${command}
|
|
10736
10710
|
|
|
10711
|
+
API Token Requirements
|
|
10712
|
+
- Quota: 1 unit
|
|
10713
|
+
- Permissions: threat-feed:list
|
|
10714
|
+
- Special access
|
|
10715
|
+
|
|
10737
10716
|
This feature requires a Threat Feed license. Please contact
|
|
10738
10717
|
sales@socket.dev if you are interested in purchasing this access.
|
|
10739
10718
|
|
|
@@ -10852,7 +10831,7 @@ function checkSocketWrapperSetup(file) {
|
|
|
10852
10831
|
)
|
|
10853
10832
|
if (linesWithSocketAlias.length) {
|
|
10854
10833
|
logger.logger.log(
|
|
10855
|
-
`The Socket npm/npx wrapper is set up in your bash profile (${file})
|
|
10834
|
+
`The Socket npm/npx wrapper is set up in your bash profile (${file})`
|
|
10856
10835
|
)
|
|
10857
10836
|
return true
|
|
10858
10837
|
}
|
|
@@ -11034,7 +11013,7 @@ void (async () => {
|
|
|
11034
11013
|
await vendor.updater({
|
|
11035
11014
|
name: SOCKET_CLI_BIN_NAME,
|
|
11036
11015
|
// The '@rollup/plugin-replace' will replace "process.env['INLINED_SOCKET_CLI_VERSION']".
|
|
11037
|
-
version: '0.14.
|
|
11016
|
+
version: '0.14.69',
|
|
11038
11017
|
ttl: 86_400_000 /* 24 hours in milliseconds */
|
|
11039
11018
|
})
|
|
11040
11019
|
try {
|
|
@@ -11105,5 +11084,5 @@ void (async () => {
|
|
|
11105
11084
|
await shadowNpmInject.captureException(e)
|
|
11106
11085
|
}
|
|
11107
11086
|
})()
|
|
11108
|
-
//# debugId=
|
|
11087
|
+
//# debugId=e3cd97d3-ecbe-4456-ae64-12b987d63408
|
|
11109
11088
|
//# sourceMappingURL=cli.js.map
|