@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/module-sync/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')
|
|
@@ -28,22 +29,22 @@ const meow = _socketInterop(require('meow'))
|
|
|
28
29
|
const objects = require('@socketsecurity/registry/lib/objects')
|
|
29
30
|
const path = require('@socketsecurity/registry/lib/path')
|
|
30
31
|
const regexps = require('@socketsecurity/registry/lib/regexps')
|
|
31
|
-
const prompts = require('@socketsecurity/registry/lib/prompts')
|
|
32
32
|
const yargsParse = _socketInterop(require('yargs-parser'))
|
|
33
33
|
const words = require('@socketsecurity/registry/lib/words')
|
|
34
34
|
const fs$1 = require('node:fs')
|
|
35
35
|
const shadowBin = require('./shadow-bin.js')
|
|
36
|
+
const prompts = require('@socketsecurity/registry/lib/prompts')
|
|
36
37
|
const chalkTable = _socketInterop(require('chalk-table'))
|
|
37
38
|
const util = require('node:util')
|
|
38
39
|
const registry = require('@socketsecurity/registry')
|
|
39
40
|
const npm = require('@socketsecurity/registry/lib/npm')
|
|
40
41
|
const packages = require('@socketsecurity/registry/lib/packages')
|
|
42
|
+
const rest = _socketInterop(require('@octokit/rest'))
|
|
41
43
|
const lockfile_fs = _socketInterop(require('@pnpm/lockfile.fs'))
|
|
44
|
+
const spawn = require('@socketsecurity/registry/lib/spawn')
|
|
42
45
|
const lockfile_detectDepTypes = _socketInterop(
|
|
43
46
|
require('@pnpm/lockfile.detect-dep-types')
|
|
44
47
|
)
|
|
45
|
-
const debug = require('@socketsecurity/registry/lib/debug')
|
|
46
|
-
const spawn = require('@socketsecurity/registry/lib/spawn')
|
|
47
48
|
const shadowNpmPaths = require('./shadow-npm-paths.js')
|
|
48
49
|
const browserslist = _socketInterop(require('browserslist'))
|
|
49
50
|
const semver = _socketInterop(require('semver'))
|
|
@@ -57,8 +58,6 @@ const npa = _socketInterop(require('npm-package-arg'))
|
|
|
57
58
|
const tinyglobby = _socketInterop(require('tinyglobby'))
|
|
58
59
|
const promises = require('@socketsecurity/registry/lib/promises')
|
|
59
60
|
const yaml = _socketInterop(require('yaml'))
|
|
60
|
-
const betterAjvErrors = _socketInterop(require('@apideck/better-ajv-errors'))
|
|
61
|
-
const config$K = require('@socketsecurity/config')
|
|
62
61
|
const open = _socketInterop(require('open'))
|
|
63
62
|
|
|
64
63
|
function failMsgWithBadge(badge, msg) {
|
|
@@ -74,7 +73,7 @@ function handleUnsuccessfulApiResponse(_name, sockSdkError) {
|
|
|
74
73
|
spinner.stop()
|
|
75
74
|
throw new shadowNpmInject.AuthError(message)
|
|
76
75
|
}
|
|
77
|
-
logger.logger.fail(failMsgWithBadge('API returned an error
|
|
76
|
+
logger.logger.fail(failMsgWithBadge('Socket API returned an error', message))
|
|
78
77
|
|
|
79
78
|
process$1.exit(1)
|
|
80
79
|
}
|
|
@@ -82,23 +81,25 @@ async function handleApiCall(value, description) {
|
|
|
82
81
|
let result
|
|
83
82
|
try {
|
|
84
83
|
result = await value
|
|
85
|
-
} catch (
|
|
84
|
+
} catch (e) {
|
|
85
|
+
debug.debugLog(`handleApiCall[${description}] error:\n`, e)
|
|
86
86
|
throw new Error(`Failed ${description}`, {
|
|
87
|
-
cause
|
|
87
|
+
cause: e
|
|
88
88
|
})
|
|
89
89
|
}
|
|
90
90
|
return result
|
|
91
91
|
}
|
|
92
92
|
async function handleApiError(code) {
|
|
93
93
|
if (code === 400) {
|
|
94
|
-
return 'One of the options passed might be incorrect
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
return 'One of the options passed might be incorrect'
|
|
95
|
+
}
|
|
96
|
+
if (code === 403) {
|
|
97
|
+
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'
|
|
98
|
+
}
|
|
99
|
+
if (code === 404) {
|
|
98
100
|
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.'
|
|
99
|
-
} else {
|
|
100
|
-
return `Server responded with status code ${code}`
|
|
101
101
|
}
|
|
102
|
+
return `Server responded with status code ${code}`
|
|
102
103
|
}
|
|
103
104
|
function getLastFiveOfApiToken(token) {
|
|
104
105
|
// Get the last 5 characters of the API token before the trailing "_api".
|
|
@@ -143,14 +144,13 @@ async function fetchOrgAnalyticsData(time, spinner) {
|
|
|
143
144
|
)
|
|
144
145
|
if (result.success === false) {
|
|
145
146
|
handleUnsuccessfulApiResponse('getOrgAnalytics', result)
|
|
146
|
-
return undefined
|
|
147
147
|
}
|
|
148
148
|
spinner.stop()
|
|
149
149
|
if (!result.data.length) {
|
|
150
150
|
logger.logger.log(
|
|
151
151
|
'No analytics data is available for this organization yet.'
|
|
152
152
|
)
|
|
153
|
-
return
|
|
153
|
+
return
|
|
154
154
|
}
|
|
155
155
|
return result.data
|
|
156
156
|
}
|
|
@@ -163,14 +163,13 @@ async function fetchRepoAnalyticsData(repo, time, spinner) {
|
|
|
163
163
|
)
|
|
164
164
|
if (result.success === false) {
|
|
165
165
|
handleUnsuccessfulApiResponse('getRepoAnalytics', result)
|
|
166
|
-
return undefined
|
|
167
166
|
}
|
|
168
167
|
spinner.stop()
|
|
169
168
|
if (!result.data.length) {
|
|
170
169
|
logger.logger.log(
|
|
171
170
|
'No analytics data is available for this organization yet.'
|
|
172
171
|
)
|
|
173
|
-
return
|
|
172
|
+
return
|
|
174
173
|
}
|
|
175
174
|
return result.data
|
|
176
175
|
}
|
|
@@ -732,7 +731,7 @@ function getHelpListOutput(
|
|
|
732
731
|
return result.trim() || '(none)'
|
|
733
732
|
}
|
|
734
733
|
|
|
735
|
-
const { DRY_RUN_LABEL:
|
|
734
|
+
const { DRY_RUN_LABEL, REDACTED: REDACTED$1 } = constants
|
|
736
735
|
async function meowWithSubcommands(subcommands, options) {
|
|
737
736
|
const {
|
|
738
737
|
aliases = {},
|
|
@@ -805,15 +804,43 @@ async function meowWithSubcommands(subcommands, options) {
|
|
|
805
804
|
// Hard override the config if instructed to do so.
|
|
806
805
|
// The env var overrides the --flag, which overrides the persisted config
|
|
807
806
|
// Also, when either of these are used, config updates won't persist.
|
|
807
|
+
let configOverrideResult
|
|
808
808
|
if (process$1.env['SOCKET_CLI_CONFIG']) {
|
|
809
|
-
shadowNpmInject.overrideCachedConfig(
|
|
810
|
-
|
|
809
|
+
configOverrideResult = shadowNpmInject.overrideCachedConfig(
|
|
810
|
+
process$1.env['SOCKET_CLI_CONFIG']
|
|
811
811
|
)
|
|
812
812
|
} else if (cli.flags['config']) {
|
|
813
|
-
shadowNpmInject.overrideCachedConfig(
|
|
814
|
-
|
|
813
|
+
configOverrideResult = shadowNpmInject.overrideCachedConfig(
|
|
814
|
+
String(cli.flags['config'] || '')
|
|
815
815
|
)
|
|
816
816
|
}
|
|
817
|
+
if (process$1.env['SOCKET_CLI_NO_API_TOKEN']) {
|
|
818
|
+
// This overrides the config override and even the explicit token env var.
|
|
819
|
+
// The config will be marked as readOnly to prevent persisting it.
|
|
820
|
+
shadowNpmInject.overrideConfigApiToken(undefined)
|
|
821
|
+
} else {
|
|
822
|
+
// Note: these are SOCKET_SECURITY prefixed because they're not specific to
|
|
823
|
+
// the CLI. For the sake of consistency we'll also support the env
|
|
824
|
+
// keys that do have the SOCKET_CLI prefix, it's an easy mistake.
|
|
825
|
+
// In case multiple are supplied, the tokens supersede the keys and the
|
|
826
|
+
// security prefix supersedes the cli prefix. "Adventure mode" ;)
|
|
827
|
+
const tokenOverride =
|
|
828
|
+
process$1.env['SOCKET_CLI_API_KEY'] ||
|
|
829
|
+
process$1.env['SOCKET_SECURITY_API_KEY'] ||
|
|
830
|
+
process$1.env['SOCKET_CLI_API_TOKEN'] ||
|
|
831
|
+
process$1.env['SOCKET_SECURITY_API_TOKEN']
|
|
832
|
+
if (tokenOverride) {
|
|
833
|
+
// This will set the token (even if there was a config override) and
|
|
834
|
+
// set it to readOnly, making sure the temp token won't be persisted.
|
|
835
|
+
shadowNpmInject.overrideConfigApiToken(tokenOverride)
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
if (configOverrideResult?.ok === false) {
|
|
839
|
+
emitBanner(name)
|
|
840
|
+
logger.logger.fail(configOverrideResult.message)
|
|
841
|
+
process$1.exitCode = 2
|
|
842
|
+
return
|
|
843
|
+
}
|
|
817
844
|
|
|
818
845
|
// If we got at least some args, then lets find out if we can find a command.
|
|
819
846
|
if (commandOrAliasName) {
|
|
@@ -838,7 +865,7 @@ async function meowWithSubcommands(subcommands, options) {
|
|
|
838
865
|
}
|
|
839
866
|
if (!cli.flags['help'] && cli.flags['dryRun']) {
|
|
840
867
|
process$1.exitCode = 0
|
|
841
|
-
logger.logger.log(`${DRY_RUN_LABEL
|
|
868
|
+
logger.logger.log(`${DRY_RUN_LABEL}: No-op, call a sub-command; ok`)
|
|
842
869
|
} else {
|
|
843
870
|
cli.showHelp()
|
|
844
871
|
}
|
|
@@ -887,9 +914,9 @@ function emitBanner(name) {
|
|
|
887
914
|
logger.logger.error(getAsciiHeader(name))
|
|
888
915
|
}
|
|
889
916
|
function getAsciiHeader(command) {
|
|
890
|
-
const cliVersion = '0.14.
|
|
917
|
+
const cliVersion = '0.14.69:2aebac3:e4bf0eac:pub' // The '@rollup/plugin-replace' will replace "process.env['INLINED_SOCKET_CLI_VERSION_HASH']".
|
|
891
918
|
const nodeVersion = process$1.version
|
|
892
|
-
const apiToken = shadowNpmInject.
|
|
919
|
+
const apiToken = shadowNpmInject.getDefaultToken()
|
|
893
920
|
const shownToken = apiToken ? getLastFiveOfApiToken(apiToken) : 'no'
|
|
894
921
|
const relCwd = path.normalizePath(
|
|
895
922
|
process$1
|
|
@@ -910,7 +937,7 @@ function getAsciiHeader(command) {
|
|
|
910
937
|
return ` ${body}\n`
|
|
911
938
|
}
|
|
912
939
|
|
|
913
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
940
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$G } = constants
|
|
914
941
|
const config$J = {
|
|
915
942
|
commandName: 'analytics',
|
|
916
943
|
description: `Look up analytics data`,
|
|
@@ -923,7 +950,7 @@ const config$J = {
|
|
|
923
950
|
shortFlag: 'f',
|
|
924
951
|
default: '-',
|
|
925
952
|
description:
|
|
926
|
-
'
|
|
953
|
+
'Filepath to save output. Only valid with --json/--markdown. Defaults to stdout.'
|
|
927
954
|
},
|
|
928
955
|
repo: {
|
|
929
956
|
type: 'string',
|
|
@@ -949,6 +976,10 @@ const config$J = {
|
|
|
949
976
|
Usage
|
|
950
977
|
$ ${command} --scope=<scope> --time=<time filter>
|
|
951
978
|
|
|
979
|
+
API Token Requirements
|
|
980
|
+
- Quota: 1 unit
|
|
981
|
+
- Permissions: report:write
|
|
982
|
+
|
|
952
983
|
Default parameters are set to show the organization-level analytics over the
|
|
953
984
|
last 7 days.
|
|
954
985
|
|
|
@@ -1024,7 +1055,7 @@ async function run$J(argv, importMeta, { parentName }) {
|
|
|
1024
1055
|
return
|
|
1025
1056
|
}
|
|
1026
1057
|
if (cli.flags['dryRun']) {
|
|
1027
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
1058
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$G)
|
|
1028
1059
|
return
|
|
1029
1060
|
}
|
|
1030
1061
|
assert(assertScope(scope))
|
|
@@ -1065,31 +1096,43 @@ async function fetchAuditLog({ logType, orgSlug, outputKind, page, perPage }) {
|
|
|
1065
1096
|
)
|
|
1066
1097
|
if (!result.success) {
|
|
1067
1098
|
handleUnsuccessfulApiResponse('getAuditLogEvents', result)
|
|
1068
|
-
return
|
|
1069
1099
|
}
|
|
1070
1100
|
spinner.stop()
|
|
1071
1101
|
return result.data
|
|
1072
1102
|
}
|
|
1073
1103
|
|
|
1104
|
+
const { REDACTED } = constants
|
|
1074
1105
|
async function outputAuditLog(
|
|
1075
1106
|
auditLogs,
|
|
1076
1107
|
{ logType, orgSlug, outputKind, page, perPage }
|
|
1077
1108
|
) {
|
|
1078
1109
|
if (outputKind === 'json') {
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1110
|
+
logger.logger.log(
|
|
1111
|
+
await outputAsJson(auditLogs.results, {
|
|
1112
|
+
logType,
|
|
1113
|
+
orgSlug,
|
|
1114
|
+
page,
|
|
1115
|
+
perPage
|
|
1116
|
+
})
|
|
1117
|
+
)
|
|
1082
1118
|
} else {
|
|
1083
|
-
|
|
1119
|
+
logger.logger.log(
|
|
1120
|
+
await outputAsMarkdown(auditLogs.results, {
|
|
1121
|
+
logType,
|
|
1122
|
+
orgSlug,
|
|
1123
|
+
page,
|
|
1124
|
+
perPage
|
|
1125
|
+
})
|
|
1126
|
+
)
|
|
1084
1127
|
}
|
|
1085
1128
|
}
|
|
1086
|
-
async function outputAsJson(auditLogs,
|
|
1129
|
+
async function outputAsJson(auditLogs, { logType, orgSlug, page, perPage }) {
|
|
1087
1130
|
let json
|
|
1088
1131
|
try {
|
|
1089
1132
|
json = JSON.stringify(
|
|
1090
1133
|
{
|
|
1091
1134
|
desc: 'Audit logs for given query',
|
|
1092
|
-
generated: new Date().toISOString(),
|
|
1135
|
+
generated: false ? REDACTED : new Date().toISOString(),
|
|
1093
1136
|
org: orgSlug,
|
|
1094
1137
|
logType,
|
|
1095
1138
|
page,
|
|
@@ -1118,15 +1161,21 @@ async function outputAsJson(auditLogs, orgSlug, logType, page, perPage) {
|
|
|
1118
1161
|
2
|
|
1119
1162
|
)
|
|
1120
1163
|
} catch (e) {
|
|
1121
|
-
process.exitCode = 1
|
|
1164
|
+
process$1.exitCode = 1
|
|
1122
1165
|
logger.logger.fail(
|
|
1123
1166
|
'There was a problem converting the logs to JSON, please try without the `--json` flag'
|
|
1124
1167
|
)
|
|
1125
|
-
|
|
1168
|
+
if (debug.isDebug()) {
|
|
1169
|
+
debug.debugLog('Error:\n', e)
|
|
1170
|
+
}
|
|
1171
|
+
return '{}'
|
|
1126
1172
|
}
|
|
1127
|
-
|
|
1173
|
+
return json
|
|
1128
1174
|
}
|
|
1129
|
-
async function outputAsMarkdown(
|
|
1175
|
+
async function outputAsMarkdown(
|
|
1176
|
+
auditLogs,
|
|
1177
|
+
{ logType, orgSlug, page, perPage }
|
|
1178
|
+
) {
|
|
1130
1179
|
try {
|
|
1131
1180
|
const table = mdTable(auditLogs, [
|
|
1132
1181
|
'event_id',
|
|
@@ -1136,7 +1185,7 @@ async function outputAsMarkdown(auditLogs, orgSlug, logType, page, perPage) {
|
|
|
1136
1185
|
'ip_address',
|
|
1137
1186
|
'user_agent'
|
|
1138
1187
|
])
|
|
1139
|
-
|
|
1188
|
+
return `
|
|
1140
1189
|
# Socket Audit Logs
|
|
1141
1190
|
|
|
1142
1191
|
These are the Socket.dev audit logs as per requested query.
|
|
@@ -1144,50 +1193,21 @@ These are the Socket.dev audit logs as per requested query.
|
|
|
1144
1193
|
- type filter: ${logType || '(none)'}
|
|
1145
1194
|
- page: ${page}
|
|
1146
1195
|
- per page: ${perPage}
|
|
1147
|
-
- generated: ${new Date().toISOString()}
|
|
1196
|
+
- generated: ${false ? REDACTED : new Date().toISOString()}
|
|
1148
1197
|
|
|
1149
1198
|
${table}
|
|
1150
|
-
`
|
|
1199
|
+
`
|
|
1151
1200
|
} catch (e) {
|
|
1152
|
-
process.exitCode = 1
|
|
1201
|
+
process$1.exitCode = 1
|
|
1153
1202
|
logger.logger.fail(
|
|
1154
|
-
'There was a problem converting the logs to
|
|
1203
|
+
'There was a problem converting the logs to Markdown, please try the `--json` flag'
|
|
1155
1204
|
)
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
}
|
|
1159
|
-
}
|
|
1160
|
-
async function outputAsPrint(auditLogs, orgSlug, logType) {
|
|
1161
|
-
const data = []
|
|
1162
|
-
const logDetails = {}
|
|
1163
|
-
for (const d of auditLogs) {
|
|
1164
|
-
const { created_at } = d
|
|
1165
|
-
if (created_at) {
|
|
1166
|
-
const name = `${new Date(created_at).toLocaleDateString('en-us', {
|
|
1167
|
-
year: 'numeric',
|
|
1168
|
-
month: 'numeric',
|
|
1169
|
-
day: 'numeric'
|
|
1170
|
-
})} - ${d.user_email} - ${d.type} - ${d.ip_address} - ${d.user_agent}`
|
|
1171
|
-
data.push(
|
|
1172
|
-
{
|
|
1173
|
-
name
|
|
1174
|
-
},
|
|
1175
|
-
new prompts.Separator()
|
|
1176
|
-
)
|
|
1177
|
-
logDetails[name] = JSON.stringify(d.payload)
|
|
1205
|
+
if (debug.isDebug()) {
|
|
1206
|
+
debug.debugLog('Error:\n', e)
|
|
1178
1207
|
}
|
|
1208
|
+
// logger.error(e)
|
|
1209
|
+
return ''
|
|
1179
1210
|
}
|
|
1180
|
-
logger.logger.log(
|
|
1181
|
-
logDetails[
|
|
1182
|
-
await prompts.select({
|
|
1183
|
-
message: logType
|
|
1184
|
-
? `\n Audit log for: ${orgSlug} with type: ${logType}\n`
|
|
1185
|
-
: `\n Audit log for: ${orgSlug}\n`,
|
|
1186
|
-
choices: data,
|
|
1187
|
-
pageSize: 30
|
|
1188
|
-
})
|
|
1189
|
-
]
|
|
1190
|
-
)
|
|
1191
1211
|
}
|
|
1192
1212
|
|
|
1193
1213
|
async function handleAuditLog({ logType, orgSlug, outputKind, page, perPage }) {
|
|
@@ -1210,7 +1230,7 @@ async function handleAuditLog({ logType, orgSlug, outputKind, page, perPage }) {
|
|
|
1210
1230
|
})
|
|
1211
1231
|
}
|
|
1212
1232
|
|
|
1213
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
1233
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$F } = constants
|
|
1214
1234
|
const config$I = {
|
|
1215
1235
|
commandName: 'audit-log',
|
|
1216
1236
|
description: 'Look up the audit log for an organization',
|
|
@@ -1241,6 +1261,10 @@ const config$I = {
|
|
|
1241
1261
|
Usage
|
|
1242
1262
|
$ ${command} <org slug>
|
|
1243
1263
|
|
|
1264
|
+
API Token Requirements
|
|
1265
|
+
- Quota: 1 unit
|
|
1266
|
+
- Permissions: audit-log:list
|
|
1267
|
+
|
|
1244
1268
|
This feature requires an Enterprise Plan. To learn more about getting access
|
|
1245
1269
|
to this feature and many more, please visit https://socket.dev/pricing
|
|
1246
1270
|
|
|
@@ -1296,7 +1320,7 @@ async function run$I(argv, importMeta, { parentName }) {
|
|
|
1296
1320
|
return
|
|
1297
1321
|
}
|
|
1298
1322
|
if (cli.flags['dryRun']) {
|
|
1299
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
1323
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$F)
|
|
1300
1324
|
return
|
|
1301
1325
|
}
|
|
1302
1326
|
await handleAuditLog({
|
|
@@ -1424,7 +1448,7 @@ function isHelpFlag(cmdArg) {
|
|
|
1424
1448
|
}
|
|
1425
1449
|
|
|
1426
1450
|
// import { meowOrExit } from '../../utils/meow-with-subcommands'
|
|
1427
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
1451
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$E } = constants
|
|
1428
1452
|
|
|
1429
1453
|
// TODO: convert yargs to meow. Or convert all the other things to yargs.
|
|
1430
1454
|
const toLower = arg => arg.toLowerCase()
|
|
@@ -1587,7 +1611,7 @@ async function run$H(argv, importMeta, { parentName }) {
|
|
|
1587
1611
|
return
|
|
1588
1612
|
}
|
|
1589
1613
|
if (cli.flags['dryRun']) {
|
|
1590
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
1614
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$E)
|
|
1591
1615
|
return
|
|
1592
1616
|
}
|
|
1593
1617
|
if (yargv.output === undefined) {
|
|
@@ -1623,7 +1647,7 @@ async function discoverConfigValue(key) {
|
|
|
1623
1647
|
success: false,
|
|
1624
1648
|
value: undefined,
|
|
1625
1649
|
message:
|
|
1626
|
-
'When uncertain, unset this key. Otherwise ask your network administrator
|
|
1650
|
+
'When uncertain, unset this key. Otherwise ask your network administrator'
|
|
1627
1651
|
}
|
|
1628
1652
|
}
|
|
1629
1653
|
if (key === 'apiToken') {
|
|
@@ -1837,7 +1861,7 @@ async function handleConfigAuto({ key, outputKind }) {
|
|
|
1837
1861
|
await outputConfigAuto(key, result, outputKind)
|
|
1838
1862
|
}
|
|
1839
1863
|
|
|
1840
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
1864
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$D } = constants
|
|
1841
1865
|
const config$G = {
|
|
1842
1866
|
commandName: 'auto',
|
|
1843
1867
|
description: 'Automatically discover and set the correct value config item',
|
|
@@ -1902,7 +1926,7 @@ async function run$G(argv, importMeta, { parentName }) {
|
|
|
1902
1926
|
return
|
|
1903
1927
|
}
|
|
1904
1928
|
if (cli.flags['dryRun']) {
|
|
1905
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
1929
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$D)
|
|
1906
1930
|
return
|
|
1907
1931
|
}
|
|
1908
1932
|
await handleConfigAuto({
|
|
@@ -1911,7 +1935,13 @@ async function run$G(argv, importMeta, { parentName }) {
|
|
|
1911
1935
|
})
|
|
1912
1936
|
}
|
|
1913
1937
|
|
|
1914
|
-
async function outputConfigGet(
|
|
1938
|
+
async function outputConfigGet(
|
|
1939
|
+
key,
|
|
1940
|
+
value,
|
|
1941
|
+
readOnly,
|
|
1942
|
+
// Is config in read-only mode? (Overrides applied)
|
|
1943
|
+
outputKind
|
|
1944
|
+
) {
|
|
1915
1945
|
if (outputKind === 'json') {
|
|
1916
1946
|
logger.logger.log(
|
|
1917
1947
|
JSON.stringify({
|
|
@@ -1919,24 +1949,38 @@ async function outputConfigGet(key, value, outputKind) {
|
|
|
1919
1949
|
result: {
|
|
1920
1950
|
key,
|
|
1921
1951
|
value
|
|
1922
|
-
}
|
|
1952
|
+
},
|
|
1953
|
+
readOnly
|
|
1923
1954
|
})
|
|
1924
1955
|
)
|
|
1925
1956
|
} else if (outputKind === 'markdown') {
|
|
1926
1957
|
logger.logger.log(`# Config Value`)
|
|
1927
1958
|
logger.logger.log('')
|
|
1928
1959
|
logger.logger.log(`Config key '${key}' has value '${value}`)
|
|
1960
|
+
if (readOnly) {
|
|
1961
|
+
logger.logger.log('')
|
|
1962
|
+
logger.logger.log(
|
|
1963
|
+
'Note: the config is in read-only mode, meaning at least one key was temporarily\n overridden from an env var or command flag.'
|
|
1964
|
+
)
|
|
1965
|
+
}
|
|
1929
1966
|
} else {
|
|
1930
1967
|
logger.logger.log(`${key}: ${value}`)
|
|
1968
|
+
if (readOnly) {
|
|
1969
|
+
logger.logger.log('')
|
|
1970
|
+
logger.logger.log(
|
|
1971
|
+
'Note: the config is in read-only mode, meaning at least one key was temporarily overridden from an env var or command flag.'
|
|
1972
|
+
)
|
|
1973
|
+
}
|
|
1931
1974
|
}
|
|
1932
1975
|
}
|
|
1933
1976
|
|
|
1934
1977
|
async function handleConfigGet({ key, outputKind }) {
|
|
1935
1978
|
const value = shadowNpmInject.getConfigValue(key)
|
|
1936
|
-
|
|
1979
|
+
const readOnly = shadowNpmInject.isReadOnlyConfig()
|
|
1980
|
+
await outputConfigGet(key, value, readOnly, outputKind)
|
|
1937
1981
|
}
|
|
1938
1982
|
|
|
1939
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
1983
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$C } = constants
|
|
1940
1984
|
const config$F = {
|
|
1941
1985
|
commandName: 'get',
|
|
1942
1986
|
description: 'Get the value of a local CLI config item',
|
|
@@ -1996,7 +2040,7 @@ async function run$F(argv, importMeta, { parentName }) {
|
|
|
1996
2040
|
return
|
|
1997
2041
|
}
|
|
1998
2042
|
if (cli.flags['dryRun']) {
|
|
1999
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
2043
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$C)
|
|
2000
2044
|
return
|
|
2001
2045
|
}
|
|
2002
2046
|
await handleConfigGet({
|
|
@@ -2006,6 +2050,7 @@ async function run$F(argv, importMeta, { parentName }) {
|
|
|
2006
2050
|
}
|
|
2007
2051
|
|
|
2008
2052
|
async function outputConfigList({ full, outputKind }) {
|
|
2053
|
+
const readOnly = shadowNpmInject.isReadOnlyConfig()
|
|
2009
2054
|
if (outputKind === 'json') {
|
|
2010
2055
|
const obj = {}
|
|
2011
2056
|
for (const key of shadowNpmInject.supportedConfigKeys.keys()) {
|
|
@@ -2022,7 +2067,8 @@ async function outputConfigList({ full, outputKind }) {
|
|
|
2022
2067
|
{
|
|
2023
2068
|
success: true,
|
|
2024
2069
|
full,
|
|
2025
|
-
config: obj
|
|
2070
|
+
config: obj,
|
|
2071
|
+
readOnly
|
|
2026
2072
|
},
|
|
2027
2073
|
null,
|
|
2028
2074
|
2
|
|
@@ -2047,10 +2093,16 @@ async function outputConfigList({ full, outputKind }) {
|
|
|
2047
2093
|
)
|
|
2048
2094
|
}
|
|
2049
2095
|
}
|
|
2096
|
+
if (readOnly) {
|
|
2097
|
+
logger.logger.log('')
|
|
2098
|
+
logger.logger.log(
|
|
2099
|
+
'Note: the config is in read-only mode, meaning at least one key was temporarily\n overridden from an env var or command flag.'
|
|
2100
|
+
)
|
|
2101
|
+
}
|
|
2050
2102
|
}
|
|
2051
2103
|
}
|
|
2052
2104
|
|
|
2053
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
2105
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$B } = constants
|
|
2054
2106
|
const config$E = {
|
|
2055
2107
|
commandName: 'list',
|
|
2056
2108
|
description: 'Show all local CLI config items and their values',
|
|
@@ -2106,7 +2158,7 @@ async function run$E(argv, importMeta, { parentName }) {
|
|
|
2106
2158
|
return
|
|
2107
2159
|
}
|
|
2108
2160
|
if (cli.flags['dryRun']) {
|
|
2109
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
2161
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$B)
|
|
2110
2162
|
return
|
|
2111
2163
|
}
|
|
2112
2164
|
await outputConfigList({
|
|
@@ -2115,29 +2167,43 @@ async function run$E(argv, importMeta, { parentName }) {
|
|
|
2115
2167
|
})
|
|
2116
2168
|
}
|
|
2117
2169
|
|
|
2118
|
-
async function outputConfigSet(key, _value, outputKind) {
|
|
2170
|
+
async function outputConfigSet(key, _value, readOnly, outputKind) {
|
|
2119
2171
|
if (outputKind === 'json') {
|
|
2120
2172
|
logger.logger.log(
|
|
2121
2173
|
JSON.stringify({
|
|
2122
2174
|
success: true,
|
|
2123
|
-
message: `Config key '${key}' was updated
|
|
2175
|
+
message: `Config key '${key}' was updated${readOnly ? ' (Note: since at least one value was overridden from flag/env, the config was not persisted)' : ''}`,
|
|
2176
|
+
readOnly
|
|
2124
2177
|
})
|
|
2125
2178
|
)
|
|
2126
2179
|
} else if (outputKind === 'markdown') {
|
|
2127
2180
|
logger.logger.log(`# Update config`)
|
|
2128
2181
|
logger.logger.log('')
|
|
2129
2182
|
logger.logger.log(`Config key '${key}' was updated`)
|
|
2183
|
+
if (readOnly) {
|
|
2184
|
+
logger.logger.log('')
|
|
2185
|
+
logger.logger.log(
|
|
2186
|
+
'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.'
|
|
2187
|
+
)
|
|
2188
|
+
}
|
|
2130
2189
|
} else {
|
|
2131
2190
|
logger.logger.log(`OK`)
|
|
2191
|
+
if (readOnly) {
|
|
2192
|
+
logger.logger.log('')
|
|
2193
|
+
logger.logger.log(
|
|
2194
|
+
'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.'
|
|
2195
|
+
)
|
|
2196
|
+
}
|
|
2132
2197
|
}
|
|
2133
2198
|
}
|
|
2134
2199
|
|
|
2135
2200
|
async function handleConfigSet({ key, outputKind, value }) {
|
|
2136
2201
|
shadowNpmInject.updateConfigValue(key, value)
|
|
2137
|
-
|
|
2202
|
+
const readOnly = shadowNpmInject.isReadOnlyConfig()
|
|
2203
|
+
await outputConfigSet(key, value, readOnly, outputKind)
|
|
2138
2204
|
}
|
|
2139
2205
|
|
|
2140
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
2206
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$A } = constants
|
|
2141
2207
|
const config$D = {
|
|
2142
2208
|
commandName: 'set',
|
|
2143
2209
|
description: 'Update the value of a local CLI config item',
|
|
@@ -2211,7 +2277,7 @@ async function run$D(argv, importMeta, { parentName }) {
|
|
|
2211
2277
|
return
|
|
2212
2278
|
}
|
|
2213
2279
|
if (cli.flags['dryRun']) {
|
|
2214
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
2280
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$A)
|
|
2215
2281
|
return
|
|
2216
2282
|
}
|
|
2217
2283
|
await handleConfigSet({
|
|
@@ -2243,7 +2309,7 @@ async function handleConfigUnset({ key, outputKind }) {
|
|
|
2243
2309
|
await outputConfigUnset(key, outputKind)
|
|
2244
2310
|
}
|
|
2245
2311
|
|
|
2246
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
2312
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$z } = constants
|
|
2247
2313
|
const config$C = {
|
|
2248
2314
|
commandName: 'unset',
|
|
2249
2315
|
description: 'Clear the value of a local CLI config item',
|
|
@@ -2303,7 +2369,7 @@ async function run$C(argv, importMeta, { parentName }) {
|
|
|
2303
2369
|
return
|
|
2304
2370
|
}
|
|
2305
2371
|
if (cli.flags['dryRun']) {
|
|
2306
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
2372
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$z)
|
|
2307
2373
|
return
|
|
2308
2374
|
}
|
|
2309
2375
|
await handleConfigUnset({
|
|
@@ -2352,7 +2418,6 @@ async function fetchDependencies({ limit, offset }) {
|
|
|
2352
2418
|
spinner.successAndStop('Received organization dependencies response.')
|
|
2353
2419
|
if (!result.success) {
|
|
2354
2420
|
handleUnsuccessfulApiResponse('searchDependencies', result)
|
|
2355
|
-
return
|
|
2356
2421
|
}
|
|
2357
2422
|
return result.data
|
|
2358
2423
|
}
|
|
@@ -2431,7 +2496,7 @@ async function handleDependencies({ limit, offset, outputKind }) {
|
|
|
2431
2496
|
})
|
|
2432
2497
|
}
|
|
2433
2498
|
|
|
2434
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
2499
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$y } = constants
|
|
2435
2500
|
const config$B = {
|
|
2436
2501
|
commandName: 'dependencies',
|
|
2437
2502
|
description:
|
|
@@ -2457,6 +2522,10 @@ const config$B = {
|
|
|
2457
2522
|
Usage
|
|
2458
2523
|
${command}
|
|
2459
2524
|
|
|
2525
|
+
API Token Requirements
|
|
2526
|
+
- Quota: 1 unit
|
|
2527
|
+
- Permissions: none (does need token with access to target org)
|
|
2528
|
+
|
|
2460
2529
|
Options
|
|
2461
2530
|
${getFlagListOutput(config.flags, 6)}
|
|
2462
2531
|
|
|
@@ -2500,7 +2569,7 @@ async function run$B(argv, importMeta, { parentName }) {
|
|
|
2500
2569
|
return
|
|
2501
2570
|
}
|
|
2502
2571
|
if (cli.flags['dryRun']) {
|
|
2503
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
2572
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$y)
|
|
2504
2573
|
return
|
|
2505
2574
|
}
|
|
2506
2575
|
await handleDependencies({
|
|
@@ -2614,7 +2683,7 @@ async function handleDiffScan({
|
|
|
2614
2683
|
})
|
|
2615
2684
|
}
|
|
2616
2685
|
|
|
2617
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
2686
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$x } = constants
|
|
2618
2687
|
const config$A = {
|
|
2619
2688
|
commandName: 'get',
|
|
2620
2689
|
description: 'Get a diff scan for an organization',
|
|
@@ -2658,6 +2727,10 @@ const config$A = {
|
|
|
2658
2727
|
Usage
|
|
2659
2728
|
$ ${command} <org slug> --before=<before> --after=<after>
|
|
2660
2729
|
|
|
2730
|
+
API Token Requirements
|
|
2731
|
+
- Quota: 1 unit
|
|
2732
|
+
- Permissions: full-scans:list
|
|
2733
|
+
|
|
2661
2734
|
This command displays the package changes between two scans. The full output
|
|
2662
2735
|
can be pretty large depending on the size of your repo and time range. It is
|
|
2663
2736
|
best stored to disk to be further analyzed by other tools.
|
|
@@ -2689,7 +2762,7 @@ async function run$A(argv, importMeta, { parentName }) {
|
|
|
2689
2762
|
{
|
|
2690
2763
|
test: !!(before && after),
|
|
2691
2764
|
message:
|
|
2692
|
-
'Specify a before and after scan ID
|
|
2765
|
+
'Specify a before and after scan ID.\nThe args are expecting a full `aaa0aa0a-aaaa-0000-0a0a-0000000a00a0` scan ID.',
|
|
2693
2766
|
pass: 'ok',
|
|
2694
2767
|
fail:
|
|
2695
2768
|
!before && !after
|
|
@@ -2726,7 +2799,7 @@ async function run$A(argv, importMeta, { parentName }) {
|
|
|
2726
2799
|
return
|
|
2727
2800
|
}
|
|
2728
2801
|
if (cli.flags['dryRun']) {
|
|
2729
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
2802
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$x)
|
|
2730
2803
|
return
|
|
2731
2804
|
}
|
|
2732
2805
|
await handleDiffScan({
|
|
@@ -2766,8 +2839,13 @@ const { NPM: NPM$f } = constants
|
|
|
2766
2839
|
function isTopLevel(tree, node) {
|
|
2767
2840
|
return tree.children.get(node.name) === node
|
|
2768
2841
|
}
|
|
2769
|
-
async function npmFix(_pkgEnvDetails,
|
|
2770
|
-
const {
|
|
2842
|
+
async function npmFix(_pkgEnvDetails, options) {
|
|
2843
|
+
const {
|
|
2844
|
+
cwd = process.cwd(),
|
|
2845
|
+
spinner,
|
|
2846
|
+
test = false,
|
|
2847
|
+
testScript = 'test'
|
|
2848
|
+
} = {
|
|
2771
2849
|
__proto__: null,
|
|
2772
2850
|
...options
|
|
2773
2851
|
}
|
|
@@ -2783,7 +2861,8 @@ async function npmFix(_pkgEnvDetails, cwd, options) {
|
|
|
2783
2861
|
existing: true,
|
|
2784
2862
|
unfixable: false,
|
|
2785
2863
|
upgradable: false
|
|
2786
|
-
}
|
|
2864
|
+
},
|
|
2865
|
+
nothrow: true
|
|
2787
2866
|
})
|
|
2788
2867
|
const infoByPkg = shadowNpmInject.getCveInfoByAlertsMap(alertsMap)
|
|
2789
2868
|
if (!infoByPkg) {
|
|
@@ -2828,11 +2907,13 @@ async function npmFix(_pkgEnvDetails, cwd, options) {
|
|
|
2828
2907
|
shadowNpmInject.updateNode(node, packument, vulnerableVersionRange)
|
|
2829
2908
|
) {
|
|
2830
2909
|
try {
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2910
|
+
if (test) {
|
|
2911
|
+
// eslint-disable-next-line no-await-in-loop
|
|
2912
|
+
await npm.runScript(testScript, [], {
|
|
2913
|
+
spinner,
|
|
2914
|
+
stdio: 'ignore'
|
|
2915
|
+
})
|
|
2916
|
+
}
|
|
2836
2917
|
spinner?.info(`Patched ${name} ${oldVersion} -> ${node.version}`)
|
|
2837
2918
|
if (isTopLevel(tree, node)) {
|
|
2838
2919
|
for (const depField of [
|
|
@@ -2868,16 +2949,24 @@ async function npmFix(_pkgEnvDetails, cwd, options) {
|
|
|
2868
2949
|
spinner?.stop()
|
|
2869
2950
|
}
|
|
2870
2951
|
|
|
2871
|
-
async function getAlertsMapFromPnpmLockfile(lockfile,
|
|
2872
|
-
const
|
|
2952
|
+
async function getAlertsMapFromPnpmLockfile(lockfile, options_) {
|
|
2953
|
+
const options = {
|
|
2873
2954
|
__proto__: null,
|
|
2874
|
-
|
|
2955
|
+
consolidate: false,
|
|
2956
|
+
nothrow: false,
|
|
2957
|
+
...options_
|
|
2875
2958
|
}
|
|
2876
2959
|
const include = {
|
|
2877
2960
|
__proto__: null,
|
|
2961
|
+
blocked: true,
|
|
2962
|
+
critical: true,
|
|
2963
|
+
cve: true,
|
|
2964
|
+
existing: false,
|
|
2878
2965
|
unfixable: true,
|
|
2879
|
-
|
|
2966
|
+
upgradable: false,
|
|
2967
|
+
...options.include
|
|
2880
2968
|
}
|
|
2969
|
+
const { spinner } = options
|
|
2881
2970
|
const depTypes = lockfile_detectDepTypes.detectDepTypes(lockfile)
|
|
2882
2971
|
const pkgIds = Object.keys(depTypes)
|
|
2883
2972
|
let { length: remaining } = pkgIds
|
|
@@ -2892,9 +2981,11 @@ async function getAlertsMapFromPnpmLockfile(lockfile, options) {
|
|
|
2892
2981
|
)
|
|
2893
2982
|
const toAlertsMapOptions = {
|
|
2894
2983
|
overrides: lockfile.overrides,
|
|
2895
|
-
|
|
2984
|
+
consolidate: options.consolidate,
|
|
2985
|
+
include,
|
|
2986
|
+
spinner
|
|
2896
2987
|
}
|
|
2897
|
-
for await (const
|
|
2988
|
+
for await (const batchResult of sockSdk.batchPackageStream(
|
|
2898
2989
|
{
|
|
2899
2990
|
alerts: 'true',
|
|
2900
2991
|
compact: 'true',
|
|
@@ -2906,12 +2997,18 @@ async function getAlertsMapFromPnpmLockfile(lockfile, options) {
|
|
|
2906
2997
|
}))
|
|
2907
2998
|
}
|
|
2908
2999
|
)) {
|
|
2909
|
-
if (
|
|
3000
|
+
if (batchResult.success) {
|
|
2910
3001
|
await shadowNpmInject.addArtifactToAlertsMap(
|
|
2911
|
-
|
|
3002
|
+
batchResult.data,
|
|
2912
3003
|
alertsByPkgId,
|
|
2913
3004
|
toAlertsMapOptions
|
|
2914
3005
|
)
|
|
3006
|
+
} else if (!options.nothrow) {
|
|
3007
|
+
const statusCode = batchResult.status ?? 'unknown'
|
|
3008
|
+
const statusMessage = batchResult.error ?? 'No status message'
|
|
3009
|
+
throw new Error(
|
|
3010
|
+
`Socket API server error (${statusCode}): ${statusMessage}`
|
|
3011
|
+
)
|
|
2915
3012
|
}
|
|
2916
3013
|
remaining -= 1
|
|
2917
3014
|
if (spinner && remaining > 0) {
|
|
@@ -3043,12 +3140,99 @@ function runAgentInstall(pkgEnvDetails, options) {
|
|
|
3043
3140
|
}
|
|
3044
3141
|
|
|
3045
3142
|
const { NPM: NPM$c, OVERRIDES: OVERRIDES$2, PNPM: PNPM$9 } = constants
|
|
3046
|
-
async function
|
|
3047
|
-
|
|
3143
|
+
async function branchExists(branchName, cwd) {
|
|
3144
|
+
try {
|
|
3145
|
+
await spawn.spawn('git', ['rev-parse', '--verify', branchName], {
|
|
3146
|
+
cwd,
|
|
3147
|
+
stdio: 'ignore'
|
|
3148
|
+
})
|
|
3149
|
+
return true
|
|
3150
|
+
} catch {
|
|
3151
|
+
return false
|
|
3152
|
+
}
|
|
3153
|
+
}
|
|
3154
|
+
async function remoteBranchExists(branchName, cwd) {
|
|
3155
|
+
try {
|
|
3156
|
+
const result = await spawn.spawn(
|
|
3157
|
+
'git',
|
|
3158
|
+
['ls-remote', '--heads', 'origin', branchName],
|
|
3159
|
+
{
|
|
3160
|
+
cwd,
|
|
3161
|
+
stdio: 'pipe'
|
|
3162
|
+
}
|
|
3163
|
+
)
|
|
3164
|
+
return !!result.stdout.trim()
|
|
3165
|
+
} catch {
|
|
3166
|
+
return false
|
|
3167
|
+
}
|
|
3168
|
+
}
|
|
3169
|
+
async function commitAndPushFix(branchName, commitMsg, cwd) {
|
|
3170
|
+
const localExists = await branchExists(branchName, cwd)
|
|
3171
|
+
const remoteExists = await remoteBranchExists(branchName, cwd)
|
|
3172
|
+
if (localExists || remoteExists) {
|
|
3173
|
+
logger.logger.warn(
|
|
3174
|
+
`Branch "${branchName}" already exists. Skipping creation.`
|
|
3175
|
+
)
|
|
3176
|
+
return
|
|
3177
|
+
}
|
|
3178
|
+
await spawn.spawn('git', ['checkout', '-b', branchName], {
|
|
3179
|
+
cwd
|
|
3180
|
+
})
|
|
3181
|
+
await spawn.spawn('git', ['add', 'package.json', 'pnpm-lock.yaml'], {
|
|
3182
|
+
cwd
|
|
3183
|
+
})
|
|
3184
|
+
await spawn.spawn('git', ['commit', '-m', commitMsg], {
|
|
3185
|
+
cwd
|
|
3186
|
+
})
|
|
3187
|
+
await spawn.spawn('git', ['push', '--set-upstream', 'origin', branchName], {
|
|
3188
|
+
cwd
|
|
3189
|
+
})
|
|
3190
|
+
}
|
|
3191
|
+
async function createPullRequest({
|
|
3192
|
+
base = 'main',
|
|
3193
|
+
body,
|
|
3194
|
+
head,
|
|
3195
|
+
owner,
|
|
3196
|
+
repo,
|
|
3197
|
+
title
|
|
3198
|
+
}) {
|
|
3199
|
+
const octokit = new rest.Octokit({
|
|
3200
|
+
auth: process.env['GITHUB_TOKEN']
|
|
3201
|
+
})
|
|
3202
|
+
await octokit.pulls.create({
|
|
3203
|
+
owner,
|
|
3204
|
+
repo,
|
|
3205
|
+
title,
|
|
3206
|
+
head,
|
|
3207
|
+
base,
|
|
3208
|
+
...(body
|
|
3209
|
+
? {
|
|
3210
|
+
body
|
|
3211
|
+
}
|
|
3212
|
+
: {})
|
|
3213
|
+
})
|
|
3214
|
+
}
|
|
3215
|
+
function getRepoInfo() {
|
|
3216
|
+
const repoString = process.env['GITHUB_REPOSITORY']
|
|
3217
|
+
if (!repoString || !repoString.includes('/')) {
|
|
3218
|
+
throw new Error('GITHUB_REPOSITORY is not set or invalid')
|
|
3219
|
+
}
|
|
3220
|
+
const { 0: owner, 1: repo } = repoString.split('/')
|
|
3221
|
+
return {
|
|
3222
|
+
owner,
|
|
3223
|
+
repo
|
|
3224
|
+
}
|
|
3225
|
+
}
|
|
3226
|
+
async function pnpmFix(pkgEnvDetails, options) {
|
|
3227
|
+
const {
|
|
3228
|
+
cwd = process.cwd(),
|
|
3229
|
+
spinner,
|
|
3230
|
+
test = false,
|
|
3231
|
+
testScript = 'test'
|
|
3232
|
+
} = {
|
|
3048
3233
|
__proto__: null,
|
|
3049
3234
|
...options
|
|
3050
3235
|
}
|
|
3051
|
-
spinner?.start()
|
|
3052
3236
|
const lockfile = await lockfile_fs.readWantedLockfile(cwd, {
|
|
3053
3237
|
ignoreIncompatible: false
|
|
3054
3238
|
})
|
|
@@ -3062,7 +3246,8 @@ async function pnpmFix(pkgEnvDetails, cwd, options) {
|
|
|
3062
3246
|
existing: true,
|
|
3063
3247
|
unfixable: false,
|
|
3064
3248
|
upgradable: false
|
|
3065
|
-
}
|
|
3249
|
+
},
|
|
3250
|
+
nothrow: true
|
|
3066
3251
|
})
|
|
3067
3252
|
const infoByPkg = shadowNpmInject.getCveInfoByAlertsMap(alertsMap)
|
|
3068
3253
|
if (!infoByPkg) {
|
|
@@ -3078,11 +3263,12 @@ async function pnpmFix(pkgEnvDetails, cwd, options) {
|
|
|
3078
3263
|
editable: true
|
|
3079
3264
|
})
|
|
3080
3265
|
const { content: pkgJson } = editablePkgJson
|
|
3266
|
+
spinner?.stop()
|
|
3081
3267
|
for (const { 0: name, 1: infos } of infoByPkg) {
|
|
3082
3268
|
const tree = arb.actualTree
|
|
3083
3269
|
const hasUpgrade = !!registry.getManifestData(NPM$c, name)
|
|
3084
3270
|
if (hasUpgrade) {
|
|
3085
|
-
|
|
3271
|
+
logger.logger.info(`Skipping ${name}. Socket Optimize package exists.`)
|
|
3086
3272
|
continue
|
|
3087
3273
|
}
|
|
3088
3274
|
const nodes = shadowNpmInject.findPackageNodes(tree, name)
|
|
@@ -3104,6 +3290,7 @@ async function pnpmFix(pkgEnvDetails, cwd, options) {
|
|
|
3104
3290
|
const { firstPatchedVersionIdentifier, vulnerableVersionRange } =
|
|
3105
3291
|
infos[j]
|
|
3106
3292
|
const { version: oldVersion } = node
|
|
3293
|
+
const oldSpec = `${name}@${oldVersion}`
|
|
3107
3294
|
const availableVersions = Object.keys(packument.versions)
|
|
3108
3295
|
// Find the highest non-vulnerable version within the same major range
|
|
3109
3296
|
const targetVersion = shadowNpmInject.findBestPatchVersion(
|
|
@@ -3114,20 +3301,28 @@ async function pnpmFix(pkgEnvDetails, cwd, options) {
|
|
|
3114
3301
|
const targetPackument = targetVersion
|
|
3115
3302
|
? packument.versions[targetVersion]
|
|
3116
3303
|
: undefined
|
|
3117
|
-
|
|
3304
|
+
spinner?.stop()
|
|
3305
|
+
|
|
3306
|
+
// Check targetVersion to make TypeScript happy.
|
|
3307
|
+
if (targetVersion && targetPackument) {
|
|
3118
3308
|
const oldPnpm = pkgJson[PNPM$9]
|
|
3119
3309
|
const oldOverrides = oldPnpm?.[OVERRIDES$2]
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3310
|
+
const overrideKey = `${node.name}@${vulnerableVersionRange}`
|
|
3311
|
+
const overrideRange = `^${targetVersion}`
|
|
3312
|
+
const fixSpec = `${name}@${overrideRange}`
|
|
3313
|
+
const data = {
|
|
3314
|
+
[PNPM$9]: {
|
|
3315
|
+
...oldPnpm,
|
|
3316
|
+
[OVERRIDES$2]: {
|
|
3317
|
+
[overrideKey]: overrideRange,
|
|
3318
|
+
...oldOverrides
|
|
3128
3319
|
}
|
|
3129
|
-
}
|
|
3130
|
-
|
|
3320
|
+
}
|
|
3321
|
+
}
|
|
3322
|
+
try {
|
|
3323
|
+
editablePkgJson.update(data)
|
|
3324
|
+
spinner?.start()
|
|
3325
|
+
spinner?.info(`Installing ${fixSpec}`)
|
|
3131
3326
|
|
|
3132
3327
|
// eslint-disable-next-line no-await-in-loop
|
|
3133
3328
|
await editablePkgJson.save()
|
|
@@ -3135,11 +3330,70 @@ async function pnpmFix(pkgEnvDetails, cwd, options) {
|
|
|
3135
3330
|
await runAgentInstall(pkgEnvDetails, {
|
|
3136
3331
|
spinner
|
|
3137
3332
|
})
|
|
3333
|
+
if (test) {
|
|
3334
|
+
spinner?.info(`Testing ${fixSpec}`)
|
|
3335
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3336
|
+
await npm.runScript(testScript, [], {
|
|
3337
|
+
spinner,
|
|
3338
|
+
stdio: 'ignore'
|
|
3339
|
+
})
|
|
3340
|
+
}
|
|
3341
|
+
try {
|
|
3342
|
+
const branchName = `fix-${name}-${targetVersion.replace(/\./g, '-')}`
|
|
3343
|
+
const commitMsg = `fix: upgrade ${name} to ${targetVersion}`
|
|
3344
|
+
const { owner, repo } = getRepoInfo()
|
|
3345
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3346
|
+
await commitAndPushFix(branchName, commitMsg, cwd)
|
|
3347
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3348
|
+
await createPullRequest({
|
|
3349
|
+
owner,
|
|
3350
|
+
repo,
|
|
3351
|
+
title: commitMsg,
|
|
3352
|
+
head: branchName,
|
|
3353
|
+
base: process.env['GITHUB_REF_NAME'] ?? 'master',
|
|
3354
|
+
body: `This PR fixes a security issue in \`${name}\` by upgrading to \`${targetVersion}\`.`
|
|
3355
|
+
})
|
|
3356
|
+
} catch (e) {
|
|
3357
|
+
console.log(e)
|
|
3358
|
+
}
|
|
3359
|
+
logger.logger.success(`Fixed ${name}`)
|
|
3138
3360
|
} catch {
|
|
3139
|
-
spinner?.error(`Reverting ${
|
|
3361
|
+
spinner?.error(`Reverting ${fixSpec}`)
|
|
3362
|
+
const pnpmKeyCount = Object.keys(data[PNPM$9]).length
|
|
3363
|
+
const pnpmOverridesKeyCount = Object.keys(
|
|
3364
|
+
data[PNPM$9][OVERRIDES$2]
|
|
3365
|
+
).length
|
|
3366
|
+
if (pnpmKeyCount === 1 && pnpmOverridesKeyCount === 1) {
|
|
3367
|
+
editablePkgJson.update({
|
|
3368
|
+
// Setting to `undefined` will remove the property.
|
|
3369
|
+
[PNPM$9]: undefined
|
|
3370
|
+
})
|
|
3371
|
+
} else {
|
|
3372
|
+
editablePkgJson.update({
|
|
3373
|
+
[PNPM$9]: {
|
|
3374
|
+
...oldPnpm,
|
|
3375
|
+
[OVERRIDES$2]:
|
|
3376
|
+
pnpmOverridesKeyCount === 1
|
|
3377
|
+
? undefined
|
|
3378
|
+
: {
|
|
3379
|
+
[overrideKey]: undefined,
|
|
3380
|
+
...oldOverrides
|
|
3381
|
+
}
|
|
3382
|
+
}
|
|
3383
|
+
})
|
|
3384
|
+
}
|
|
3385
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3386
|
+
await editablePkgJson.save()
|
|
3387
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3388
|
+
await runAgentInstall(pkgEnvDetails, {
|
|
3389
|
+
spinner
|
|
3390
|
+
})
|
|
3391
|
+
spinner?.stop()
|
|
3392
|
+
logger.logger.error(`Failed to fix ${oldSpec}`)
|
|
3140
3393
|
}
|
|
3141
3394
|
} else {
|
|
3142
|
-
spinner?.
|
|
3395
|
+
spinner?.stop()
|
|
3396
|
+
logger.logger.error(`Could not patch ${oldSpec}`)
|
|
3143
3397
|
}
|
|
3144
3398
|
}
|
|
3145
3399
|
}
|
|
@@ -3545,39 +3799,59 @@ async function detectAndValidatePackageEnvironment(cwd, options) {
|
|
|
3545
3799
|
|
|
3546
3800
|
const { NPM: NPM$a, PNPM: PNPM$7 } = constants
|
|
3547
3801
|
const CMD_NAME$2 = 'socket fix'
|
|
3548
|
-
async function runFix(
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3802
|
+
async function runFix({
|
|
3803
|
+
cwd = process.cwd(),
|
|
3804
|
+
spinner,
|
|
3805
|
+
test = false,
|
|
3806
|
+
testScript = 'test'
|
|
3807
|
+
}) {
|
|
3553
3808
|
const pkgEnvDetails = await detectAndValidatePackageEnvironment(cwd, {
|
|
3554
3809
|
cmdName: CMD_NAME$2,
|
|
3555
3810
|
logger: logger.logger
|
|
3556
3811
|
})
|
|
3557
3812
|
if (!pkgEnvDetails) {
|
|
3558
|
-
spinner
|
|
3813
|
+
spinner?.stop()
|
|
3559
3814
|
return
|
|
3560
3815
|
}
|
|
3816
|
+
logger.logger.info(`Fixing packages for ${pkgEnvDetails.agent}`)
|
|
3561
3817
|
switch (pkgEnvDetails.agent) {
|
|
3562
3818
|
case NPM$a: {
|
|
3563
|
-
await npmFix(pkgEnvDetails,
|
|
3819
|
+
await npmFix(pkgEnvDetails, {
|
|
3820
|
+
spinner,
|
|
3821
|
+
test,
|
|
3822
|
+
testScript
|
|
3823
|
+
})
|
|
3564
3824
|
break
|
|
3565
3825
|
}
|
|
3566
3826
|
case PNPM$7: {
|
|
3567
|
-
await pnpmFix(pkgEnvDetails,
|
|
3827
|
+
await pnpmFix(pkgEnvDetails, {
|
|
3828
|
+
spinner,
|
|
3829
|
+
test,
|
|
3830
|
+
testScript
|
|
3831
|
+
})
|
|
3568
3832
|
break
|
|
3569
3833
|
}
|
|
3570
3834
|
}
|
|
3571
|
-
spinner.successAndStop('Socket.dev fix successful')
|
|
3835
|
+
// spinner.successAndStop('Socket.dev fix successful')
|
|
3572
3836
|
}
|
|
3573
3837
|
|
|
3574
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
3838
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$w } = constants
|
|
3575
3839
|
const config$z = {
|
|
3576
3840
|
commandName: 'fix',
|
|
3577
3841
|
description: 'Fix "fixable" Socket alerts',
|
|
3578
3842
|
hidden: true,
|
|
3579
3843
|
flags: {
|
|
3580
|
-
...commonFlags
|
|
3844
|
+
...commonFlags,
|
|
3845
|
+
test: {
|
|
3846
|
+
type: 'boolean',
|
|
3847
|
+
default: true,
|
|
3848
|
+
description: 'Very the fix by running unit tests'
|
|
3849
|
+
},
|
|
3850
|
+
testScript: {
|
|
3851
|
+
type: 'string',
|
|
3852
|
+
default: 'test',
|
|
3853
|
+
description: 'The test script to run for each fix attempt'
|
|
3854
|
+
}
|
|
3581
3855
|
},
|
|
3582
3856
|
help: (command, config) => `
|
|
3583
3857
|
Usage
|
|
@@ -3600,10 +3874,17 @@ async function run$z(argv, importMeta, { parentName }) {
|
|
|
3600
3874
|
parentName
|
|
3601
3875
|
})
|
|
3602
3876
|
if (cli.flags['dryRun']) {
|
|
3603
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
3877
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$w)
|
|
3604
3878
|
return
|
|
3605
3879
|
}
|
|
3606
|
-
|
|
3880
|
+
|
|
3881
|
+
// Lazily access constants.spinner.
|
|
3882
|
+
const { spinner } = constants
|
|
3883
|
+
await runFix({
|
|
3884
|
+
spinner,
|
|
3885
|
+
test: Boolean(cli.flags['test']),
|
|
3886
|
+
testScript: cli.flags['testScript']
|
|
3887
|
+
})
|
|
3607
3888
|
}
|
|
3608
3889
|
|
|
3609
3890
|
async function fetchPackageInfo(pkgName, pkgVersion, includeAllIssues) {
|
|
@@ -3628,10 +3909,10 @@ async function fetchPackageInfo(pkgName, pkgVersion, includeAllIssues) {
|
|
|
3628
3909
|
)
|
|
3629
3910
|
spinner.successAndStop('Data fetched')
|
|
3630
3911
|
if (result.success === false) {
|
|
3631
|
-
|
|
3912
|
+
handleUnsuccessfulApiResponse('getIssuesByNPMPackage', result)
|
|
3632
3913
|
}
|
|
3633
3914
|
if (scoreResult.success === false) {
|
|
3634
|
-
|
|
3915
|
+
handleUnsuccessfulApiResponse('getScoreByNPMPackage', scoreResult)
|
|
3635
3916
|
}
|
|
3636
3917
|
const severityCount = shadowNpmInject.getSeverityCount(
|
|
3637
3918
|
result.data,
|
|
@@ -3792,7 +4073,7 @@ async function handlePackageInfo({
|
|
|
3792
4073
|
}
|
|
3793
4074
|
}
|
|
3794
4075
|
|
|
3795
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4076
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$v } = constants
|
|
3796
4077
|
const config$y = {
|
|
3797
4078
|
commandName: 'info',
|
|
3798
4079
|
description: 'Look up info regarding a package',
|
|
@@ -3860,7 +4141,7 @@ async function run$y(argv, importMeta, { parentName }) {
|
|
|
3860
4141
|
const pkgVersion =
|
|
3861
4142
|
versionSeparator < 1 ? 'latest' : rawPkgName.slice(versionSeparator + 1)
|
|
3862
4143
|
if (cli.flags['dryRun']) {
|
|
3863
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4144
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$v)
|
|
3864
4145
|
return
|
|
3865
4146
|
}
|
|
3866
4147
|
await handlePackageInfo({
|
|
@@ -3897,7 +4178,6 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
|
|
|
3897
4178
|
if (!result.success) {
|
|
3898
4179
|
logger.logger.fail('Authentication failed...')
|
|
3899
4180
|
handleUnsuccessfulApiResponse('getOrganizations', result)
|
|
3900
|
-
return
|
|
3901
4181
|
}
|
|
3902
4182
|
logger.logger.success('API key verified')
|
|
3903
4183
|
const orgs = result.data
|
|
@@ -3935,16 +4215,24 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
|
|
|
3935
4215
|
}
|
|
3936
4216
|
}
|
|
3937
4217
|
spinner.stop()
|
|
3938
|
-
const
|
|
4218
|
+
const previousPersistedToken = shadowNpmInject.getConfigValue('apiToken')
|
|
3939
4219
|
try {
|
|
3940
4220
|
applyLogin(apiToken, enforcedOrgs, apiBaseUrl, apiProxy)
|
|
3941
|
-
logger.logger.success(
|
|
4221
|
+
logger.logger.success(
|
|
4222
|
+
`API credentials ${previousPersistedToken === apiToken ? 'refreshed' : previousPersistedToken ? 'updated' : 'set'}`
|
|
4223
|
+
)
|
|
4224
|
+
if (!shadowNpmInject.isReadOnlyConfig()) {
|
|
4225
|
+
logger.logger.log('')
|
|
4226
|
+
logger.logger.warn(
|
|
4227
|
+
'Note: config is in read-only mode, at least one key was overridden through flag/env, so the login was not persisted!'
|
|
4228
|
+
)
|
|
4229
|
+
}
|
|
3942
4230
|
} catch {
|
|
3943
4231
|
logger.logger.fail(`API login failed`)
|
|
3944
4232
|
}
|
|
3945
4233
|
}
|
|
3946
4234
|
|
|
3947
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4235
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$u } = constants
|
|
3948
4236
|
const config$x = {
|
|
3949
4237
|
commandName: 'login',
|
|
3950
4238
|
description: 'Socket API login',
|
|
@@ -3964,6 +4252,9 @@ const config$x = {
|
|
|
3964
4252
|
Usage
|
|
3965
4253
|
$ ${command}
|
|
3966
4254
|
|
|
4255
|
+
API Token Requirements
|
|
4256
|
+
- Quota: 1 unit
|
|
4257
|
+
|
|
3967
4258
|
Logs into the Socket API by prompting for an API key
|
|
3968
4259
|
|
|
3969
4260
|
Options
|
|
@@ -3989,7 +4280,7 @@ async function run$x(argv, importMeta, { parentName }) {
|
|
|
3989
4280
|
const apiBaseUrl = cli.flags['apiBaseUrl']
|
|
3990
4281
|
const apiProxy = cli.flags['apiProxy']
|
|
3991
4282
|
if (cli.flags['dryRun']) {
|
|
3992
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4283
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$u)
|
|
3993
4284
|
return
|
|
3994
4285
|
}
|
|
3995
4286
|
if (!isInteractive()) {
|
|
@@ -4011,12 +4302,18 @@ function attemptLogout() {
|
|
|
4011
4302
|
try {
|
|
4012
4303
|
applyLogout()
|
|
4013
4304
|
logger.logger.success('Successfully logged out')
|
|
4305
|
+
if (!shadowNpmInject.isReadOnlyConfig()) {
|
|
4306
|
+
logger.logger.log('')
|
|
4307
|
+
logger.logger.warn(
|
|
4308
|
+
'Note: config is in read-only mode, at least one key was overridden through flag/env, so the logout was not persisted!'
|
|
4309
|
+
)
|
|
4310
|
+
}
|
|
4014
4311
|
} catch {
|
|
4015
4312
|
logger.logger.fail('Failed to complete logout steps')
|
|
4016
4313
|
}
|
|
4017
4314
|
}
|
|
4018
4315
|
|
|
4019
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4316
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$t } = constants
|
|
4020
4317
|
const config$w = {
|
|
4021
4318
|
commandName: 'logout',
|
|
4022
4319
|
description: 'Socket API logout',
|
|
@@ -4044,7 +4341,7 @@ async function run$w(argv, importMeta, { parentName }) {
|
|
|
4044
4341
|
parentName
|
|
4045
4342
|
})
|
|
4046
4343
|
if (cli.flags['dryRun']) {
|
|
4047
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4344
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$t)
|
|
4048
4345
|
return
|
|
4049
4346
|
}
|
|
4050
4347
|
attemptLogout()
|
|
@@ -4152,7 +4449,7 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
|
|
|
4152
4449
|
}
|
|
4153
4450
|
}
|
|
4154
4451
|
|
|
4155
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4452
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$s } = constants
|
|
4156
4453
|
const config$v = {
|
|
4157
4454
|
commandName: 'gradle',
|
|
4158
4455
|
description:
|
|
@@ -4299,7 +4596,7 @@ async function run$v(argv, importMeta, { parentName }) {
|
|
|
4299
4596
|
.filter(Boolean)
|
|
4300
4597
|
}
|
|
4301
4598
|
if (cli.flags['dryRun']) {
|
|
4302
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4599
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$s)
|
|
4303
4600
|
return
|
|
4304
4601
|
}
|
|
4305
4602
|
await convertGradleToMaven(target, bin, out, verbose, gradleOpts)
|
|
@@ -4408,7 +4705,7 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
|
|
|
4408
4705
|
}
|
|
4409
4706
|
}
|
|
4410
4707
|
|
|
4411
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4708
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$r } = constants
|
|
4412
4709
|
const config$u = {
|
|
4413
4710
|
commandName: 'scala',
|
|
4414
4711
|
description:
|
|
@@ -4553,13 +4850,13 @@ async function run$u(argv, importMeta, { parentName }) {
|
|
|
4553
4850
|
.filter(Boolean)
|
|
4554
4851
|
}
|
|
4555
4852
|
if (cli.flags['dryRun']) {
|
|
4556
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4853
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$r)
|
|
4557
4854
|
return
|
|
4558
4855
|
}
|
|
4559
4856
|
await convertSbtToMaven(target, bin, out, verbose, sbtOpts)
|
|
4560
4857
|
}
|
|
4561
4858
|
|
|
4562
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4859
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$q } = constants
|
|
4563
4860
|
const config$t = {
|
|
4564
4861
|
commandName: 'auto',
|
|
4565
4862
|
description: 'Auto-detect build and attempt to generate manifest file',
|
|
@@ -4625,7 +4922,7 @@ async function run$t(argv, importMeta, { parentName }) {
|
|
|
4625
4922
|
}
|
|
4626
4923
|
subArgs.push(dir)
|
|
4627
4924
|
if (cli.flags['dryRun']) {
|
|
4628
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4925
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$q)
|
|
4629
4926
|
return
|
|
4630
4927
|
}
|
|
4631
4928
|
await cmdManifestScala.run(subArgs, importMeta, {
|
|
@@ -4642,7 +4939,7 @@ async function run$t(argv, importMeta, { parentName }) {
|
|
|
4642
4939
|
subArgs.push(cwd)
|
|
4643
4940
|
}
|
|
4644
4941
|
if (cli.flags['dryRun']) {
|
|
4645
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4942
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$q)
|
|
4646
4943
|
return
|
|
4647
4944
|
}
|
|
4648
4945
|
await cmdManifestGradle.run(subArgs, importMeta, {
|
|
@@ -4651,7 +4948,7 @@ async function run$t(argv, importMeta, { parentName }) {
|
|
|
4651
4948
|
return
|
|
4652
4949
|
}
|
|
4653
4950
|
if (cli.flags['dryRun']) {
|
|
4654
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4951
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$q)
|
|
4655
4952
|
return
|
|
4656
4953
|
}
|
|
4657
4954
|
|
|
@@ -4678,7 +4975,7 @@ async function run$t(argv, importMeta, { parentName }) {
|
|
|
4678
4975
|
).showHelp()
|
|
4679
4976
|
}
|
|
4680
4977
|
|
|
4681
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4978
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$p } = constants
|
|
4682
4979
|
|
|
4683
4980
|
// TODO: we may want to dedupe some pieces for all gradle languages. I think it
|
|
4684
4981
|
// makes sense to have separate commands for them and I think it makes
|
|
@@ -4831,7 +5128,7 @@ async function run$s(argv, importMeta, { parentName }) {
|
|
|
4831
5128
|
.filter(Boolean)
|
|
4832
5129
|
}
|
|
4833
5130
|
if (cli.flags['dryRun']) {
|
|
4834
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
5131
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$p)
|
|
4835
5132
|
return
|
|
4836
5133
|
}
|
|
4837
5134
|
await convertGradleToMaven(target, bin, out, verbose, gradleOpts)
|
|
@@ -4882,7 +5179,7 @@ async function wrapNpm(argv) {
|
|
|
4882
5179
|
await shadowBin(NPM$8, argv)
|
|
4883
5180
|
}
|
|
4884
5181
|
|
|
4885
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
5182
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$o, NPM: NPM$7 } = constants
|
|
4886
5183
|
const config$q = {
|
|
4887
5184
|
commandName: 'npm',
|
|
4888
5185
|
description: `${NPM$7} wrapper functionality`,
|
|
@@ -4909,7 +5206,7 @@ async function run$q(argv, importMeta, { parentName }) {
|
|
|
4909
5206
|
parentName
|
|
4910
5207
|
})
|
|
4911
5208
|
if (cli.flags['dryRun']) {
|
|
4912
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
5209
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$o)
|
|
4913
5210
|
return
|
|
4914
5211
|
}
|
|
4915
5212
|
await wrapNpm(argv)
|
|
@@ -4922,7 +5219,7 @@ async function wrapNpx(argv) {
|
|
|
4922
5219
|
await shadowBin(NPX$2, argv)
|
|
4923
5220
|
}
|
|
4924
5221
|
|
|
4925
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
5222
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$n, NPX: NPX$1 } = constants
|
|
4926
5223
|
const config$p = {
|
|
4927
5224
|
commandName: 'npx',
|
|
4928
5225
|
description: `${NPX$1} wrapper functionality`,
|
|
@@ -4949,13 +5246,13 @@ async function run$p(argv, importMeta, { parentName }) {
|
|
|
4949
5246
|
parentName
|
|
4950
5247
|
})
|
|
4951
5248
|
if (cli.flags['dryRun']) {
|
|
4952
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
5249
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$n)
|
|
4953
5250
|
return
|
|
4954
5251
|
}
|
|
4955
5252
|
await wrapNpx(argv)
|
|
4956
5253
|
}
|
|
4957
5254
|
|
|
4958
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
5255
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$m } = constants
|
|
4959
5256
|
const config$o = {
|
|
4960
5257
|
commandName: 'oops',
|
|
4961
5258
|
description: 'Trigger an intentional error (for development)',
|
|
@@ -4983,7 +5280,7 @@ async function run$o(argv, importMeta, { parentName }) {
|
|
|
4983
5280
|
parentName
|
|
4984
5281
|
})
|
|
4985
5282
|
if (cli.flags['dryRun']) {
|
|
4986
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
5283
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$m)
|
|
4987
5284
|
return
|
|
4988
5285
|
}
|
|
4989
5286
|
throw new Error('This error was intentionally left blank')
|
|
@@ -5872,7 +6169,7 @@ async function applyOptimization(cwd, pin, prod) {
|
|
|
5872
6169
|
}
|
|
5873
6170
|
}
|
|
5874
6171
|
|
|
5875
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
6172
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$l } = constants
|
|
5876
6173
|
const config$n = {
|
|
5877
6174
|
commandName: 'optimize',
|
|
5878
6175
|
description: 'Optimize dependencies with @socketregistry overrides',
|
|
@@ -5916,7 +6213,7 @@ async function run$n(argv, importMeta, { parentName }) {
|
|
|
5916
6213
|
})
|
|
5917
6214
|
const cwd = process.cwd()
|
|
5918
6215
|
if (cli.flags['dryRun']) {
|
|
5919
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
6216
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$l)
|
|
5920
6217
|
return
|
|
5921
6218
|
}
|
|
5922
6219
|
await applyOptimization(
|
|
@@ -5939,7 +6236,6 @@ async function fetchOrganization() {
|
|
|
5939
6236
|
spinner.successAndStop('Received organization list response.')
|
|
5940
6237
|
if (!result.success) {
|
|
5941
6238
|
handleUnsuccessfulApiResponse('getOrganizations', result)
|
|
5942
|
-
return
|
|
5943
6239
|
}
|
|
5944
6240
|
return result.data
|
|
5945
6241
|
}
|
|
@@ -6018,7 +6314,7 @@ async function handleOrganizationList(outputKind = 'text') {
|
|
|
6018
6314
|
await outputOrganizationList(data, outputKind)
|
|
6019
6315
|
}
|
|
6020
6316
|
|
|
6021
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
6317
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$k } = constants
|
|
6022
6318
|
const config$m = {
|
|
6023
6319
|
commandName: 'list',
|
|
6024
6320
|
description: 'List organizations associated with the API key used',
|
|
@@ -6031,6 +6327,10 @@ const config$m = {
|
|
|
6031
6327
|
Usage
|
|
6032
6328
|
$ ${command}
|
|
6033
6329
|
|
|
6330
|
+
API Token Requirements
|
|
6331
|
+
- Quota: 1 unit
|
|
6332
|
+
- Permissions: none (does need a token)
|
|
6333
|
+
|
|
6034
6334
|
Options
|
|
6035
6335
|
${getFlagListOutput(config$m.flags, 6)}
|
|
6036
6336
|
`
|
|
@@ -6071,7 +6371,7 @@ async function run$m(argv, importMeta, { parentName }) {
|
|
|
6071
6371
|
return
|
|
6072
6372
|
}
|
|
6073
6373
|
if (cli.flags['dryRun']) {
|
|
6074
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
6374
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$k)
|
|
6075
6375
|
return
|
|
6076
6376
|
}
|
|
6077
6377
|
await handleOrganizationList(json ? 'json' : markdown ? 'markdown' : 'text')
|
|
@@ -6090,7 +6390,6 @@ async function fetchLicensePolicy(orgSlug) {
|
|
|
6090
6390
|
spinner.successAndStop('Received organization license policy response.')
|
|
6091
6391
|
if (!result.success) {
|
|
6092
6392
|
handleUnsuccessfulApiResponse('getOrgLicensePolicy', result)
|
|
6093
|
-
return
|
|
6094
6393
|
}
|
|
6095
6394
|
return result.data
|
|
6096
6395
|
}
|
|
@@ -6135,7 +6434,7 @@ async function handleLicensePolicy(orgSlug, outputKind) {
|
|
|
6135
6434
|
await outputLicensePolicy(data, outputKind)
|
|
6136
6435
|
}
|
|
6137
6436
|
|
|
6138
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
6437
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$j } = constants
|
|
6139
6438
|
|
|
6140
6439
|
// TODO: secret toplevel alias `socket license policy`?
|
|
6141
6440
|
const config$l = {
|
|
@@ -6150,6 +6449,10 @@ const config$l = {
|
|
|
6150
6449
|
Usage
|
|
6151
6450
|
$ ${command} <org slug>
|
|
6152
6451
|
|
|
6452
|
+
API Token Requirements
|
|
6453
|
+
- Quota: 1 unit
|
|
6454
|
+
- Permissions: license-policy:read
|
|
6455
|
+
|
|
6153
6456
|
Options
|
|
6154
6457
|
${getFlagListOutput(config$l.flags, 6)}
|
|
6155
6458
|
|
|
@@ -6206,7 +6509,7 @@ async function run$l(argv, importMeta, { parentName }) {
|
|
|
6206
6509
|
return
|
|
6207
6510
|
}
|
|
6208
6511
|
if (cli.flags['dryRun']) {
|
|
6209
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
6512
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$j)
|
|
6210
6513
|
return
|
|
6211
6514
|
}
|
|
6212
6515
|
await handleLicensePolicy(
|
|
@@ -6228,7 +6531,6 @@ async function fetchSecurityPolicy(orgSlug) {
|
|
|
6228
6531
|
spinner.successAndStop('Received organization security policy response.')
|
|
6229
6532
|
if (!result.success) {
|
|
6230
6533
|
handleUnsuccessfulApiResponse('getOrgSecurityPolicy', result)
|
|
6231
|
-
return
|
|
6232
6534
|
}
|
|
6233
6535
|
return result.data
|
|
6234
6536
|
}
|
|
@@ -6274,7 +6576,7 @@ async function handleSecurityPolicy(orgSlug, outputKind) {
|
|
|
6274
6576
|
await outputSecurityPolicy(data, outputKind)
|
|
6275
6577
|
}
|
|
6276
6578
|
|
|
6277
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
6579
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$i } = constants
|
|
6278
6580
|
|
|
6279
6581
|
// TODO: secret toplevel alias `socket security policy`?
|
|
6280
6582
|
const config$k = {
|
|
@@ -6289,6 +6591,10 @@ const config$k = {
|
|
|
6289
6591
|
Usage
|
|
6290
6592
|
$ ${command} <org slug>
|
|
6291
6593
|
|
|
6594
|
+
API Token Requirements
|
|
6595
|
+
- Quota: 1 unit
|
|
6596
|
+
- Permissions: security-policy:read
|
|
6597
|
+
|
|
6292
6598
|
Options
|
|
6293
6599
|
${getFlagListOutput(config$k.flags, 6)}
|
|
6294
6600
|
|
|
@@ -6345,7 +6651,7 @@ async function run$k(argv, importMeta, { parentName }) {
|
|
|
6345
6651
|
return
|
|
6346
6652
|
}
|
|
6347
6653
|
if (cli.flags['dryRun']) {
|
|
6348
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
6654
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$i)
|
|
6349
6655
|
return
|
|
6350
6656
|
}
|
|
6351
6657
|
await handleSecurityPolicy(
|
|
@@ -6393,7 +6699,6 @@ async function fetchQuota() {
|
|
|
6393
6699
|
spinner.successAndStop('Received organization quota response.')
|
|
6394
6700
|
if (!result.success) {
|
|
6395
6701
|
handleUnsuccessfulApiResponse('getQuota', result)
|
|
6396
|
-
return
|
|
6397
6702
|
}
|
|
6398
6703
|
return result.data
|
|
6399
6704
|
}
|
|
@@ -6432,7 +6737,7 @@ async function handleQuota(outputKind = 'text') {
|
|
|
6432
6737
|
await outputQuota(data, outputKind)
|
|
6433
6738
|
}
|
|
6434
6739
|
|
|
6435
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
6740
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$h } = constants
|
|
6436
6741
|
const config$j = {
|
|
6437
6742
|
commandName: 'quota',
|
|
6438
6743
|
description: 'List organizations associated with the API key used',
|
|
@@ -6485,7 +6790,7 @@ async function run$j(argv, importMeta, { parentName }) {
|
|
|
6485
6790
|
return
|
|
6486
6791
|
}
|
|
6487
6792
|
if (cli.flags['dryRun']) {
|
|
6488
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
6793
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$h)
|
|
6489
6794
|
return
|
|
6490
6795
|
}
|
|
6491
6796
|
await handleQuota(json ? 'json' : markdown ? 'markdown' : 'text')
|
|
@@ -6518,6 +6823,7 @@ const cmdOrganization = {
|
|
|
6518
6823
|
}
|
|
6519
6824
|
}
|
|
6520
6825
|
|
|
6826
|
+
const { SOCKET_CLI_ISSUES_URL } = constants
|
|
6521
6827
|
async function fetchPurlDeepScore(purl) {
|
|
6522
6828
|
const apiToken = shadowNpmInject.getDefaultToken()
|
|
6523
6829
|
if (!apiToken) {
|
|
@@ -6559,7 +6865,7 @@ async function fetchPurlDeepScore(purl) {
|
|
|
6559
6865
|
return JSON.parse(data)
|
|
6560
6866
|
} catch (e) {
|
|
6561
6867
|
throw new Error(
|
|
6562
|
-
|
|
6868
|
+
`Unable to parse JSON response from the Socket API.\nPlease report to ${SOCKET_CLI_ISSUES_URL}`
|
|
6563
6869
|
)
|
|
6564
6870
|
}
|
|
6565
6871
|
}
|
|
@@ -6752,7 +7058,7 @@ async function outputPurlScore(purl, data, outputKind) {
|
|
|
6752
7058
|
)
|
|
6753
7059
|
} else {
|
|
6754
7060
|
logger.logger.log(
|
|
6755
|
-
'This package had no alerts and neither did any of its direct/transitive dependencies
|
|
7061
|
+
'This package had no alerts and neither did any of its direct/transitive dependencies'
|
|
6756
7062
|
)
|
|
6757
7063
|
}
|
|
6758
7064
|
logger.logger.log('')
|
|
@@ -6827,7 +7133,7 @@ function parsePackageSpecifiers(ecosystem, pkgs) {
|
|
|
6827
7133
|
}
|
|
6828
7134
|
}
|
|
6829
7135
|
|
|
6830
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
7136
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$g } = constants
|
|
6831
7137
|
const config$i = {
|
|
6832
7138
|
commandName: 'score',
|
|
6833
7139
|
description:
|
|
@@ -6841,13 +7147,13 @@ const config$i = {
|
|
|
6841
7147
|
Usage
|
|
6842
7148
|
$ ${command} <<ecosystem> <name> | <purl>>
|
|
6843
7149
|
|
|
7150
|
+
API Token Requirements
|
|
7151
|
+
- Quota: 100 units
|
|
7152
|
+
- Permissions: packages:list
|
|
7153
|
+
|
|
6844
7154
|
Options
|
|
6845
7155
|
${getFlagListOutput(config.flags, 6)}
|
|
6846
7156
|
|
|
6847
|
-
Requirements
|
|
6848
|
-
- quota: 100
|
|
6849
|
-
- scope: \`packages:list\`
|
|
6850
|
-
|
|
6851
7157
|
Show deep scoring details for one package. The score will reflect the package
|
|
6852
7158
|
itself, any of its dependencies, and any of its transitive dependencies.
|
|
6853
7159
|
|
|
@@ -6919,7 +7225,7 @@ async function run$i(argv, importMeta, { parentName }) {
|
|
|
6919
7225
|
return
|
|
6920
7226
|
}
|
|
6921
7227
|
if (cli.flags['dryRun']) {
|
|
6922
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
7228
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$g)
|
|
6923
7229
|
return
|
|
6924
7230
|
}
|
|
6925
7231
|
await handlePurlDeepScore(
|
|
@@ -6943,10 +7249,6 @@ async function fetchPurlsShallowScore(purls) {
|
|
|
6943
7249
|
sockSdk.batchPackageFetch(
|
|
6944
7250
|
{
|
|
6945
7251
|
alerts: 'true'
|
|
6946
|
-
// compact: false,
|
|
6947
|
-
// fixable: false,
|
|
6948
|
-
// licenseattrib: false,
|
|
6949
|
-
// licensedetails: false
|
|
6950
7252
|
},
|
|
6951
7253
|
{
|
|
6952
7254
|
components: purls.map(purl => ({
|
|
@@ -6959,7 +7261,6 @@ async function fetchPurlsShallowScore(purls) {
|
|
|
6959
7261
|
spinner.successAndStop('Request completed')
|
|
6960
7262
|
if (!result.success) {
|
|
6961
7263
|
handleUnsuccessfulApiResponse('batchPackageFetch', result)
|
|
6962
|
-
return
|
|
6963
7264
|
}
|
|
6964
7265
|
return result
|
|
6965
7266
|
}
|
|
@@ -7116,7 +7417,7 @@ async function handlePurlsShallowScore({ outputKind, purls }) {
|
|
|
7116
7417
|
outputPurlsShallowScore(purls, packageData.data, outputKind)
|
|
7117
7418
|
}
|
|
7118
7419
|
|
|
7119
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
7420
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$f } = constants
|
|
7120
7421
|
const config$h = {
|
|
7121
7422
|
commandName: 'shallow',
|
|
7122
7423
|
description:
|
|
@@ -7130,13 +7431,13 @@ const config$h = {
|
|
|
7130
7431
|
Usage
|
|
7131
7432
|
$ ${command} <<ecosystem> <name> [<name> ...] | <purl> [<purl> ...]>
|
|
7132
7433
|
|
|
7434
|
+
API Token Requirements
|
|
7435
|
+
- Quota: 100 units
|
|
7436
|
+
- Permissions: packages:list
|
|
7437
|
+
|
|
7133
7438
|
Options
|
|
7134
7439
|
${getFlagListOutput(config.flags, 6)}
|
|
7135
7440
|
|
|
7136
|
-
Requirements
|
|
7137
|
-
- quota: 100
|
|
7138
|
-
- scope: \`packages:list\`
|
|
7139
|
-
|
|
7140
7441
|
Show scoring details for one or more packages purely based on their own package.
|
|
7141
7442
|
This means that any dependency scores are not reflected by the score. You can
|
|
7142
7443
|
use the \`socket package score <pkg>\` command to get its full transitive score.
|
|
@@ -7207,7 +7508,7 @@ async function run$h(argv, importMeta, { parentName }) {
|
|
|
7207
7508
|
return
|
|
7208
7509
|
}
|
|
7209
7510
|
if (cli.flags['dryRun']) {
|
|
7210
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
7511
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$f)
|
|
7211
7512
|
return
|
|
7212
7513
|
}
|
|
7213
7514
|
await handlePurlsShallowScore({
|
|
@@ -7260,7 +7561,7 @@ async function runRawNpm(argv) {
|
|
|
7260
7561
|
await spawnPromise
|
|
7261
7562
|
}
|
|
7262
7563
|
|
|
7263
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
7564
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$e, NPM } = constants
|
|
7264
7565
|
const config$g = {
|
|
7265
7566
|
commandName: 'raw-npm',
|
|
7266
7567
|
description: `Temporarily disable the Socket ${NPM} wrapper`,
|
|
@@ -7288,7 +7589,7 @@ async function run$g(argv, importMeta, { parentName }) {
|
|
|
7288
7589
|
parentName
|
|
7289
7590
|
})
|
|
7290
7591
|
if (cli.flags['dryRun']) {
|
|
7291
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
7592
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$e)
|
|
7292
7593
|
return
|
|
7293
7594
|
}
|
|
7294
7595
|
await runRawNpm(argv)
|
|
@@ -7310,7 +7611,7 @@ async function runRawNpx(argv) {
|
|
|
7310
7611
|
await spawnPromise
|
|
7311
7612
|
}
|
|
7312
7613
|
|
|
7313
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
7614
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$d, NPX } = constants
|
|
7314
7615
|
const config$f = {
|
|
7315
7616
|
commandName: 'raw-npx',
|
|
7316
7617
|
description: `Temporarily disable the Socket ${NPX} wrapper`,
|
|
@@ -7338,242 +7639,12 @@ async function run$f(argv, importMeta, { parentName }) {
|
|
|
7338
7639
|
parentName
|
|
7339
7640
|
})
|
|
7340
7641
|
if (cli.flags['dryRun']) {
|
|
7341
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
7642
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$d)
|
|
7342
7643
|
return
|
|
7343
7644
|
}
|
|
7344
7645
|
await runRawNpx(argv)
|
|
7345
7646
|
}
|
|
7346
7647
|
|
|
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
7648
|
const config$e = {
|
|
7578
7649
|
commandName: 'create',
|
|
7579
7650
|
description: '[Deprecated] Create a project report',
|
|
@@ -7605,57 +7676,17 @@ const cmdReportCreate = {
|
|
|
7605
7676
|
run: run$e
|
|
7606
7677
|
}
|
|
7607
7678
|
async function run$e(argv, importMeta, { parentName }) {
|
|
7608
|
-
|
|
7679
|
+
meowOrExit({
|
|
7609
7680
|
argv,
|
|
7610
7681
|
config: config$e,
|
|
7611
7682
|
importMeta,
|
|
7612
7683
|
parentName
|
|
7613
7684
|
})
|
|
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
|
-
}
|
|
7685
|
+
logger.logger.fail(
|
|
7686
|
+
'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.'
|
|
7687
|
+
)
|
|
7656
7688
|
}
|
|
7657
7689
|
|
|
7658
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$d } = constants
|
|
7659
7690
|
const config$d = {
|
|
7660
7691
|
commandName: 'view',
|
|
7661
7692
|
description: '[Deprecated] View a project report',
|
|
@@ -7676,49 +7707,15 @@ const cmdReportView = {
|
|
|
7676
7707
|
run: run$d
|
|
7677
7708
|
}
|
|
7678
7709
|
async function run$d(argv, importMeta, { parentName }) {
|
|
7679
|
-
|
|
7710
|
+
meowOrExit({
|
|
7680
7711
|
argv,
|
|
7681
7712
|
config: config$d,
|
|
7682
7713
|
importMeta,
|
|
7683
7714
|
parentName
|
|
7684
7715
|
})
|
|
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
|
-
}
|
|
7716
|
+
logger.logger.fail(
|
|
7717
|
+
'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
7718
|
)
|
|
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
7719
|
}
|
|
7723
7720
|
|
|
7724
7721
|
const description$2 = '[Deprecated] Project report related commands'
|
|
@@ -7768,7 +7765,6 @@ async function fetchCreateRepo({
|
|
|
7768
7765
|
spinner.successAndStop('Received response requesting to create a repository.')
|
|
7769
7766
|
if (!result.success) {
|
|
7770
7767
|
handleUnsuccessfulApiResponse('createOrgRepo', result)
|
|
7771
|
-
return
|
|
7772
7768
|
}
|
|
7773
7769
|
return result.data
|
|
7774
7770
|
}
|
|
@@ -7841,6 +7837,10 @@ const config$c = {
|
|
|
7841
7837
|
Usage
|
|
7842
7838
|
$ ${command} <org slug>
|
|
7843
7839
|
|
|
7840
|
+
API Token Requirements
|
|
7841
|
+
- Quota: 1 unit
|
|
7842
|
+
- Permissions: repo:create
|
|
7843
|
+
|
|
7844
7844
|
Options
|
|
7845
7845
|
${getFlagListOutput(config.flags, 6)}
|
|
7846
7846
|
|
|
@@ -7916,7 +7916,6 @@ async function handleDeleteRepo(orgSlug, repoName) {
|
|
|
7916
7916
|
)
|
|
7917
7917
|
if (!result.success) {
|
|
7918
7918
|
handleUnsuccessfulApiResponse('deleteOrgRepo', result)
|
|
7919
|
-
return
|
|
7920
7919
|
}
|
|
7921
7920
|
spinner.successAndStop('Repository deleted successfully')
|
|
7922
7921
|
}
|
|
@@ -7933,6 +7932,10 @@ const config$b = {
|
|
|
7933
7932
|
Usage
|
|
7934
7933
|
$ ${command} <org slug> <repo slug>
|
|
7935
7934
|
|
|
7935
|
+
API Token Requirements
|
|
7936
|
+
- Quota: 1 unit
|
|
7937
|
+
- Permissions: repo:delete
|
|
7938
|
+
|
|
7936
7939
|
Options
|
|
7937
7940
|
${getFlagListOutput(config.flags, 6)}
|
|
7938
7941
|
|
|
@@ -8007,7 +8010,6 @@ async function fetchListRepos({ direction, orgSlug, page, per_page, sort }) {
|
|
|
8007
8010
|
spinner.successAndStop('Received response for repository list.')
|
|
8008
8011
|
if (!result.success) {
|
|
8009
8012
|
handleUnsuccessfulApiResponse('getOrgRepoList', result)
|
|
8010
|
-
return
|
|
8011
8013
|
}
|
|
8012
8014
|
return result.data
|
|
8013
8015
|
}
|
|
@@ -8109,6 +8111,10 @@ const config$a = {
|
|
|
8109
8111
|
Usage
|
|
8110
8112
|
$ ${command} <org slug>
|
|
8111
8113
|
|
|
8114
|
+
API Token Requirements
|
|
8115
|
+
- Quota: 1 unit
|
|
8116
|
+
- Permissions: repo:list
|
|
8117
|
+
|
|
8112
8118
|
Options
|
|
8113
8119
|
${getFlagListOutput(config.flags, 6)}
|
|
8114
8120
|
|
|
@@ -8201,7 +8207,6 @@ async function fetchUpdateRepo({
|
|
|
8201
8207
|
spinner.successAndStop('Received response trying to update a repository')
|
|
8202
8208
|
if (!result.success) {
|
|
8203
8209
|
handleUnsuccessfulApiResponse('updateOrgRepo', result)
|
|
8204
|
-
return
|
|
8205
8210
|
}
|
|
8206
8211
|
return result.data
|
|
8207
8212
|
}
|
|
@@ -8274,6 +8279,10 @@ const config$9 = {
|
|
|
8274
8279
|
Usage
|
|
8275
8280
|
$ ${command} <org slug>
|
|
8276
8281
|
|
|
8282
|
+
API Token Requirements
|
|
8283
|
+
- Quota: 1 unit
|
|
8284
|
+
- Permissions: repo:update
|
|
8285
|
+
|
|
8277
8286
|
Options
|
|
8278
8287
|
${getFlagListOutput(config.flags, 6)}
|
|
8279
8288
|
|
|
@@ -8350,7 +8359,6 @@ async function fetchViewRepo(orgSlug, repoName) {
|
|
|
8350
8359
|
spinner.successAndStop('Received response while fetched repository data.')
|
|
8351
8360
|
if (!result.success) {
|
|
8352
8361
|
handleUnsuccessfulApiResponse('getOrgRepo', result)
|
|
8353
|
-
return
|
|
8354
8362
|
}
|
|
8355
8363
|
return result.data
|
|
8356
8364
|
}
|
|
@@ -8445,6 +8453,10 @@ const config$8 = {
|
|
|
8445
8453
|
Usage
|
|
8446
8454
|
$ ${command} <org slug>
|
|
8447
8455
|
|
|
8456
|
+
API Token Requirements
|
|
8457
|
+
- Quota: 1 unit
|
|
8458
|
+
- Permissions: repo:list
|
|
8459
|
+
|
|
8448
8460
|
Options
|
|
8449
8461
|
${getFlagListOutput(config.flags, 6)}
|
|
8450
8462
|
|
|
@@ -8550,7 +8562,9 @@ async function fetchCreateOrgFullScan(
|
|
|
8550
8562
|
|
|
8551
8563
|
// Lazily access constants.spinner.
|
|
8552
8564
|
const { spinner } = constants
|
|
8553
|
-
spinner.start(
|
|
8565
|
+
spinner.start(
|
|
8566
|
+
`Sending request to create a scan with ${packagePaths.length} packages...`
|
|
8567
|
+
)
|
|
8554
8568
|
const result = await handleApiCall(
|
|
8555
8569
|
sockSdk.createOrgFullScan(
|
|
8556
8570
|
orgSlug,
|
|
@@ -8567,10 +8581,9 @@ async function fetchCreateOrgFullScan(
|
|
|
8567
8581
|
),
|
|
8568
8582
|
'Creating scan'
|
|
8569
8583
|
)
|
|
8570
|
-
spinner.successAndStop('
|
|
8584
|
+
spinner.successAndStop('Completed request to create a new scan.')
|
|
8571
8585
|
if (!result.success) {
|
|
8572
8586
|
handleUnsuccessfulApiResponse('CreateOrgFullScan', result)
|
|
8573
|
-
return
|
|
8574
8587
|
}
|
|
8575
8588
|
return result.data
|
|
8576
8589
|
}
|
|
@@ -8585,12 +8598,12 @@ async function fetchSupportedScanFileNames() {
|
|
|
8585
8598
|
sockSdk.getReportSupportedFiles(),
|
|
8586
8599
|
'fetching supported scan file types'
|
|
8587
8600
|
)
|
|
8588
|
-
spinner.
|
|
8601
|
+
spinner.stop()
|
|
8602
|
+
logger.logger.success(
|
|
8589
8603
|
'Received response while fetched supported scan file types.'
|
|
8590
8604
|
)
|
|
8591
8605
|
if (!result.success) {
|
|
8592
8606
|
handleUnsuccessfulApiResponse('getReportSupportedFiles', result)
|
|
8593
|
-
return
|
|
8594
8607
|
}
|
|
8595
8608
|
return result.data
|
|
8596
8609
|
}
|
|
@@ -8628,7 +8641,6 @@ async function handleCreateNewScan({
|
|
|
8628
8641
|
cwd,
|
|
8629
8642
|
targets,
|
|
8630
8643
|
supportedFileNames
|
|
8631
|
-
// socketConfig
|
|
8632
8644
|
)
|
|
8633
8645
|
handleBadInput({
|
|
8634
8646
|
nook: true,
|
|
@@ -8692,7 +8704,7 @@ async function suggestOrgSlug() {
|
|
|
8692
8704
|
}
|
|
8693
8705
|
} else {
|
|
8694
8706
|
logger.logger.fail(
|
|
8695
|
-
'Failed to lookup organization list from API, unable to suggest
|
|
8707
|
+
'Failed to lookup organization list from API, unable to suggest'
|
|
8696
8708
|
)
|
|
8697
8709
|
}
|
|
8698
8710
|
}
|
|
@@ -8947,6 +8959,10 @@ const config$7 = {
|
|
|
8947
8959
|
Usage
|
|
8948
8960
|
$ ${command} [...options] <org> <TARGET> [TARGET...]
|
|
8949
8961
|
|
|
8962
|
+
API Token Requirements
|
|
8963
|
+
- Quota: 1 unit
|
|
8964
|
+
- Permissions: full-scans:create
|
|
8965
|
+
|
|
8950
8966
|
Uploads the specified "package.json" and lock files for JavaScript, Python,
|
|
8951
8967
|
Go, Scala, Gradle, and Kotlin dependency manifests.
|
|
8952
8968
|
If any folder is specified, the ones found in there recursively are uploaded.
|
|
@@ -8988,7 +9004,7 @@ async function run$7(argv, importMeta, { parentName }) {
|
|
|
8988
9004
|
cwdOverride && cwdOverride !== 'process.cwd()'
|
|
8989
9005
|
? String(cwdOverride)
|
|
8990
9006
|
: process.cwd()
|
|
8991
|
-
let { branch: branchName, repo: repoName } = cli.flags
|
|
9007
|
+
let { branch: branchName = '', repo: repoName = '' } = cli.flags
|
|
8992
9008
|
|
|
8993
9009
|
// We're going to need an api token to suggest data because those suggestions
|
|
8994
9010
|
// must come from data we already know. Don't error on missing api token yet.
|
|
@@ -9116,7 +9132,6 @@ async function fetchDeleteOrgFullScan(orgSlug, scanId) {
|
|
|
9116
9132
|
spinner.successAndStop('Received response for deleting a scan.')
|
|
9117
9133
|
if (!result.success) {
|
|
9118
9134
|
handleUnsuccessfulApiResponse('deleteOrgFullScan', result)
|
|
9119
|
-
return
|
|
9120
9135
|
}
|
|
9121
9136
|
return result.data
|
|
9122
9137
|
}
|
|
@@ -9146,6 +9161,10 @@ const config$6 = {
|
|
|
9146
9161
|
Usage
|
|
9147
9162
|
$ ${command} <org slug> <scan ID>
|
|
9148
9163
|
|
|
9164
|
+
API Token Requirements
|
|
9165
|
+
- Quota: 1 unit
|
|
9166
|
+
- Permissions: full-scans:delete
|
|
9167
|
+
|
|
9149
9168
|
Options
|
|
9150
9169
|
${getFlagListOutput(config.flags, 6)}
|
|
9151
9170
|
|
|
@@ -9228,7 +9247,6 @@ async function fetchListScans({
|
|
|
9228
9247
|
spinner.successAndStop(`Received response for list of scans.`)
|
|
9229
9248
|
if (!result.success) {
|
|
9230
9249
|
handleUnsuccessfulApiResponse('getOrgFullScanList', result)
|
|
9231
|
-
return
|
|
9232
9250
|
}
|
|
9233
9251
|
return result.data
|
|
9234
9252
|
}
|
|
@@ -9349,6 +9367,10 @@ const config$5 = {
|
|
|
9349
9367
|
Usage
|
|
9350
9368
|
$ ${command} <org slug>
|
|
9351
9369
|
|
|
9370
|
+
API Token Requirements
|
|
9371
|
+
- Quota: 1 unit
|
|
9372
|
+
- Permissions: full-scans:list
|
|
9373
|
+
|
|
9352
9374
|
Options
|
|
9353
9375
|
${getFlagListOutput(config.flags, 6)}
|
|
9354
9376
|
|
|
@@ -9427,7 +9449,6 @@ async function fetchScanMetadata(orgSlug, scanId) {
|
|
|
9427
9449
|
spinner.successAndStop('Received response for scan meta data.')
|
|
9428
9450
|
if (!result.success) {
|
|
9429
9451
|
handleUnsuccessfulApiResponse('getOrgFullScanMetadata', result)
|
|
9430
|
-
return
|
|
9431
9452
|
}
|
|
9432
9453
|
return result.data
|
|
9433
9454
|
}
|
|
@@ -9489,6 +9510,10 @@ const config$4 = {
|
|
|
9489
9510
|
Usage
|
|
9490
9511
|
$ ${command} <org slug> <scan id>
|
|
9491
9512
|
|
|
9513
|
+
API Token Requirements
|
|
9514
|
+
- Quota: 1 unit
|
|
9515
|
+
- Permissions: full-scans:list
|
|
9516
|
+
|
|
9492
9517
|
Options
|
|
9493
9518
|
${getFlagListOutput(config.flags, 6)}
|
|
9494
9519
|
|
|
@@ -9560,14 +9585,8 @@ async function run$4(argv, importMeta, { parentName }) {
|
|
|
9560
9585
|
/**
|
|
9561
9586
|
* This fetches all the relevant pieces of data to generate a report, given a
|
|
9562
9587
|
* full scan ID.
|
|
9563
|
-
* It can optionally only fetch the security or license side of things.
|
|
9564
9588
|
*/
|
|
9565
|
-
async function fetchReportData(
|
|
9566
|
-
orgSlug,
|
|
9567
|
-
scanId,
|
|
9568
|
-
// includeLicensePolicy: boolean,
|
|
9569
|
-
includeSecurityPolicy
|
|
9570
|
-
) {
|
|
9589
|
+
async function fetchReportData(orgSlug, scanId, includeLicensePolicy) {
|
|
9571
9590
|
const apiToken = shadowNpmInject.getDefaultToken()
|
|
9572
9591
|
if (!apiToken) {
|
|
9573
9592
|
throw new shadowNpmInject.AuthError(
|
|
@@ -9576,7 +9595,6 @@ async function fetchReportData(
|
|
|
9576
9595
|
}
|
|
9577
9596
|
const sockSdk = await shadowNpmInject.setupSdk(apiToken)
|
|
9578
9597
|
let haveScan = false
|
|
9579
|
-
// let haveLicensePolicy = false
|
|
9580
9598
|
let haveSecurityPolicy = false
|
|
9581
9599
|
|
|
9582
9600
|
// Lazily access constants.spinner.
|
|
@@ -9584,48 +9602,26 @@ async function fetchReportData(
|
|
|
9584
9602
|
function updateProgress() {
|
|
9585
9603
|
const needs = [
|
|
9586
9604
|
!haveScan ? 'scan' : undefined,
|
|
9587
|
-
|
|
9588
|
-
includeSecurityPolicy && !haveSecurityPolicy
|
|
9589
|
-
? 'security policy'
|
|
9590
|
-
: undefined
|
|
9605
|
+
!haveSecurityPolicy ? 'security policy' : undefined
|
|
9591
9606
|
].filter(Boolean)
|
|
9592
|
-
if (needs.length > 2) {
|
|
9593
|
-
// .toOxford()
|
|
9594
|
-
needs[needs.length - 1] = `and ${needs[needs.length - 1]}`
|
|
9595
|
-
}
|
|
9596
9607
|
const haves = [
|
|
9597
9608
|
haveScan ? 'scan' : undefined,
|
|
9598
|
-
|
|
9599
|
-
includeSecurityPolicy && haveSecurityPolicy
|
|
9600
|
-
? 'security policy'
|
|
9601
|
-
: undefined
|
|
9609
|
+
haveSecurityPolicy ? 'security policy' : undefined
|
|
9602
9610
|
].filter(Boolean)
|
|
9603
|
-
if (haves.length > 2) {
|
|
9604
|
-
// .toOxford()
|
|
9605
|
-
haves[haves.length - 1] = `and ${haves[haves.length - 1]}`
|
|
9606
|
-
}
|
|
9607
9611
|
if (needs.length) {
|
|
9608
9612
|
spinner.start(
|
|
9609
|
-
`Fetching ${needs.join(
|
|
9613
|
+
`Fetching ${needs.join(' and ')}...${haves.length ? ` Completed fetching ${haves.join(' and ')}.` : ''}`
|
|
9610
9614
|
)
|
|
9611
9615
|
} else {
|
|
9612
|
-
spinner.successAndStop(
|
|
9613
|
-
`Completed fetching ${haves.join(haves.length > 2 ? ', ' : ' and ')}.`
|
|
9614
|
-
)
|
|
9616
|
+
spinner.successAndStop(`Completed fetching ${haves.join(' and ')}.`)
|
|
9615
9617
|
}
|
|
9616
9618
|
}
|
|
9617
9619
|
updateProgress()
|
|
9618
|
-
|
|
9619
|
-
// @ts-ignore
|
|
9620
|
-
const [
|
|
9621
|
-
scan,
|
|
9622
|
-
// licensePolicyMaybe,
|
|
9623
|
-
securityPolicyMaybe
|
|
9624
|
-
] = await Promise.all([
|
|
9620
|
+
const [scan, securityPolicyMaybe] = await Promise.all([
|
|
9625
9621
|
(async () => {
|
|
9626
9622
|
try {
|
|
9627
9623
|
const response = await queryApi(
|
|
9628
|
-
`orgs/${orgSlug}/full-scans/${encodeURIComponent(scanId)}`,
|
|
9624
|
+
`orgs/${orgSlug}/full-scans/${encodeURIComponent(scanId)}${includeLicensePolicy ? '?include_license_details=true' : ''}`,
|
|
9629
9625
|
apiToken
|
|
9630
9626
|
)
|
|
9631
9627
|
haveScan = true
|
|
@@ -9651,32 +9647,16 @@ async function fetchReportData(
|
|
|
9651
9647
|
})
|
|
9652
9648
|
return data
|
|
9653
9649
|
} catch (e) {
|
|
9654
|
-
spinner.errorAndStop(
|
|
9655
|
-
'There was an issue while fetching full scan data.'
|
|
9656
|
-
)
|
|
9650
|
+
spinner.errorAndStop('There was an issue while fetching full scan data')
|
|
9657
9651
|
throw e
|
|
9658
9652
|
}
|
|
9659
9653
|
})(),
|
|
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
|
-
})()
|
|
9654
|
+
(async () => {
|
|
9655
|
+
const r = await sockSdk.getOrgSecurityPolicy(orgSlug)
|
|
9656
|
+
haveSecurityPolicy = true
|
|
9657
|
+
updateProgress()
|
|
9658
|
+
return await handleApiCall(r, "looking up organization's security policy")
|
|
9659
|
+
})()
|
|
9680
9660
|
]).finally(() => spinner.stop())
|
|
9681
9661
|
if (!Array.isArray(scan)) {
|
|
9682
9662
|
logger.logger.error('Was unable to fetch scan, bailing')
|
|
@@ -9684,55 +9664,30 @@ async function fetchReportData(
|
|
|
9684
9664
|
return {
|
|
9685
9665
|
ok: false,
|
|
9686
9666
|
scan: undefined,
|
|
9687
|
-
// licensePolicy: undefined,
|
|
9688
9667
|
securityPolicy: undefined
|
|
9689
9668
|
}
|
|
9690
9669
|
}
|
|
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
9670
|
let securityPolicy = undefined
|
|
9711
|
-
if (
|
|
9712
|
-
|
|
9713
|
-
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
|
|
9718
|
-
|
|
9719
|
-
|
|
9720
|
-
// licensePolicy: undefined,
|
|
9721
|
-
securityPolicy: undefined
|
|
9722
|
-
}
|
|
9671
|
+
if (securityPolicyMaybe && securityPolicyMaybe.success) {
|
|
9672
|
+
securityPolicy = securityPolicyMaybe
|
|
9673
|
+
} else {
|
|
9674
|
+
logger.logger.error('Was unable to fetch security policy, bailing')
|
|
9675
|
+
process.exitCode = 1
|
|
9676
|
+
return {
|
|
9677
|
+
ok: false,
|
|
9678
|
+
scan: undefined,
|
|
9679
|
+
securityPolicy: undefined
|
|
9723
9680
|
}
|
|
9724
9681
|
}
|
|
9725
9682
|
return {
|
|
9726
9683
|
ok: true,
|
|
9727
9684
|
scan,
|
|
9728
|
-
// licensePolicy,
|
|
9729
9685
|
securityPolicy
|
|
9730
9686
|
}
|
|
9731
9687
|
}
|
|
9732
9688
|
|
|
9733
9689
|
function generateReport(
|
|
9734
9690
|
scan,
|
|
9735
|
-
_licensePolicy,
|
|
9736
9691
|
securityPolicy,
|
|
9737
9692
|
{ fold, orgSlug, reportLevel, scanId, short, spinner }
|
|
9738
9693
|
) {
|
|
@@ -9758,6 +9713,14 @@ function generateReport(
|
|
|
9758
9713
|
// - monitor/ignore: no action
|
|
9759
9714
|
// - defer: unknown (no action)
|
|
9760
9715
|
|
|
9716
|
+
// Note: the server will emit alerts for license policy violations but
|
|
9717
|
+
// those are only included if you set the flag when requesting the scan
|
|
9718
|
+
// data. The alerts map to a single security policy key that determines
|
|
9719
|
+
// what to do with any violation, regardless of the concrete license.
|
|
9720
|
+
// That rule is called "License Policy Violation".
|
|
9721
|
+
// The license policy part is implicitly handled here. Either they are
|
|
9722
|
+
// included and may show up, or they are not and won't show up.
|
|
9723
|
+
|
|
9761
9724
|
const violations = new Map()
|
|
9762
9725
|
let healthy = true
|
|
9763
9726
|
const securityRules = securityPolicy?.data.securityPolicyRules
|
|
@@ -10004,13 +9967,11 @@ function* walkNestedMap(map, keys = []) {
|
|
|
10004
9967
|
|
|
10005
9968
|
async function outputScanReport(
|
|
10006
9969
|
scan,
|
|
10007
|
-
// licensePolicy: undefined | SocketSdkReturnType<'getOrgSecurityPolicy'>,
|
|
10008
9970
|
securityPolicy,
|
|
10009
9971
|
{
|
|
10010
9972
|
filePath,
|
|
10011
9973
|
fold,
|
|
10012
9974
|
includeLicensePolicy,
|
|
10013
|
-
includeSecurityPolicy,
|
|
10014
9975
|
orgSlug,
|
|
10015
9976
|
outputKind,
|
|
10016
9977
|
reportLevel,
|
|
@@ -10018,25 +9979,15 @@ async function outputScanReport(
|
|
|
10018
9979
|
short
|
|
10019
9980
|
}
|
|
10020
9981
|
) {
|
|
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
|
-
)
|
|
9982
|
+
const scanReport = generateReport(scan, securityPolicy, {
|
|
9983
|
+
orgSlug,
|
|
9984
|
+
scanId,
|
|
9985
|
+
fold,
|
|
9986
|
+
reportLevel,
|
|
9987
|
+
short,
|
|
9988
|
+
// Lazily access constants.spinner.
|
|
9989
|
+
spinner: constants.spinner
|
|
9990
|
+
})
|
|
10040
9991
|
if (!scanReport.healthy) {
|
|
10041
9992
|
process.exitCode = 1
|
|
10042
9993
|
}
|
|
@@ -10044,7 +9995,9 @@ async function outputScanReport(
|
|
|
10044
9995
|
outputKind === 'json' ||
|
|
10045
9996
|
(outputKind === 'text' && filePath && filePath.endsWith('.json'))
|
|
10046
9997
|
) {
|
|
10047
|
-
const json = short
|
|
9998
|
+
const json = short
|
|
9999
|
+
? JSON.stringify(scanReport)
|
|
10000
|
+
: toJsonReport(scanReport, includeLicensePolicy)
|
|
10048
10001
|
if (filePath !== '-') {
|
|
10049
10002
|
logger.logger.log('Writing json report to', filePath)
|
|
10050
10003
|
return await fs.writeFile(filePath, json)
|
|
@@ -10055,7 +10008,7 @@ async function outputScanReport(
|
|
|
10055
10008
|
if (outputKind === 'markdown' || filePath.endsWith('.md')) {
|
|
10056
10009
|
const md = short
|
|
10057
10010
|
? `healthy = ${scanReport.healthy}`
|
|
10058
|
-
: toMarkdownReport(scanReport)
|
|
10011
|
+
: toMarkdownReport(scanReport, includeLicensePolicy)
|
|
10059
10012
|
if (filePath !== '-') {
|
|
10060
10013
|
logger.logger.log('Writing markdown report to', filePath)
|
|
10061
10014
|
return await fs.writeFile(filePath, md)
|
|
@@ -10071,10 +10024,11 @@ async function outputScanReport(
|
|
|
10071
10024
|
})
|
|
10072
10025
|
}
|
|
10073
10026
|
}
|
|
10074
|
-
function toJsonReport(report) {
|
|
10027
|
+
function toJsonReport(report, includeLicensePolicy) {
|
|
10075
10028
|
const obj = mapToObject(report.alerts)
|
|
10076
10029
|
const json = JSON.stringify(
|
|
10077
10030
|
{
|
|
10031
|
+
includeLicensePolicy,
|
|
10078
10032
|
...report,
|
|
10079
10033
|
alerts: obj
|
|
10080
10034
|
},
|
|
@@ -10083,7 +10037,7 @@ function toJsonReport(report) {
|
|
|
10083
10037
|
)
|
|
10084
10038
|
return json
|
|
10085
10039
|
}
|
|
10086
|
-
function toMarkdownReport(report) {
|
|
10040
|
+
function toMarkdownReport(report, includeLicensePolicy) {
|
|
10087
10041
|
const flatData = Array.from(walkNestedMap(report.alerts)).map(
|
|
10088
10042
|
({ keys, value }) => {
|
|
10089
10043
|
const { manifest, policy, type, url } = value
|
|
@@ -10102,11 +10056,11 @@ function toMarkdownReport(report) {
|
|
|
10102
10056
|
# Scan Policy Report
|
|
10103
10057
|
|
|
10104
10058
|
This report tells you whether the results of a Socket scan results violate the
|
|
10105
|
-
security or license policy set by your organization.
|
|
10059
|
+
security${includeLicensePolicy ? ' or license' : ''} policy set by your organization.
|
|
10106
10060
|
|
|
10107
10061
|
## Health status
|
|
10108
10062
|
|
|
10109
|
-
${report.healthy ?
|
|
10063
|
+
${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
10064
|
|
|
10111
10065
|
## Settings
|
|
10112
10066
|
|
|
@@ -10116,6 +10070,7 @@ Configuration used to generate this report:
|
|
|
10116
10070
|
- Scan ID: ${report.scanId}
|
|
10117
10071
|
- Alert folding: ${report.options.fold === 'none' ? 'none' : `up to ${report.options.fold}`}
|
|
10118
10072
|
- Minimal policy level for alert to be included in report: ${report.options.reportLevel === 'defer' ? 'everything' : report.options.reportLevel}
|
|
10073
|
+
- Include license alerts: ${includeLicensePolicy ? 'yes' : 'no'}
|
|
10119
10074
|
|
|
10120
10075
|
## Alerts
|
|
10121
10076
|
|
|
@@ -10130,27 +10085,16 @@ async function handleScanReport({
|
|
|
10130
10085
|
filePath,
|
|
10131
10086
|
fold,
|
|
10132
10087
|
includeLicensePolicy,
|
|
10133
|
-
includeSecurityPolicy,
|
|
10134
10088
|
orgSlug,
|
|
10135
10089
|
outputKind,
|
|
10136
10090
|
reportLevel,
|
|
10137
10091
|
scanId,
|
|
10138
10092
|
short
|
|
10139
10093
|
}) {
|
|
10140
|
-
|
|
10141
|
-
process.exitCode = 1
|
|
10142
|
-
return // caller should assert
|
|
10143
|
-
}
|
|
10144
|
-
const {
|
|
10145
|
-
// licensePolicy,
|
|
10146
|
-
ok,
|
|
10147
|
-
scan,
|
|
10148
|
-
securityPolicy
|
|
10149
|
-
} = await fetchReportData(
|
|
10094
|
+
const { ok, scan, securityPolicy } = await fetchReportData(
|
|
10150
10095
|
orgSlug,
|
|
10151
10096
|
scanId,
|
|
10152
|
-
|
|
10153
|
-
includeSecurityPolicy
|
|
10097
|
+
includeLicensePolicy
|
|
10154
10098
|
)
|
|
10155
10099
|
if (!ok) {
|
|
10156
10100
|
return
|
|
@@ -10160,7 +10104,6 @@ async function handleScanReport({
|
|
|
10160
10104
|
fold,
|
|
10161
10105
|
scanId: scanId,
|
|
10162
10106
|
includeLicensePolicy,
|
|
10163
|
-
includeSecurityPolicy,
|
|
10164
10107
|
orgSlug,
|
|
10165
10108
|
outputKind,
|
|
10166
10109
|
reportLevel,
|
|
@@ -10173,8 +10116,7 @@ const config$3 = {
|
|
|
10173
10116
|
commandName: 'report',
|
|
10174
10117
|
description:
|
|
10175
10118
|
'Check whether a scan result passes the organizational policies (security, license)',
|
|
10176
|
-
hidden:
|
|
10177
|
-
// [beta]
|
|
10119
|
+
hidden: false,
|
|
10178
10120
|
flags: {
|
|
10179
10121
|
...commonFlags,
|
|
10180
10122
|
...outputFlags,
|
|
@@ -10193,31 +10135,23 @@ const config$3 = {
|
|
|
10193
10135
|
default: false,
|
|
10194
10136
|
description: 'Report only the healthy status'
|
|
10195
10137
|
},
|
|
10196
|
-
|
|
10197
|
-
// type: 'boolean',
|
|
10198
|
-
// default: true,
|
|
10199
|
-
// description: 'Report the license policy status. Default: true'
|
|
10200
|
-
// },
|
|
10201
|
-
security: {
|
|
10138
|
+
license: {
|
|
10202
10139
|
type: 'boolean',
|
|
10203
|
-
default:
|
|
10204
|
-
description: '
|
|
10140
|
+
default: false,
|
|
10141
|
+
description: 'Also report the license policy status. Default: false'
|
|
10205
10142
|
}
|
|
10206
10143
|
},
|
|
10207
10144
|
help: (command, config) => `
|
|
10208
10145
|
Usage
|
|
10209
10146
|
$ ${command} <org slug> <scan ID> [path to output file]
|
|
10210
10147
|
|
|
10148
|
+
API Token Requirements
|
|
10149
|
+
- Quota: 2 units
|
|
10150
|
+
- Permissions: full-scans:list security-policy:read
|
|
10151
|
+
|
|
10211
10152
|
Options
|
|
10212
10153
|
${getFlagListOutput(config.flags, 6)}
|
|
10213
10154
|
|
|
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
10155
|
By default the result is a nested object that looks like this:
|
|
10222
10156
|
\`{[ecosystem]: {[pkgName]: {[version]: {[file]: {[type:loc]: policy}}}}\`
|
|
10223
10157
|
You can fold this up to given level: 'pkg', 'version', 'file', and 'none'.
|
|
@@ -10229,6 +10163,7 @@ const config$3 = {
|
|
|
10229
10163
|
|
|
10230
10164
|
Examples
|
|
10231
10165
|
$ ${command} FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 --json --fold=version
|
|
10166
|
+
$ ${command} FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 --license --markdown --short
|
|
10232
10167
|
`
|
|
10233
10168
|
}
|
|
10234
10169
|
const cmdScanReport = {
|
|
@@ -10246,10 +10181,9 @@ async function run$3(argv, importMeta, { parentName }) {
|
|
|
10246
10181
|
const {
|
|
10247
10182
|
fold = 'none',
|
|
10248
10183
|
json,
|
|
10249
|
-
|
|
10184
|
+
license,
|
|
10250
10185
|
markdown,
|
|
10251
|
-
reportLevel = 'warn'
|
|
10252
|
-
security
|
|
10186
|
+
reportLevel = 'warn'
|
|
10253
10187
|
} = cli.flags
|
|
10254
10188
|
const defaultOrgSlug = shadowNpmInject.getConfigValue('defaultOrg')
|
|
10255
10189
|
const orgSlug = defaultOrgSlug || cli.input[0] || ''
|
|
@@ -10296,9 +10230,7 @@ async function run$3(argv, importMeta, { parentName }) {
|
|
|
10296
10230
|
await handleScanReport({
|
|
10297
10231
|
orgSlug,
|
|
10298
10232
|
scanId: scanId,
|
|
10299
|
-
includeLicensePolicy:
|
|
10300
|
-
// !!license,
|
|
10301
|
-
includeSecurityPolicy: typeof security === 'boolean' ? security : true,
|
|
10233
|
+
includeLicensePolicy: !!license,
|
|
10302
10234
|
outputKind: json ? 'json' : markdown ? 'markdown' : 'text',
|
|
10303
10235
|
filePath: file,
|
|
10304
10236
|
fold: fold,
|
|
@@ -10307,6 +10239,46 @@ async function run$3(argv, importMeta, { parentName }) {
|
|
|
10307
10239
|
})
|
|
10308
10240
|
}
|
|
10309
10241
|
|
|
10242
|
+
async function fetchScan(orgSlug, scanId) {
|
|
10243
|
+
const apiToken = shadowNpmInject.getDefaultToken()
|
|
10244
|
+
if (!apiToken) {
|
|
10245
|
+
throw new shadowNpmInject.AuthError(
|
|
10246
|
+
'User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.'
|
|
10247
|
+
)
|
|
10248
|
+
}
|
|
10249
|
+
|
|
10250
|
+
// Lazily access constants.spinner.
|
|
10251
|
+
const { spinner } = constants
|
|
10252
|
+
spinner.start('Fetching scan data...')
|
|
10253
|
+
const response = await queryApi(
|
|
10254
|
+
`orgs/${orgSlug}/full-scans/${encodeURIComponent(scanId)}`,
|
|
10255
|
+
apiToken
|
|
10256
|
+
)
|
|
10257
|
+
spinner.successAndStop('Received response while fetching scan data.')
|
|
10258
|
+
if (!response.ok) {
|
|
10259
|
+
const err = await handleApiError(response.status)
|
|
10260
|
+
logger.logger.fail(
|
|
10261
|
+
failMsgWithBadge(response.statusText, `Fetch error: ${err}`)
|
|
10262
|
+
)
|
|
10263
|
+
return
|
|
10264
|
+
}
|
|
10265
|
+
|
|
10266
|
+
// This is nd-json; each line is a json object
|
|
10267
|
+
const jsons = await response.text()
|
|
10268
|
+
const lines = jsons.split('\n').filter(Boolean)
|
|
10269
|
+
const data = lines.map(line => {
|
|
10270
|
+
try {
|
|
10271
|
+
return JSON.parse(line)
|
|
10272
|
+
} catch {
|
|
10273
|
+
console.error(
|
|
10274
|
+
'At least one line item was returned that could not be parsed as JSON...'
|
|
10275
|
+
)
|
|
10276
|
+
return {}
|
|
10277
|
+
}
|
|
10278
|
+
})
|
|
10279
|
+
return data
|
|
10280
|
+
}
|
|
10281
|
+
|
|
10310
10282
|
async function outputScanView(artifacts, orgSlug, scanId, filePath) {
|
|
10311
10283
|
const display = artifacts.map(art => {
|
|
10312
10284
|
const author = Array.isArray(art.author)
|
|
@@ -10367,7 +10339,6 @@ async function streamScan(orgSlug, scanId, file) {
|
|
|
10367
10339
|
spinner.successAndStop(`Full scan details written to ${file}`)
|
|
10368
10340
|
if (!data?.success) {
|
|
10369
10341
|
handleUnsuccessfulApiResponse('getOrgFullScan', data)
|
|
10370
|
-
return
|
|
10371
10342
|
}
|
|
10372
10343
|
return data
|
|
10373
10344
|
}
|
|
@@ -10385,6 +10356,10 @@ const config$2 = {
|
|
|
10385
10356
|
Usage
|
|
10386
10357
|
$ ${command} <org slug> <scan ID> [path to output file]
|
|
10387
10358
|
|
|
10359
|
+
API Token Requirements
|
|
10360
|
+
- Quota: 1 unit
|
|
10361
|
+
- Permissions: full-scans:list
|
|
10362
|
+
|
|
10388
10363
|
When no output path is given the contents is sent to stdout.
|
|
10389
10364
|
|
|
10390
10365
|
Options
|
|
@@ -10734,6 +10709,11 @@ const config$1 = {
|
|
|
10734
10709
|
Usage
|
|
10735
10710
|
$ ${command}
|
|
10736
10711
|
|
|
10712
|
+
API Token Requirements
|
|
10713
|
+
- Quota: 1 unit
|
|
10714
|
+
- Permissions: threat-feed:list
|
|
10715
|
+
- Special access
|
|
10716
|
+
|
|
10737
10717
|
This feature requires a Threat Feed license. Please contact
|
|
10738
10718
|
sales@socket.dev if you are interested in purchasing this access.
|
|
10739
10719
|
|
|
@@ -10852,7 +10832,7 @@ function checkSocketWrapperSetup(file) {
|
|
|
10852
10832
|
)
|
|
10853
10833
|
if (linesWithSocketAlias.length) {
|
|
10854
10834
|
logger.logger.log(
|
|
10855
|
-
`The Socket npm/npx wrapper is set up in your bash profile (${file})
|
|
10835
|
+
`The Socket npm/npx wrapper is set up in your bash profile (${file})`
|
|
10856
10836
|
)
|
|
10857
10837
|
return true
|
|
10858
10838
|
}
|
|
@@ -11034,7 +11014,7 @@ void (async () => {
|
|
|
11034
11014
|
await updateNotifier({
|
|
11035
11015
|
name: SOCKET_CLI_BIN_NAME,
|
|
11036
11016
|
// The '@rollup/plugin-replace' will replace "process.env['INLINED_SOCKET_CLI_VERSION']".
|
|
11037
|
-
version: '0.14.
|
|
11017
|
+
version: '0.14.69',
|
|
11038
11018
|
ttl: 86_400_000 /* 24 hours in milliseconds */
|
|
11039
11019
|
})
|
|
11040
11020
|
try {
|
|
@@ -11105,5 +11085,5 @@ void (async () => {
|
|
|
11105
11085
|
await shadowNpmInject.captureException(e)
|
|
11106
11086
|
}
|
|
11107
11087
|
})()
|
|
11108
|
-
//# debugId=
|
|
11088
|
+
//# debugId=a9c4fdbd-ffcd-4218-a422-d82749e51eff
|
|
11109
11089
|
//# sourceMappingURL=cli.js.map
|