socket 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/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 +6 -4
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:ca167d28: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) {
|
|
@@ -3039,12 +3136,99 @@ function runAgentInstall(pkgEnvDetails, options) {
|
|
|
3039
3136
|
}
|
|
3040
3137
|
|
|
3041
3138
|
const { NPM: NPM$c, OVERRIDES: OVERRIDES$2, PNPM: PNPM$9 } = constants
|
|
3042
|
-
async function
|
|
3043
|
-
|
|
3139
|
+
async function branchExists(branchName, cwd) {
|
|
3140
|
+
try {
|
|
3141
|
+
await spawn.spawn('git', ['rev-parse', '--verify', branchName], {
|
|
3142
|
+
cwd,
|
|
3143
|
+
stdio: 'ignore'
|
|
3144
|
+
})
|
|
3145
|
+
return true
|
|
3146
|
+
} catch {
|
|
3147
|
+
return false
|
|
3148
|
+
}
|
|
3149
|
+
}
|
|
3150
|
+
async function remoteBranchExists(branchName, cwd) {
|
|
3151
|
+
try {
|
|
3152
|
+
const result = await spawn.spawn(
|
|
3153
|
+
'git',
|
|
3154
|
+
['ls-remote', '--heads', 'origin', branchName],
|
|
3155
|
+
{
|
|
3156
|
+
cwd,
|
|
3157
|
+
stdio: 'pipe'
|
|
3158
|
+
}
|
|
3159
|
+
)
|
|
3160
|
+
return !!result.stdout.trim()
|
|
3161
|
+
} catch {
|
|
3162
|
+
return false
|
|
3163
|
+
}
|
|
3164
|
+
}
|
|
3165
|
+
async function commitAndPushFix(branchName, commitMsg, cwd) {
|
|
3166
|
+
const localExists = await branchExists(branchName, cwd)
|
|
3167
|
+
const remoteExists = await remoteBranchExists(branchName, cwd)
|
|
3168
|
+
if (localExists || remoteExists) {
|
|
3169
|
+
logger.logger.warn(
|
|
3170
|
+
`Branch "${branchName}" already exists. Skipping creation.`
|
|
3171
|
+
)
|
|
3172
|
+
return
|
|
3173
|
+
}
|
|
3174
|
+
await spawn.spawn('git', ['checkout', '-b', branchName], {
|
|
3175
|
+
cwd
|
|
3176
|
+
})
|
|
3177
|
+
await spawn.spawn('git', ['add', 'package.json', 'pnpm-lock.yaml'], {
|
|
3178
|
+
cwd
|
|
3179
|
+
})
|
|
3180
|
+
await spawn.spawn('git', ['commit', '-m', commitMsg], {
|
|
3181
|
+
cwd
|
|
3182
|
+
})
|
|
3183
|
+
await spawn.spawn('git', ['push', '--set-upstream', 'origin', branchName], {
|
|
3184
|
+
cwd
|
|
3185
|
+
})
|
|
3186
|
+
}
|
|
3187
|
+
async function createPullRequest({
|
|
3188
|
+
base = 'main',
|
|
3189
|
+
body,
|
|
3190
|
+
head,
|
|
3191
|
+
owner,
|
|
3192
|
+
repo,
|
|
3193
|
+
title
|
|
3194
|
+
}) {
|
|
3195
|
+
const octokit = new rest.Octokit({
|
|
3196
|
+
auth: process.env['GITHUB_TOKEN']
|
|
3197
|
+
})
|
|
3198
|
+
await octokit.pulls.create({
|
|
3199
|
+
owner,
|
|
3200
|
+
repo,
|
|
3201
|
+
title,
|
|
3202
|
+
head,
|
|
3203
|
+
base,
|
|
3204
|
+
...(body
|
|
3205
|
+
? {
|
|
3206
|
+
body
|
|
3207
|
+
}
|
|
3208
|
+
: {})
|
|
3209
|
+
})
|
|
3210
|
+
}
|
|
3211
|
+
function getRepoInfo() {
|
|
3212
|
+
const repoString = process.env['GITHUB_REPOSITORY']
|
|
3213
|
+
if (!repoString || !repoString.includes('/')) {
|
|
3214
|
+
throw new Error('GITHUB_REPOSITORY is not set or invalid')
|
|
3215
|
+
}
|
|
3216
|
+
const { 0: owner, 1: repo } = repoString.split('/')
|
|
3217
|
+
return {
|
|
3218
|
+
owner,
|
|
3219
|
+
repo
|
|
3220
|
+
}
|
|
3221
|
+
}
|
|
3222
|
+
async function pnpmFix(pkgEnvDetails, options) {
|
|
3223
|
+
const {
|
|
3224
|
+
cwd = process.cwd(),
|
|
3225
|
+
spinner,
|
|
3226
|
+
test = false,
|
|
3227
|
+
testScript = 'test'
|
|
3228
|
+
} = {
|
|
3044
3229
|
__proto__: null,
|
|
3045
3230
|
...options
|
|
3046
3231
|
}
|
|
3047
|
-
spinner?.start()
|
|
3048
3232
|
const lockfile = await lockfile_fs.readWantedLockfile(cwd, {
|
|
3049
3233
|
ignoreIncompatible: false
|
|
3050
3234
|
})
|
|
@@ -3058,7 +3242,8 @@ async function pnpmFix(pkgEnvDetails, cwd, options) {
|
|
|
3058
3242
|
existing: true,
|
|
3059
3243
|
unfixable: false,
|
|
3060
3244
|
upgradable: false
|
|
3061
|
-
}
|
|
3245
|
+
},
|
|
3246
|
+
nothrow: true
|
|
3062
3247
|
})
|
|
3063
3248
|
const infoByPkg = shadowNpmInject.getCveInfoByAlertsMap(alertsMap)
|
|
3064
3249
|
if (!infoByPkg) {
|
|
@@ -3074,11 +3259,12 @@ async function pnpmFix(pkgEnvDetails, cwd, options) {
|
|
|
3074
3259
|
editable: true
|
|
3075
3260
|
})
|
|
3076
3261
|
const { content: pkgJson } = editablePkgJson
|
|
3262
|
+
spinner?.stop()
|
|
3077
3263
|
for (const { 0: name, 1: infos } of infoByPkg) {
|
|
3078
3264
|
const tree = arb.actualTree
|
|
3079
3265
|
const hasUpgrade = !!registry.getManifestData(NPM$c, name)
|
|
3080
3266
|
if (hasUpgrade) {
|
|
3081
|
-
|
|
3267
|
+
logger.logger.info(`Skipping ${name}. Socket Optimize package exists.`)
|
|
3082
3268
|
continue
|
|
3083
3269
|
}
|
|
3084
3270
|
const nodes = shadowNpmInject.findPackageNodes(tree, name)
|
|
@@ -3100,6 +3286,7 @@ async function pnpmFix(pkgEnvDetails, cwd, options) {
|
|
|
3100
3286
|
const { firstPatchedVersionIdentifier, vulnerableVersionRange } =
|
|
3101
3287
|
infos[j]
|
|
3102
3288
|
const { version: oldVersion } = node
|
|
3289
|
+
const oldSpec = `${name}@${oldVersion}`
|
|
3103
3290
|
const availableVersions = Object.keys(packument.versions)
|
|
3104
3291
|
// Find the highest non-vulnerable version within the same major range
|
|
3105
3292
|
const targetVersion = shadowNpmInject.findBestPatchVersion(
|
|
@@ -3110,20 +3297,28 @@ async function pnpmFix(pkgEnvDetails, cwd, options) {
|
|
|
3110
3297
|
const targetPackument = targetVersion
|
|
3111
3298
|
? packument.versions[targetVersion]
|
|
3112
3299
|
: undefined
|
|
3113
|
-
|
|
3300
|
+
spinner?.stop()
|
|
3301
|
+
|
|
3302
|
+
// Check targetVersion to make TypeScript happy.
|
|
3303
|
+
if (targetVersion && targetPackument) {
|
|
3114
3304
|
const oldPnpm = pkgJson[PNPM$9]
|
|
3115
3305
|
const oldOverrides = oldPnpm?.[OVERRIDES$2]
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3306
|
+
const overrideKey = `${node.name}@${vulnerableVersionRange}`
|
|
3307
|
+
const overrideRange = `^${targetVersion}`
|
|
3308
|
+
const fixSpec = `${name}@${overrideRange}`
|
|
3309
|
+
const data = {
|
|
3310
|
+
[PNPM$9]: {
|
|
3311
|
+
...oldPnpm,
|
|
3312
|
+
[OVERRIDES$2]: {
|
|
3313
|
+
[overrideKey]: overrideRange,
|
|
3314
|
+
...oldOverrides
|
|
3124
3315
|
}
|
|
3125
|
-
}
|
|
3126
|
-
|
|
3316
|
+
}
|
|
3317
|
+
}
|
|
3318
|
+
try {
|
|
3319
|
+
editablePkgJson.update(data)
|
|
3320
|
+
spinner?.start()
|
|
3321
|
+
spinner?.info(`Installing ${fixSpec}`)
|
|
3127
3322
|
|
|
3128
3323
|
// eslint-disable-next-line no-await-in-loop
|
|
3129
3324
|
await editablePkgJson.save()
|
|
@@ -3131,11 +3326,70 @@ async function pnpmFix(pkgEnvDetails, cwd, options) {
|
|
|
3131
3326
|
await runAgentInstall(pkgEnvDetails, {
|
|
3132
3327
|
spinner
|
|
3133
3328
|
})
|
|
3329
|
+
if (test) {
|
|
3330
|
+
spinner?.info(`Testing ${fixSpec}`)
|
|
3331
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3332
|
+
await npm.runScript(testScript, [], {
|
|
3333
|
+
spinner,
|
|
3334
|
+
stdio: 'ignore'
|
|
3335
|
+
})
|
|
3336
|
+
}
|
|
3337
|
+
try {
|
|
3338
|
+
const branchName = `fix-${name}-${targetVersion.replace(/\./g, '-')}`
|
|
3339
|
+
const commitMsg = `fix: upgrade ${name} to ${targetVersion}`
|
|
3340
|
+
const { owner, repo } = getRepoInfo()
|
|
3341
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3342
|
+
await commitAndPushFix(branchName, commitMsg, cwd)
|
|
3343
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3344
|
+
await createPullRequest({
|
|
3345
|
+
owner,
|
|
3346
|
+
repo,
|
|
3347
|
+
title: commitMsg,
|
|
3348
|
+
head: branchName,
|
|
3349
|
+
base: process.env['GITHUB_REF_NAME'] ?? 'master',
|
|
3350
|
+
body: `This PR fixes a security issue in \`${name}\` by upgrading to \`${targetVersion}\`.`
|
|
3351
|
+
})
|
|
3352
|
+
} catch (e) {
|
|
3353
|
+
console.log(e)
|
|
3354
|
+
}
|
|
3355
|
+
logger.logger.success(`Fixed ${name}`)
|
|
3134
3356
|
} catch {
|
|
3135
|
-
spinner?.error(`Reverting ${
|
|
3357
|
+
spinner?.error(`Reverting ${fixSpec}`)
|
|
3358
|
+
const pnpmKeyCount = Object.keys(data[PNPM$9]).length
|
|
3359
|
+
const pnpmOverridesKeyCount = Object.keys(
|
|
3360
|
+
data[PNPM$9][OVERRIDES$2]
|
|
3361
|
+
).length
|
|
3362
|
+
if (pnpmKeyCount === 1 && pnpmOverridesKeyCount === 1) {
|
|
3363
|
+
editablePkgJson.update({
|
|
3364
|
+
// Setting to `undefined` will remove the property.
|
|
3365
|
+
[PNPM$9]: undefined
|
|
3366
|
+
})
|
|
3367
|
+
} else {
|
|
3368
|
+
editablePkgJson.update({
|
|
3369
|
+
[PNPM$9]: {
|
|
3370
|
+
...oldPnpm,
|
|
3371
|
+
[OVERRIDES$2]:
|
|
3372
|
+
pnpmOverridesKeyCount === 1
|
|
3373
|
+
? undefined
|
|
3374
|
+
: {
|
|
3375
|
+
[overrideKey]: undefined,
|
|
3376
|
+
...oldOverrides
|
|
3377
|
+
}
|
|
3378
|
+
}
|
|
3379
|
+
})
|
|
3380
|
+
}
|
|
3381
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3382
|
+
await editablePkgJson.save()
|
|
3383
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3384
|
+
await runAgentInstall(pkgEnvDetails, {
|
|
3385
|
+
spinner
|
|
3386
|
+
})
|
|
3387
|
+
spinner?.stop()
|
|
3388
|
+
logger.logger.error(`Failed to fix ${oldSpec}`)
|
|
3136
3389
|
}
|
|
3137
3390
|
} else {
|
|
3138
|
-
spinner?.
|
|
3391
|
+
spinner?.stop()
|
|
3392
|
+
logger.logger.error(`Could not patch ${oldSpec}`)
|
|
3139
3393
|
}
|
|
3140
3394
|
}
|
|
3141
3395
|
}
|
|
@@ -3541,39 +3795,59 @@ async function detectAndValidatePackageEnvironment(cwd, options) {
|
|
|
3541
3795
|
|
|
3542
3796
|
const { NPM: NPM$a, PNPM: PNPM$7 } = constants
|
|
3543
3797
|
const CMD_NAME$2 = 'socket fix'
|
|
3544
|
-
async function runFix(
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3798
|
+
async function runFix({
|
|
3799
|
+
cwd = process.cwd(),
|
|
3800
|
+
spinner,
|
|
3801
|
+
test = false,
|
|
3802
|
+
testScript = 'test'
|
|
3803
|
+
}) {
|
|
3549
3804
|
const pkgEnvDetails = await detectAndValidatePackageEnvironment(cwd, {
|
|
3550
3805
|
cmdName: CMD_NAME$2,
|
|
3551
3806
|
logger: logger.logger
|
|
3552
3807
|
})
|
|
3553
3808
|
if (!pkgEnvDetails) {
|
|
3554
|
-
spinner
|
|
3809
|
+
spinner?.stop()
|
|
3555
3810
|
return
|
|
3556
3811
|
}
|
|
3812
|
+
logger.logger.info(`Fixing packages for ${pkgEnvDetails.agent}`)
|
|
3557
3813
|
switch (pkgEnvDetails.agent) {
|
|
3558
3814
|
case NPM$a: {
|
|
3559
|
-
await npmFix(pkgEnvDetails,
|
|
3815
|
+
await npmFix(pkgEnvDetails, {
|
|
3816
|
+
spinner,
|
|
3817
|
+
test,
|
|
3818
|
+
testScript
|
|
3819
|
+
})
|
|
3560
3820
|
break
|
|
3561
3821
|
}
|
|
3562
3822
|
case PNPM$7: {
|
|
3563
|
-
await pnpmFix(pkgEnvDetails,
|
|
3823
|
+
await pnpmFix(pkgEnvDetails, {
|
|
3824
|
+
spinner,
|
|
3825
|
+
test,
|
|
3826
|
+
testScript
|
|
3827
|
+
})
|
|
3564
3828
|
break
|
|
3565
3829
|
}
|
|
3566
3830
|
}
|
|
3567
|
-
spinner.successAndStop('Socket.dev fix successful')
|
|
3831
|
+
// spinner.successAndStop('Socket.dev fix successful')
|
|
3568
3832
|
}
|
|
3569
3833
|
|
|
3570
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
3834
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$w } = constants
|
|
3571
3835
|
const config$z = {
|
|
3572
3836
|
commandName: 'fix',
|
|
3573
3837
|
description: 'Fix "fixable" Socket alerts',
|
|
3574
3838
|
hidden: true,
|
|
3575
3839
|
flags: {
|
|
3576
|
-
...commonFlags
|
|
3840
|
+
...commonFlags,
|
|
3841
|
+
test: {
|
|
3842
|
+
type: 'boolean',
|
|
3843
|
+
default: true,
|
|
3844
|
+
description: 'Very the fix by running unit tests'
|
|
3845
|
+
},
|
|
3846
|
+
testScript: {
|
|
3847
|
+
type: 'string',
|
|
3848
|
+
default: 'test',
|
|
3849
|
+
description: 'The test script to run for each fix attempt'
|
|
3850
|
+
}
|
|
3577
3851
|
},
|
|
3578
3852
|
help: (command, config) => `
|
|
3579
3853
|
Usage
|
|
@@ -3596,10 +3870,17 @@ async function run$z(argv, importMeta, { parentName }) {
|
|
|
3596
3870
|
parentName
|
|
3597
3871
|
})
|
|
3598
3872
|
if (cli.flags['dryRun']) {
|
|
3599
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
3873
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$w)
|
|
3600
3874
|
return
|
|
3601
3875
|
}
|
|
3602
|
-
|
|
3876
|
+
|
|
3877
|
+
// Lazily access constants.spinner.
|
|
3878
|
+
const { spinner } = constants
|
|
3879
|
+
await runFix({
|
|
3880
|
+
spinner,
|
|
3881
|
+
test: Boolean(cli.flags['test']),
|
|
3882
|
+
testScript: cli.flags['testScript']
|
|
3883
|
+
})
|
|
3603
3884
|
}
|
|
3604
3885
|
|
|
3605
3886
|
async function fetchPackageInfo(pkgName, pkgVersion, includeAllIssues) {
|
|
@@ -3624,10 +3905,10 @@ async function fetchPackageInfo(pkgName, pkgVersion, includeAllIssues) {
|
|
|
3624
3905
|
)
|
|
3625
3906
|
spinner.successAndStop('Data fetched')
|
|
3626
3907
|
if (result.success === false) {
|
|
3627
|
-
|
|
3908
|
+
handleUnsuccessfulApiResponse('getIssuesByNPMPackage', result)
|
|
3628
3909
|
}
|
|
3629
3910
|
if (scoreResult.success === false) {
|
|
3630
|
-
|
|
3911
|
+
handleUnsuccessfulApiResponse('getScoreByNPMPackage', scoreResult)
|
|
3631
3912
|
}
|
|
3632
3913
|
const severityCount = shadowNpmInject.getSeverityCount(
|
|
3633
3914
|
result.data,
|
|
@@ -3788,7 +4069,7 @@ async function handlePackageInfo({
|
|
|
3788
4069
|
}
|
|
3789
4070
|
}
|
|
3790
4071
|
|
|
3791
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4072
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$v } = constants
|
|
3792
4073
|
const config$y = {
|
|
3793
4074
|
commandName: 'info',
|
|
3794
4075
|
description: 'Look up info regarding a package',
|
|
@@ -3856,7 +4137,7 @@ async function run$y(argv, importMeta, { parentName }) {
|
|
|
3856
4137
|
const pkgVersion =
|
|
3857
4138
|
versionSeparator < 1 ? 'latest' : rawPkgName.slice(versionSeparator + 1)
|
|
3858
4139
|
if (cli.flags['dryRun']) {
|
|
3859
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4140
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$v)
|
|
3860
4141
|
return
|
|
3861
4142
|
}
|
|
3862
4143
|
await handlePackageInfo({
|
|
@@ -3893,7 +4174,6 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
|
|
|
3893
4174
|
if (!result.success) {
|
|
3894
4175
|
logger.logger.fail('Authentication failed...')
|
|
3895
4176
|
handleUnsuccessfulApiResponse('getOrganizations', result)
|
|
3896
|
-
return
|
|
3897
4177
|
}
|
|
3898
4178
|
logger.logger.success('API key verified')
|
|
3899
4179
|
const orgs = result.data
|
|
@@ -3931,16 +4211,24 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
|
|
|
3931
4211
|
}
|
|
3932
4212
|
}
|
|
3933
4213
|
spinner.stop()
|
|
3934
|
-
const
|
|
4214
|
+
const previousPersistedToken = shadowNpmInject.getConfigValue('apiToken')
|
|
3935
4215
|
try {
|
|
3936
4216
|
applyLogin(apiToken, enforcedOrgs, apiBaseUrl, apiProxy)
|
|
3937
|
-
logger.logger.success(
|
|
4217
|
+
logger.logger.success(
|
|
4218
|
+
`API credentials ${previousPersistedToken === apiToken ? 'refreshed' : previousPersistedToken ? 'updated' : 'set'}`
|
|
4219
|
+
)
|
|
4220
|
+
if (!shadowNpmInject.isReadOnlyConfig()) {
|
|
4221
|
+
logger.logger.log('')
|
|
4222
|
+
logger.logger.warn(
|
|
4223
|
+
'Note: config is in read-only mode, at least one key was overridden through flag/env, so the login was not persisted!'
|
|
4224
|
+
)
|
|
4225
|
+
}
|
|
3938
4226
|
} catch {
|
|
3939
4227
|
logger.logger.fail(`API login failed`)
|
|
3940
4228
|
}
|
|
3941
4229
|
}
|
|
3942
4230
|
|
|
3943
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4231
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$u } = constants
|
|
3944
4232
|
const config$x = {
|
|
3945
4233
|
commandName: 'login',
|
|
3946
4234
|
description: 'Socket API login',
|
|
@@ -3960,6 +4248,9 @@ const config$x = {
|
|
|
3960
4248
|
Usage
|
|
3961
4249
|
$ ${command}
|
|
3962
4250
|
|
|
4251
|
+
API Token Requirements
|
|
4252
|
+
- Quota: 1 unit
|
|
4253
|
+
|
|
3963
4254
|
Logs into the Socket API by prompting for an API key
|
|
3964
4255
|
|
|
3965
4256
|
Options
|
|
@@ -3985,7 +4276,7 @@ async function run$x(argv, importMeta, { parentName }) {
|
|
|
3985
4276
|
const apiBaseUrl = cli.flags['apiBaseUrl']
|
|
3986
4277
|
const apiProxy = cli.flags['apiProxy']
|
|
3987
4278
|
if (cli.flags['dryRun']) {
|
|
3988
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4279
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$u)
|
|
3989
4280
|
return
|
|
3990
4281
|
}
|
|
3991
4282
|
if (!isInteractive()) {
|
|
@@ -4007,12 +4298,18 @@ function attemptLogout() {
|
|
|
4007
4298
|
try {
|
|
4008
4299
|
applyLogout()
|
|
4009
4300
|
logger.logger.success('Successfully logged out')
|
|
4301
|
+
if (!shadowNpmInject.isReadOnlyConfig()) {
|
|
4302
|
+
logger.logger.log('')
|
|
4303
|
+
logger.logger.warn(
|
|
4304
|
+
'Note: config is in read-only mode, at least one key was overridden through flag/env, so the logout was not persisted!'
|
|
4305
|
+
)
|
|
4306
|
+
}
|
|
4010
4307
|
} catch {
|
|
4011
4308
|
logger.logger.fail('Failed to complete logout steps')
|
|
4012
4309
|
}
|
|
4013
4310
|
}
|
|
4014
4311
|
|
|
4015
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4312
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$t } = constants
|
|
4016
4313
|
const config$w = {
|
|
4017
4314
|
commandName: 'logout',
|
|
4018
4315
|
description: 'Socket API logout',
|
|
@@ -4040,7 +4337,7 @@ async function run$w(argv, importMeta, { parentName }) {
|
|
|
4040
4337
|
parentName
|
|
4041
4338
|
})
|
|
4042
4339
|
if (cli.flags['dryRun']) {
|
|
4043
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4340
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$t)
|
|
4044
4341
|
return
|
|
4045
4342
|
}
|
|
4046
4343
|
attemptLogout()
|
|
@@ -4148,7 +4445,7 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
|
|
|
4148
4445
|
}
|
|
4149
4446
|
}
|
|
4150
4447
|
|
|
4151
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4448
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$s } = constants
|
|
4152
4449
|
const config$v = {
|
|
4153
4450
|
commandName: 'gradle',
|
|
4154
4451
|
description:
|
|
@@ -4295,7 +4592,7 @@ async function run$v(argv, importMeta, { parentName }) {
|
|
|
4295
4592
|
.filter(Boolean)
|
|
4296
4593
|
}
|
|
4297
4594
|
if (cli.flags['dryRun']) {
|
|
4298
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4595
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$s)
|
|
4299
4596
|
return
|
|
4300
4597
|
}
|
|
4301
4598
|
await convertGradleToMaven(target, bin, out, verbose, gradleOpts)
|
|
@@ -4404,7 +4701,7 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
|
|
|
4404
4701
|
}
|
|
4405
4702
|
}
|
|
4406
4703
|
|
|
4407
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4704
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$r } = constants
|
|
4408
4705
|
const config$u = {
|
|
4409
4706
|
commandName: 'scala',
|
|
4410
4707
|
description:
|
|
@@ -4549,13 +4846,13 @@ async function run$u(argv, importMeta, { parentName }) {
|
|
|
4549
4846
|
.filter(Boolean)
|
|
4550
4847
|
}
|
|
4551
4848
|
if (cli.flags['dryRun']) {
|
|
4552
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4849
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$r)
|
|
4553
4850
|
return
|
|
4554
4851
|
}
|
|
4555
4852
|
await convertSbtToMaven(target, bin, out, verbose, sbtOpts)
|
|
4556
4853
|
}
|
|
4557
4854
|
|
|
4558
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4855
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$q } = constants
|
|
4559
4856
|
const config$t = {
|
|
4560
4857
|
commandName: 'auto',
|
|
4561
4858
|
description: 'Auto-detect build and attempt to generate manifest file',
|
|
@@ -4621,7 +4918,7 @@ async function run$t(argv, importMeta, { parentName }) {
|
|
|
4621
4918
|
}
|
|
4622
4919
|
subArgs.push(dir)
|
|
4623
4920
|
if (cli.flags['dryRun']) {
|
|
4624
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4921
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$q)
|
|
4625
4922
|
return
|
|
4626
4923
|
}
|
|
4627
4924
|
await cmdManifestScala.run(subArgs, importMeta, {
|
|
@@ -4638,7 +4935,7 @@ async function run$t(argv, importMeta, { parentName }) {
|
|
|
4638
4935
|
subArgs.push(cwd)
|
|
4639
4936
|
}
|
|
4640
4937
|
if (cli.flags['dryRun']) {
|
|
4641
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4938
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$q)
|
|
4642
4939
|
return
|
|
4643
4940
|
}
|
|
4644
4941
|
await cmdManifestGradle.run(subArgs, importMeta, {
|
|
@@ -4647,7 +4944,7 @@ async function run$t(argv, importMeta, { parentName }) {
|
|
|
4647
4944
|
return
|
|
4648
4945
|
}
|
|
4649
4946
|
if (cli.flags['dryRun']) {
|
|
4650
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
4947
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$q)
|
|
4651
4948
|
return
|
|
4652
4949
|
}
|
|
4653
4950
|
|
|
@@ -4674,7 +4971,7 @@ async function run$t(argv, importMeta, { parentName }) {
|
|
|
4674
4971
|
).showHelp()
|
|
4675
4972
|
}
|
|
4676
4973
|
|
|
4677
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
4974
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$p } = constants
|
|
4678
4975
|
|
|
4679
4976
|
// TODO: we may want to dedupe some pieces for all gradle languages. I think it
|
|
4680
4977
|
// makes sense to have separate commands for them and I think it makes
|
|
@@ -4827,7 +5124,7 @@ async function run$s(argv, importMeta, { parentName }) {
|
|
|
4827
5124
|
.filter(Boolean)
|
|
4828
5125
|
}
|
|
4829
5126
|
if (cli.flags['dryRun']) {
|
|
4830
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
5127
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$p)
|
|
4831
5128
|
return
|
|
4832
5129
|
}
|
|
4833
5130
|
await convertGradleToMaven(target, bin, out, verbose, gradleOpts)
|
|
@@ -4878,7 +5175,7 @@ async function wrapNpm(argv) {
|
|
|
4878
5175
|
await shadowBin(NPM$8, argv)
|
|
4879
5176
|
}
|
|
4880
5177
|
|
|
4881
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
5178
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$o, NPM: NPM$7 } = constants
|
|
4882
5179
|
const config$q = {
|
|
4883
5180
|
commandName: 'npm',
|
|
4884
5181
|
description: `${NPM$7} wrapper functionality`,
|
|
@@ -4905,7 +5202,7 @@ async function run$q(argv, importMeta, { parentName }) {
|
|
|
4905
5202
|
parentName
|
|
4906
5203
|
})
|
|
4907
5204
|
if (cli.flags['dryRun']) {
|
|
4908
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
5205
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$o)
|
|
4909
5206
|
return
|
|
4910
5207
|
}
|
|
4911
5208
|
await wrapNpm(argv)
|
|
@@ -4918,7 +5215,7 @@ async function wrapNpx(argv) {
|
|
|
4918
5215
|
await shadowBin(NPX$2, argv)
|
|
4919
5216
|
}
|
|
4920
5217
|
|
|
4921
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
5218
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$n, NPX: NPX$1 } = constants
|
|
4922
5219
|
const config$p = {
|
|
4923
5220
|
commandName: 'npx',
|
|
4924
5221
|
description: `${NPX$1} wrapper functionality`,
|
|
@@ -4945,13 +5242,13 @@ async function run$p(argv, importMeta, { parentName }) {
|
|
|
4945
5242
|
parentName
|
|
4946
5243
|
})
|
|
4947
5244
|
if (cli.flags['dryRun']) {
|
|
4948
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
5245
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$n)
|
|
4949
5246
|
return
|
|
4950
5247
|
}
|
|
4951
5248
|
await wrapNpx(argv)
|
|
4952
5249
|
}
|
|
4953
5250
|
|
|
4954
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
5251
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$m } = constants
|
|
4955
5252
|
const config$o = {
|
|
4956
5253
|
commandName: 'oops',
|
|
4957
5254
|
description: 'Trigger an intentional error (for development)',
|
|
@@ -4979,7 +5276,7 @@ async function run$o(argv, importMeta, { parentName }) {
|
|
|
4979
5276
|
parentName
|
|
4980
5277
|
})
|
|
4981
5278
|
if (cli.flags['dryRun']) {
|
|
4982
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
5279
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$m)
|
|
4983
5280
|
return
|
|
4984
5281
|
}
|
|
4985
5282
|
throw new Error('This error was intentionally left blank')
|
|
@@ -5868,7 +6165,7 @@ async function applyOptimization(cwd, pin, prod) {
|
|
|
5868
6165
|
}
|
|
5869
6166
|
}
|
|
5870
6167
|
|
|
5871
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
6168
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$l } = constants
|
|
5872
6169
|
const config$n = {
|
|
5873
6170
|
commandName: 'optimize',
|
|
5874
6171
|
description: 'Optimize dependencies with @socketregistry overrides',
|
|
@@ -5912,7 +6209,7 @@ async function run$n(argv, importMeta, { parentName }) {
|
|
|
5912
6209
|
})
|
|
5913
6210
|
const cwd = process.cwd()
|
|
5914
6211
|
if (cli.flags['dryRun']) {
|
|
5915
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
6212
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$l)
|
|
5916
6213
|
return
|
|
5917
6214
|
}
|
|
5918
6215
|
await applyOptimization(
|
|
@@ -5935,7 +6232,6 @@ async function fetchOrganization() {
|
|
|
5935
6232
|
spinner.successAndStop('Received organization list response.')
|
|
5936
6233
|
if (!result.success) {
|
|
5937
6234
|
handleUnsuccessfulApiResponse('getOrganizations', result)
|
|
5938
|
-
return
|
|
5939
6235
|
}
|
|
5940
6236
|
return result.data
|
|
5941
6237
|
}
|
|
@@ -6014,7 +6310,7 @@ async function handleOrganizationList(outputKind = 'text') {
|
|
|
6014
6310
|
await outputOrganizationList(data, outputKind)
|
|
6015
6311
|
}
|
|
6016
6312
|
|
|
6017
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
6313
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$k } = constants
|
|
6018
6314
|
const config$m = {
|
|
6019
6315
|
commandName: 'list',
|
|
6020
6316
|
description: 'List organizations associated with the API key used',
|
|
@@ -6027,6 +6323,10 @@ const config$m = {
|
|
|
6027
6323
|
Usage
|
|
6028
6324
|
$ ${command}
|
|
6029
6325
|
|
|
6326
|
+
API Token Requirements
|
|
6327
|
+
- Quota: 1 unit
|
|
6328
|
+
- Permissions: none (does need a token)
|
|
6329
|
+
|
|
6030
6330
|
Options
|
|
6031
6331
|
${getFlagListOutput(config$m.flags, 6)}
|
|
6032
6332
|
`
|
|
@@ -6067,7 +6367,7 @@ async function run$m(argv, importMeta, { parentName }) {
|
|
|
6067
6367
|
return
|
|
6068
6368
|
}
|
|
6069
6369
|
if (cli.flags['dryRun']) {
|
|
6070
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
6370
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$k)
|
|
6071
6371
|
return
|
|
6072
6372
|
}
|
|
6073
6373
|
await handleOrganizationList(json ? 'json' : markdown ? 'markdown' : 'text')
|
|
@@ -6086,7 +6386,6 @@ async function fetchLicensePolicy(orgSlug) {
|
|
|
6086
6386
|
spinner.successAndStop('Received organization license policy response.')
|
|
6087
6387
|
if (!result.success) {
|
|
6088
6388
|
handleUnsuccessfulApiResponse('getOrgLicensePolicy', result)
|
|
6089
|
-
return
|
|
6090
6389
|
}
|
|
6091
6390
|
return result.data
|
|
6092
6391
|
}
|
|
@@ -6131,7 +6430,7 @@ async function handleLicensePolicy(orgSlug, outputKind) {
|
|
|
6131
6430
|
await outputLicensePolicy(data, outputKind)
|
|
6132
6431
|
}
|
|
6133
6432
|
|
|
6134
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
6433
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$j } = constants
|
|
6135
6434
|
|
|
6136
6435
|
// TODO: secret toplevel alias `socket license policy`?
|
|
6137
6436
|
const config$l = {
|
|
@@ -6146,6 +6445,10 @@ const config$l = {
|
|
|
6146
6445
|
Usage
|
|
6147
6446
|
$ ${command} <org slug>
|
|
6148
6447
|
|
|
6448
|
+
API Token Requirements
|
|
6449
|
+
- Quota: 1 unit
|
|
6450
|
+
- Permissions: license-policy:read
|
|
6451
|
+
|
|
6149
6452
|
Options
|
|
6150
6453
|
${getFlagListOutput(config$l.flags, 6)}
|
|
6151
6454
|
|
|
@@ -6202,7 +6505,7 @@ async function run$l(argv, importMeta, { parentName }) {
|
|
|
6202
6505
|
return
|
|
6203
6506
|
}
|
|
6204
6507
|
if (cli.flags['dryRun']) {
|
|
6205
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
6508
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$j)
|
|
6206
6509
|
return
|
|
6207
6510
|
}
|
|
6208
6511
|
await handleLicensePolicy(
|
|
@@ -6224,7 +6527,6 @@ async function fetchSecurityPolicy(orgSlug) {
|
|
|
6224
6527
|
spinner.successAndStop('Received organization security policy response.')
|
|
6225
6528
|
if (!result.success) {
|
|
6226
6529
|
handleUnsuccessfulApiResponse('getOrgSecurityPolicy', result)
|
|
6227
|
-
return
|
|
6228
6530
|
}
|
|
6229
6531
|
return result.data
|
|
6230
6532
|
}
|
|
@@ -6270,7 +6572,7 @@ async function handleSecurityPolicy(orgSlug, outputKind) {
|
|
|
6270
6572
|
await outputSecurityPolicy(data, outputKind)
|
|
6271
6573
|
}
|
|
6272
6574
|
|
|
6273
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
6575
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$i } = constants
|
|
6274
6576
|
|
|
6275
6577
|
// TODO: secret toplevel alias `socket security policy`?
|
|
6276
6578
|
const config$k = {
|
|
@@ -6285,6 +6587,10 @@ const config$k = {
|
|
|
6285
6587
|
Usage
|
|
6286
6588
|
$ ${command} <org slug>
|
|
6287
6589
|
|
|
6590
|
+
API Token Requirements
|
|
6591
|
+
- Quota: 1 unit
|
|
6592
|
+
- Permissions: security-policy:read
|
|
6593
|
+
|
|
6288
6594
|
Options
|
|
6289
6595
|
${getFlagListOutput(config$k.flags, 6)}
|
|
6290
6596
|
|
|
@@ -6341,7 +6647,7 @@ async function run$k(argv, importMeta, { parentName }) {
|
|
|
6341
6647
|
return
|
|
6342
6648
|
}
|
|
6343
6649
|
if (cli.flags['dryRun']) {
|
|
6344
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
6650
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$i)
|
|
6345
6651
|
return
|
|
6346
6652
|
}
|
|
6347
6653
|
await handleSecurityPolicy(
|
|
@@ -6389,7 +6695,6 @@ async function fetchQuota() {
|
|
|
6389
6695
|
spinner.successAndStop('Received organization quota response.')
|
|
6390
6696
|
if (!result.success) {
|
|
6391
6697
|
handleUnsuccessfulApiResponse('getQuota', result)
|
|
6392
|
-
return
|
|
6393
6698
|
}
|
|
6394
6699
|
return result.data
|
|
6395
6700
|
}
|
|
@@ -6428,7 +6733,7 @@ async function handleQuota(outputKind = 'text') {
|
|
|
6428
6733
|
await outputQuota(data, outputKind)
|
|
6429
6734
|
}
|
|
6430
6735
|
|
|
6431
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
6736
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$h } = constants
|
|
6432
6737
|
const config$j = {
|
|
6433
6738
|
commandName: 'quota',
|
|
6434
6739
|
description: 'List organizations associated with the API key used',
|
|
@@ -6481,7 +6786,7 @@ async function run$j(argv, importMeta, { parentName }) {
|
|
|
6481
6786
|
return
|
|
6482
6787
|
}
|
|
6483
6788
|
if (cli.flags['dryRun']) {
|
|
6484
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
6789
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$h)
|
|
6485
6790
|
return
|
|
6486
6791
|
}
|
|
6487
6792
|
await handleQuota(json ? 'json' : markdown ? 'markdown' : 'text')
|
|
@@ -6514,6 +6819,7 @@ const cmdOrganization = {
|
|
|
6514
6819
|
}
|
|
6515
6820
|
}
|
|
6516
6821
|
|
|
6822
|
+
const { SOCKET_CLI_ISSUES_URL } = constants
|
|
6517
6823
|
async function fetchPurlDeepScore(purl) {
|
|
6518
6824
|
const apiToken = shadowNpmInject.getDefaultToken()
|
|
6519
6825
|
if (!apiToken) {
|
|
@@ -6555,7 +6861,7 @@ async function fetchPurlDeepScore(purl) {
|
|
|
6555
6861
|
return JSON.parse(data)
|
|
6556
6862
|
} catch (e) {
|
|
6557
6863
|
throw new Error(
|
|
6558
|
-
|
|
6864
|
+
`Unable to parse JSON response from the Socket API.\nPlease report to ${SOCKET_CLI_ISSUES_URL}`
|
|
6559
6865
|
)
|
|
6560
6866
|
}
|
|
6561
6867
|
}
|
|
@@ -6748,7 +7054,7 @@ async function outputPurlScore(purl, data, outputKind) {
|
|
|
6748
7054
|
)
|
|
6749
7055
|
} else {
|
|
6750
7056
|
logger.logger.log(
|
|
6751
|
-
'This package had no alerts and neither did any of its direct/transitive dependencies
|
|
7057
|
+
'This package had no alerts and neither did any of its direct/transitive dependencies'
|
|
6752
7058
|
)
|
|
6753
7059
|
}
|
|
6754
7060
|
logger.logger.log('')
|
|
@@ -6823,7 +7129,7 @@ function parsePackageSpecifiers(ecosystem, pkgs) {
|
|
|
6823
7129
|
}
|
|
6824
7130
|
}
|
|
6825
7131
|
|
|
6826
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
7132
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$g } = constants
|
|
6827
7133
|
const config$i = {
|
|
6828
7134
|
commandName: 'score',
|
|
6829
7135
|
description:
|
|
@@ -6837,13 +7143,13 @@ const config$i = {
|
|
|
6837
7143
|
Usage
|
|
6838
7144
|
$ ${command} <<ecosystem> <name> | <purl>>
|
|
6839
7145
|
|
|
7146
|
+
API Token Requirements
|
|
7147
|
+
- Quota: 100 units
|
|
7148
|
+
- Permissions: packages:list
|
|
7149
|
+
|
|
6840
7150
|
Options
|
|
6841
7151
|
${getFlagListOutput(config.flags, 6)}
|
|
6842
7152
|
|
|
6843
|
-
Requirements
|
|
6844
|
-
- quota: 100
|
|
6845
|
-
- scope: \`packages:list\`
|
|
6846
|
-
|
|
6847
7153
|
Show deep scoring details for one package. The score will reflect the package
|
|
6848
7154
|
itself, any of its dependencies, and any of its transitive dependencies.
|
|
6849
7155
|
|
|
@@ -6915,7 +7221,7 @@ async function run$i(argv, importMeta, { parentName }) {
|
|
|
6915
7221
|
return
|
|
6916
7222
|
}
|
|
6917
7223
|
if (cli.flags['dryRun']) {
|
|
6918
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
7224
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$g)
|
|
6919
7225
|
return
|
|
6920
7226
|
}
|
|
6921
7227
|
await handlePurlDeepScore(
|
|
@@ -6939,10 +7245,6 @@ async function fetchPurlsShallowScore(purls) {
|
|
|
6939
7245
|
sockSdk.batchPackageFetch(
|
|
6940
7246
|
{
|
|
6941
7247
|
alerts: 'true'
|
|
6942
|
-
// compact: false,
|
|
6943
|
-
// fixable: false,
|
|
6944
|
-
// licenseattrib: false,
|
|
6945
|
-
// licensedetails: false
|
|
6946
7248
|
},
|
|
6947
7249
|
{
|
|
6948
7250
|
components: purls.map(purl => ({
|
|
@@ -6955,7 +7257,6 @@ async function fetchPurlsShallowScore(purls) {
|
|
|
6955
7257
|
spinner.successAndStop('Request completed')
|
|
6956
7258
|
if (!result.success) {
|
|
6957
7259
|
handleUnsuccessfulApiResponse('batchPackageFetch', result)
|
|
6958
|
-
return
|
|
6959
7260
|
}
|
|
6960
7261
|
return result
|
|
6961
7262
|
}
|
|
@@ -7112,7 +7413,7 @@ async function handlePurlsShallowScore({ outputKind, purls }) {
|
|
|
7112
7413
|
outputPurlsShallowScore(purls, packageData.data, outputKind)
|
|
7113
7414
|
}
|
|
7114
7415
|
|
|
7115
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
7416
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$f } = constants
|
|
7116
7417
|
const config$h = {
|
|
7117
7418
|
commandName: 'shallow',
|
|
7118
7419
|
description:
|
|
@@ -7126,13 +7427,13 @@ const config$h = {
|
|
|
7126
7427
|
Usage
|
|
7127
7428
|
$ ${command} <<ecosystem> <name> [<name> ...] | <purl> [<purl> ...]>
|
|
7128
7429
|
|
|
7430
|
+
API Token Requirements
|
|
7431
|
+
- Quota: 100 units
|
|
7432
|
+
- Permissions: packages:list
|
|
7433
|
+
|
|
7129
7434
|
Options
|
|
7130
7435
|
${getFlagListOutput(config.flags, 6)}
|
|
7131
7436
|
|
|
7132
|
-
Requirements
|
|
7133
|
-
- quota: 100
|
|
7134
|
-
- scope: \`packages:list\`
|
|
7135
|
-
|
|
7136
7437
|
Show scoring details for one or more packages purely based on their own package.
|
|
7137
7438
|
This means that any dependency scores are not reflected by the score. You can
|
|
7138
7439
|
use the \`socket package score <pkg>\` command to get its full transitive score.
|
|
@@ -7203,7 +7504,7 @@ async function run$h(argv, importMeta, { parentName }) {
|
|
|
7203
7504
|
return
|
|
7204
7505
|
}
|
|
7205
7506
|
if (cli.flags['dryRun']) {
|
|
7206
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
7507
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$f)
|
|
7207
7508
|
return
|
|
7208
7509
|
}
|
|
7209
7510
|
await handlePurlsShallowScore({
|
|
@@ -7256,7 +7557,7 @@ async function runRawNpm(argv) {
|
|
|
7256
7557
|
await spawnPromise
|
|
7257
7558
|
}
|
|
7258
7559
|
|
|
7259
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
7560
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$e, NPM } = constants
|
|
7260
7561
|
const config$g = {
|
|
7261
7562
|
commandName: 'raw-npm',
|
|
7262
7563
|
description: `Temporarily disable the Socket ${NPM} wrapper`,
|
|
@@ -7284,7 +7585,7 @@ async function run$g(argv, importMeta, { parentName }) {
|
|
|
7284
7585
|
parentName
|
|
7285
7586
|
})
|
|
7286
7587
|
if (cli.flags['dryRun']) {
|
|
7287
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
7588
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$e)
|
|
7288
7589
|
return
|
|
7289
7590
|
}
|
|
7290
7591
|
await runRawNpm(argv)
|
|
@@ -7306,7 +7607,7 @@ async function runRawNpx(argv) {
|
|
|
7306
7607
|
await spawnPromise
|
|
7307
7608
|
}
|
|
7308
7609
|
|
|
7309
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$
|
|
7610
|
+
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$d, NPX } = constants
|
|
7310
7611
|
const config$f = {
|
|
7311
7612
|
commandName: 'raw-npx',
|
|
7312
7613
|
description: `Temporarily disable the Socket ${NPX} wrapper`,
|
|
@@ -7334,242 +7635,12 @@ async function run$f(argv, importMeta, { parentName }) {
|
|
|
7334
7635
|
parentName
|
|
7335
7636
|
})
|
|
7336
7637
|
if (cli.flags['dryRun']) {
|
|
7337
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$
|
|
7638
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$d)
|
|
7338
7639
|
return
|
|
7339
7640
|
}
|
|
7340
7641
|
await runRawNpx(argv)
|
|
7341
7642
|
}
|
|
7342
7643
|
|
|
7343
|
-
const { DRY_RUN_LABEL } = constants
|
|
7344
|
-
async function createReport(socketConfig, inputPaths, { cwd, dryRun }) {
|
|
7345
|
-
// Lazily access constants.spinner.
|
|
7346
|
-
const { spinner } = constants
|
|
7347
|
-
const sockSdk = await shadowNpmInject.setupSdk()
|
|
7348
|
-
const supportedFiles = await sockSdk
|
|
7349
|
-
.getReportSupportedFiles()
|
|
7350
|
-
.then(res => {
|
|
7351
|
-
if (!res.success) {
|
|
7352
|
-
handleUnsuccessfulApiResponse('getReportSupportedFiles', res)
|
|
7353
|
-
}
|
|
7354
|
-
return res.data
|
|
7355
|
-
})
|
|
7356
|
-
.catch(cause => {
|
|
7357
|
-
throw new Error('Failed getting supported files for report', {
|
|
7358
|
-
cause
|
|
7359
|
-
})
|
|
7360
|
-
})
|
|
7361
|
-
const packagePaths = await shadowNpmPaths.getPackageFilesForScan(
|
|
7362
|
-
cwd,
|
|
7363
|
-
inputPaths,
|
|
7364
|
-
supportedFiles,
|
|
7365
|
-
socketConfig
|
|
7366
|
-
)
|
|
7367
|
-
const packagePathsCount = packagePaths.length
|
|
7368
|
-
if (packagePathsCount && debug.isDebug()) {
|
|
7369
|
-
for (const pkgPath of packagePaths) {
|
|
7370
|
-
debug.debugLog(`Uploading: ${pkgPath}`)
|
|
7371
|
-
}
|
|
7372
|
-
}
|
|
7373
|
-
if (dryRun) {
|
|
7374
|
-
debug.debugLog(`${DRY_RUN_LABEL}: Skipped actual upload`)
|
|
7375
|
-
return undefined
|
|
7376
|
-
}
|
|
7377
|
-
spinner.start(
|
|
7378
|
-
`Creating report with ${packagePathsCount} package ${words.pluralize('file', packagePathsCount)}`
|
|
7379
|
-
)
|
|
7380
|
-
const apiCall = sockSdk.createReportFromFilePaths(
|
|
7381
|
-
packagePaths,
|
|
7382
|
-
cwd,
|
|
7383
|
-
socketConfig?.issueRules
|
|
7384
|
-
)
|
|
7385
|
-
const result = await handleApiCall(apiCall, 'creating report')
|
|
7386
|
-
if (!result.success) {
|
|
7387
|
-
handleUnsuccessfulApiResponse('createReport', result)
|
|
7388
|
-
return undefined
|
|
7389
|
-
}
|
|
7390
|
-
spinner.successAndStop()
|
|
7391
|
-
return result
|
|
7392
|
-
}
|
|
7393
|
-
|
|
7394
|
-
async function getSocketConfig(absoluteConfigPath) {
|
|
7395
|
-
const socketConfig = await config$K
|
|
7396
|
-
.readSocketConfig(absoluteConfigPath)
|
|
7397
|
-
.catch(cause => {
|
|
7398
|
-
if (
|
|
7399
|
-
cause &&
|
|
7400
|
-
typeof cause === 'object' &&
|
|
7401
|
-
cause instanceof config$K.SocketValidationError
|
|
7402
|
-
) {
|
|
7403
|
-
// Inspired by workbox-build:
|
|
7404
|
-
// https://github.com/GoogleChrome/workbox/blob/95f97a207fd51efb3f8a653f6e3e58224183a778/packages/workbox-build/src/lib/validate-options.ts#L68-L71
|
|
7405
|
-
const betterErrors = betterAjvErrors.betterAjvErrors({
|
|
7406
|
-
basePath: 'config',
|
|
7407
|
-
data: cause.data,
|
|
7408
|
-
errors: cause.validationErrors,
|
|
7409
|
-
schema: cause.schema
|
|
7410
|
-
})
|
|
7411
|
-
throw new shadowNpmInject.InputError(
|
|
7412
|
-
'The socket.yml config is not valid',
|
|
7413
|
-
betterErrors
|
|
7414
|
-
.map(
|
|
7415
|
-
err =>
|
|
7416
|
-
`[${err.path}] ${err.message}.${err.suggestion ? err.suggestion : ''}`
|
|
7417
|
-
)
|
|
7418
|
-
.join('\n')
|
|
7419
|
-
)
|
|
7420
|
-
} else {
|
|
7421
|
-
throw new Error('Failed to read socket.yml config', {
|
|
7422
|
-
cause
|
|
7423
|
-
})
|
|
7424
|
-
}
|
|
7425
|
-
})
|
|
7426
|
-
return socketConfig
|
|
7427
|
-
}
|
|
7428
|
-
|
|
7429
|
-
const MAX_TIMEOUT_RETRY = 5
|
|
7430
|
-
const HTTP_CODE_TIMEOUT = 524
|
|
7431
|
-
async function fetchReportData$1(reportId, includeAllIssues, strict) {
|
|
7432
|
-
// Lazily access constants.spinner.
|
|
7433
|
-
const { spinner } = constants
|
|
7434
|
-
spinner.log('Fetching report with ID ${reportId} (this could take a while)')
|
|
7435
|
-
spinner.start(`Fetch started... (this could take a while)`)
|
|
7436
|
-
const sockSdk = await shadowNpmInject.setupSdk()
|
|
7437
|
-
let result
|
|
7438
|
-
for (let retry = 1; !result; ++retry) {
|
|
7439
|
-
try {
|
|
7440
|
-
// eslint-disable-next-line no-await-in-loop
|
|
7441
|
-
result = await handleApiCall(
|
|
7442
|
-
sockSdk.getReport(reportId),
|
|
7443
|
-
'fetching report'
|
|
7444
|
-
)
|
|
7445
|
-
} catch (err) {
|
|
7446
|
-
if (
|
|
7447
|
-
retry >= MAX_TIMEOUT_RETRY ||
|
|
7448
|
-
!(err instanceof Error) ||
|
|
7449
|
-
err.cause?.cause?.response?.statusCode !== HTTP_CODE_TIMEOUT
|
|
7450
|
-
) {
|
|
7451
|
-
spinner.stop(`Failed to fetch report`)
|
|
7452
|
-
throw err
|
|
7453
|
-
}
|
|
7454
|
-
spinner.fail(`Retrying report fetch ${retry} / ${MAX_TIMEOUT_RETRY}`)
|
|
7455
|
-
}
|
|
7456
|
-
}
|
|
7457
|
-
if (!result.success) {
|
|
7458
|
-
return handleUnsuccessfulApiResponse('getReport', result)
|
|
7459
|
-
}
|
|
7460
|
-
|
|
7461
|
-
// Conclude the status of the API call.
|
|
7462
|
-
if (strict) {
|
|
7463
|
-
if (result.data.healthy) {
|
|
7464
|
-
spinner.success('Report result is healthy and great!')
|
|
7465
|
-
} else {
|
|
7466
|
-
spinner.error('Report result deemed unhealthy for project')
|
|
7467
|
-
}
|
|
7468
|
-
} else if (!result.data.healthy) {
|
|
7469
|
-
const severityCount = shadowNpmInject.getSeverityCount(
|
|
7470
|
-
result.data.issues,
|
|
7471
|
-
includeAllIssues ? undefined : 'high'
|
|
7472
|
-
)
|
|
7473
|
-
const issueSummary = shadowNpmInject.formatSeverityCount(severityCount)
|
|
7474
|
-
spinner.success(`Report has these issues: ${issueSummary}`)
|
|
7475
|
-
} else {
|
|
7476
|
-
spinner.success('Report has no issues')
|
|
7477
|
-
}
|
|
7478
|
-
spinner.stop()
|
|
7479
|
-
return result.data
|
|
7480
|
-
}
|
|
7481
|
-
|
|
7482
|
-
function formatReportDataOutput(
|
|
7483
|
-
reportId,
|
|
7484
|
-
data,
|
|
7485
|
-
commandName,
|
|
7486
|
-
outputKind,
|
|
7487
|
-
strict,
|
|
7488
|
-
artifacts
|
|
7489
|
-
) {
|
|
7490
|
-
if (outputKind === 'json') {
|
|
7491
|
-
logger.logger.log(JSON.stringify(data, undefined, 2))
|
|
7492
|
-
} else {
|
|
7493
|
-
const format = new shadowNpmInject.ColorOrMarkdown(
|
|
7494
|
-
outputKind === 'markdown'
|
|
7495
|
-
)
|
|
7496
|
-
logger.logger.log(commonTags.stripIndents`
|
|
7497
|
-
Detailed info on socket.dev: ${format.hyperlink(reportId, data.url, {
|
|
7498
|
-
fallbackToUrl: true
|
|
7499
|
-
})}`)
|
|
7500
|
-
if (outputKind === 'print') {
|
|
7501
|
-
logger.logger.log(data)
|
|
7502
|
-
logger.logger.log(
|
|
7503
|
-
colors.dim(
|
|
7504
|
-
`Or rerun ${colors.italic(commandName)} using the ${colors.italic('--json')} flag to get full JSON output`
|
|
7505
|
-
)
|
|
7506
|
-
)
|
|
7507
|
-
logger.logger.log('The scan:')
|
|
7508
|
-
logger.logger.log(artifacts)
|
|
7509
|
-
}
|
|
7510
|
-
}
|
|
7511
|
-
if (strict && !data.healthy) {
|
|
7512
|
-
|
|
7513
|
-
process$1.exit(1)
|
|
7514
|
-
}
|
|
7515
|
-
}
|
|
7516
|
-
|
|
7517
|
-
async function fetchScan(orgSlug, scanId) {
|
|
7518
|
-
const apiToken = shadowNpmInject.getDefaultToken()
|
|
7519
|
-
if (!apiToken) {
|
|
7520
|
-
throw new shadowNpmInject.AuthError(
|
|
7521
|
-
'User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.'
|
|
7522
|
-
)
|
|
7523
|
-
}
|
|
7524
|
-
|
|
7525
|
-
// Lazily access constants.spinner.
|
|
7526
|
-
const { spinner } = constants
|
|
7527
|
-
spinner.start('Fetching scan data...')
|
|
7528
|
-
const response = await queryApi(
|
|
7529
|
-
`orgs/${orgSlug}/full-scans/${encodeURIComponent(scanId)}`,
|
|
7530
|
-
apiToken
|
|
7531
|
-
)
|
|
7532
|
-
spinner.successAndStop('Received response while fetching scan data.')
|
|
7533
|
-
if (!response.ok) {
|
|
7534
|
-
const err = await handleApiError(response.status)
|
|
7535
|
-
logger.logger.fail(
|
|
7536
|
-
failMsgWithBadge(response.statusText, `Fetch error: ${err}`)
|
|
7537
|
-
)
|
|
7538
|
-
return
|
|
7539
|
-
}
|
|
7540
|
-
|
|
7541
|
-
// This is nd-json; each line is a json object
|
|
7542
|
-
const jsons = await response.text()
|
|
7543
|
-
const lines = jsons.split('\n').filter(Boolean)
|
|
7544
|
-
const data = lines.map(line => {
|
|
7545
|
-
try {
|
|
7546
|
-
return JSON.parse(line)
|
|
7547
|
-
} catch {
|
|
7548
|
-
console.error(
|
|
7549
|
-
'At least one line item was returned that could not be parsed as JSON...'
|
|
7550
|
-
)
|
|
7551
|
-
return {}
|
|
7552
|
-
}
|
|
7553
|
-
})
|
|
7554
|
-
return data
|
|
7555
|
-
}
|
|
7556
|
-
|
|
7557
|
-
async function viewReport(reportId, { all, commandName, outputKind, strict }) {
|
|
7558
|
-
const result = await fetchReportData$1(reportId, all, strict)
|
|
7559
|
-
const artifacts = await fetchScan('socketdev', reportId)
|
|
7560
|
-
if (result) {
|
|
7561
|
-
formatReportDataOutput(
|
|
7562
|
-
reportId,
|
|
7563
|
-
result,
|
|
7564
|
-
commandName,
|
|
7565
|
-
outputKind,
|
|
7566
|
-
strict,
|
|
7567
|
-
artifacts
|
|
7568
|
-
)
|
|
7569
|
-
}
|
|
7570
|
-
}
|
|
7571
|
-
|
|
7572
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$e } = constants
|
|
7573
7644
|
const config$e = {
|
|
7574
7645
|
commandName: 'create',
|
|
7575
7646
|
description: '[Deprecated] Create a project report',
|
|
@@ -7601,57 +7672,17 @@ const cmdReportCreate = {
|
|
|
7601
7672
|
run: run$e
|
|
7602
7673
|
}
|
|
7603
7674
|
async function run$e(argv, importMeta, { parentName }) {
|
|
7604
|
-
|
|
7675
|
+
meowOrExit({
|
|
7605
7676
|
argv,
|
|
7606
7677
|
config: config$e,
|
|
7607
7678
|
importMeta,
|
|
7608
7679
|
parentName
|
|
7609
7680
|
})
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
const absoluteConfigPath = path$1.join(cwd, 'socket.yml')
|
|
7614
|
-
const dryRun = Boolean(cli.flags['dryRun'])
|
|
7615
|
-
const json = Boolean(cli.flags['json'])
|
|
7616
|
-
const markdown = Boolean(cli.flags['markdown'])
|
|
7617
|
-
const strict = Boolean(cli.flags['strict'])
|
|
7618
|
-
const includeAllIssues = Boolean(cli.flags['all'])
|
|
7619
|
-
const view = Boolean(cli.flags['view'])
|
|
7620
|
-
|
|
7621
|
-
// Note exiting earlier to skirt a hidden auth requirement
|
|
7622
|
-
if (cli.flags['dryRun']) {
|
|
7623
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$e)
|
|
7624
|
-
return
|
|
7625
|
-
}
|
|
7626
|
-
const socketConfig = await getSocketConfig(absoluteConfigPath)
|
|
7627
|
-
const result = await createReport(socketConfig, cli.input, {
|
|
7628
|
-
cwd,
|
|
7629
|
-
dryRun
|
|
7630
|
-
})
|
|
7631
|
-
const commandName = `${parentName} ${config$e.commandName}`
|
|
7632
|
-
if (result?.success) {
|
|
7633
|
-
if (view) {
|
|
7634
|
-
const reportId = result.data.id
|
|
7635
|
-
await viewReport(reportId, {
|
|
7636
|
-
all: includeAllIssues,
|
|
7637
|
-
commandName,
|
|
7638
|
-
outputKind: json ? 'json' : markdown ? 'markdown' : 'print',
|
|
7639
|
-
strict
|
|
7640
|
-
})
|
|
7641
|
-
} else if (json) {
|
|
7642
|
-
logger.logger.log(JSON.stringify(result.data, undefined, 2))
|
|
7643
|
-
} else {
|
|
7644
|
-
const format = new shadowNpmInject.ColorOrMarkdown(markdown)
|
|
7645
|
-
logger.logger.log(
|
|
7646
|
-
`New report: ${format.hyperlink(result.data.id, result.data.url, {
|
|
7647
|
-
fallbackToUrl: true
|
|
7648
|
-
})}`
|
|
7649
|
-
)
|
|
7650
|
-
}
|
|
7651
|
-
}
|
|
7681
|
+
logger.logger.fail(
|
|
7682
|
+
'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.'
|
|
7683
|
+
)
|
|
7652
7684
|
}
|
|
7653
7685
|
|
|
7654
|
-
const { DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$d } = constants
|
|
7655
7686
|
const config$d = {
|
|
7656
7687
|
commandName: 'view',
|
|
7657
7688
|
description: '[Deprecated] View a project report',
|
|
@@ -7672,49 +7703,15 @@ const cmdReportView = {
|
|
|
7672
7703
|
run: run$d
|
|
7673
7704
|
}
|
|
7674
7705
|
async function run$d(argv, importMeta, { parentName }) {
|
|
7675
|
-
|
|
7706
|
+
meowOrExit({
|
|
7676
7707
|
argv,
|
|
7677
7708
|
config: config$d,
|
|
7678
7709
|
importMeta,
|
|
7679
7710
|
parentName
|
|
7680
7711
|
})
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
const wasBadInput = handleBadInput(
|
|
7684
|
-
{
|
|
7685
|
-
test: reportId,
|
|
7686
|
-
message: 'Need at least one report ID',
|
|
7687
|
-
pass: 'ok',
|
|
7688
|
-
fail: 'missing'
|
|
7689
|
-
},
|
|
7690
|
-
{
|
|
7691
|
-
nook: true,
|
|
7692
|
-
test: extraInput.length === 0,
|
|
7693
|
-
message: 'Can only handle a single report ID',
|
|
7694
|
-
pass: 'ok',
|
|
7695
|
-
fail: 'received ' + (extraInput.length + 1)
|
|
7696
|
-
},
|
|
7697
|
-
{
|
|
7698
|
-
nook: true,
|
|
7699
|
-
test: !json || !markdown,
|
|
7700
|
-
message: 'The json and markdown flags cannot be both set, pick one',
|
|
7701
|
-
pass: 'ok',
|
|
7702
|
-
fail: 'omit one'
|
|
7703
|
-
}
|
|
7712
|
+
logger.logger.fail(
|
|
7713
|
+
'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.'
|
|
7704
7714
|
)
|
|
7705
|
-
if (wasBadInput) {
|
|
7706
|
-
return
|
|
7707
|
-
}
|
|
7708
|
-
if (cli.flags['dryRun']) {
|
|
7709
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$d)
|
|
7710
|
-
return
|
|
7711
|
-
}
|
|
7712
|
-
await viewReport(reportId, {
|
|
7713
|
-
all: Boolean(cli.flags['all']),
|
|
7714
|
-
commandName: `${parentName} ${config$d.commandName}`,
|
|
7715
|
-
outputKind: json ? 'json' : markdown ? 'markdown' : 'print',
|
|
7716
|
-
strict: Boolean(cli.flags['strict'])
|
|
7717
|
-
})
|
|
7718
7715
|
}
|
|
7719
7716
|
|
|
7720
7717
|
const description$2 = '[Deprecated] Project report related commands'
|
|
@@ -7764,7 +7761,6 @@ async function fetchCreateRepo({
|
|
|
7764
7761
|
spinner.successAndStop('Received response requesting to create a repository.')
|
|
7765
7762
|
if (!result.success) {
|
|
7766
7763
|
handleUnsuccessfulApiResponse('createOrgRepo', result)
|
|
7767
|
-
return
|
|
7768
7764
|
}
|
|
7769
7765
|
return result.data
|
|
7770
7766
|
}
|
|
@@ -7837,6 +7833,10 @@ const config$c = {
|
|
|
7837
7833
|
Usage
|
|
7838
7834
|
$ ${command} <org slug>
|
|
7839
7835
|
|
|
7836
|
+
API Token Requirements
|
|
7837
|
+
- Quota: 1 unit
|
|
7838
|
+
- Permissions: repo:create
|
|
7839
|
+
|
|
7840
7840
|
Options
|
|
7841
7841
|
${getFlagListOutput(config.flags, 6)}
|
|
7842
7842
|
|
|
@@ -7912,7 +7912,6 @@ async function handleDeleteRepo(orgSlug, repoName) {
|
|
|
7912
7912
|
)
|
|
7913
7913
|
if (!result.success) {
|
|
7914
7914
|
handleUnsuccessfulApiResponse('deleteOrgRepo', result)
|
|
7915
|
-
return
|
|
7916
7915
|
}
|
|
7917
7916
|
spinner.successAndStop('Repository deleted successfully')
|
|
7918
7917
|
}
|
|
@@ -7929,6 +7928,10 @@ const config$b = {
|
|
|
7929
7928
|
Usage
|
|
7930
7929
|
$ ${command} <org slug> <repo slug>
|
|
7931
7930
|
|
|
7931
|
+
API Token Requirements
|
|
7932
|
+
- Quota: 1 unit
|
|
7933
|
+
- Permissions: repo:delete
|
|
7934
|
+
|
|
7932
7935
|
Options
|
|
7933
7936
|
${getFlagListOutput(config.flags, 6)}
|
|
7934
7937
|
|
|
@@ -8003,7 +8006,6 @@ async function fetchListRepos({ direction, orgSlug, page, per_page, sort }) {
|
|
|
8003
8006
|
spinner.successAndStop('Received response for repository list.')
|
|
8004
8007
|
if (!result.success) {
|
|
8005
8008
|
handleUnsuccessfulApiResponse('getOrgRepoList', result)
|
|
8006
|
-
return
|
|
8007
8009
|
}
|
|
8008
8010
|
return result.data
|
|
8009
8011
|
}
|
|
@@ -8105,6 +8107,10 @@ const config$a = {
|
|
|
8105
8107
|
Usage
|
|
8106
8108
|
$ ${command} <org slug>
|
|
8107
8109
|
|
|
8110
|
+
API Token Requirements
|
|
8111
|
+
- Quota: 1 unit
|
|
8112
|
+
- Permissions: repo:list
|
|
8113
|
+
|
|
8108
8114
|
Options
|
|
8109
8115
|
${getFlagListOutput(config.flags, 6)}
|
|
8110
8116
|
|
|
@@ -8197,7 +8203,6 @@ async function fetchUpdateRepo({
|
|
|
8197
8203
|
spinner.successAndStop('Received response trying to update a repository')
|
|
8198
8204
|
if (!result.success) {
|
|
8199
8205
|
handleUnsuccessfulApiResponse('updateOrgRepo', result)
|
|
8200
|
-
return
|
|
8201
8206
|
}
|
|
8202
8207
|
return result.data
|
|
8203
8208
|
}
|
|
@@ -8270,6 +8275,10 @@ const config$9 = {
|
|
|
8270
8275
|
Usage
|
|
8271
8276
|
$ ${command} <org slug>
|
|
8272
8277
|
|
|
8278
|
+
API Token Requirements
|
|
8279
|
+
- Quota: 1 unit
|
|
8280
|
+
- Permissions: repo:update
|
|
8281
|
+
|
|
8273
8282
|
Options
|
|
8274
8283
|
${getFlagListOutput(config.flags, 6)}
|
|
8275
8284
|
|
|
@@ -8346,7 +8355,6 @@ async function fetchViewRepo(orgSlug, repoName) {
|
|
|
8346
8355
|
spinner.successAndStop('Received response while fetched repository data.')
|
|
8347
8356
|
if (!result.success) {
|
|
8348
8357
|
handleUnsuccessfulApiResponse('getOrgRepo', result)
|
|
8349
|
-
return
|
|
8350
8358
|
}
|
|
8351
8359
|
return result.data
|
|
8352
8360
|
}
|
|
@@ -8441,6 +8449,10 @@ const config$8 = {
|
|
|
8441
8449
|
Usage
|
|
8442
8450
|
$ ${command} <org slug>
|
|
8443
8451
|
|
|
8452
|
+
API Token Requirements
|
|
8453
|
+
- Quota: 1 unit
|
|
8454
|
+
- Permissions: repo:list
|
|
8455
|
+
|
|
8444
8456
|
Options
|
|
8445
8457
|
${getFlagListOutput(config.flags, 6)}
|
|
8446
8458
|
|
|
@@ -8546,7 +8558,9 @@ async function fetchCreateOrgFullScan(
|
|
|
8546
8558
|
|
|
8547
8559
|
// Lazily access constants.spinner.
|
|
8548
8560
|
const { spinner } = constants
|
|
8549
|
-
spinner.start(
|
|
8561
|
+
spinner.start(
|
|
8562
|
+
`Sending request to create a scan with ${packagePaths.length} packages...`
|
|
8563
|
+
)
|
|
8550
8564
|
const result = await handleApiCall(
|
|
8551
8565
|
sockSdk.createOrgFullScan(
|
|
8552
8566
|
orgSlug,
|
|
@@ -8563,10 +8577,9 @@ async function fetchCreateOrgFullScan(
|
|
|
8563
8577
|
),
|
|
8564
8578
|
'Creating scan'
|
|
8565
8579
|
)
|
|
8566
|
-
spinner.successAndStop('
|
|
8580
|
+
spinner.successAndStop('Completed request to create a new scan.')
|
|
8567
8581
|
if (!result.success) {
|
|
8568
8582
|
handleUnsuccessfulApiResponse('CreateOrgFullScan', result)
|
|
8569
|
-
return
|
|
8570
8583
|
}
|
|
8571
8584
|
return result.data
|
|
8572
8585
|
}
|
|
@@ -8581,12 +8594,12 @@ async function fetchSupportedScanFileNames() {
|
|
|
8581
8594
|
sockSdk.getReportSupportedFiles(),
|
|
8582
8595
|
'fetching supported scan file types'
|
|
8583
8596
|
)
|
|
8584
|
-
spinner.
|
|
8597
|
+
spinner.stop()
|
|
8598
|
+
logger.logger.success(
|
|
8585
8599
|
'Received response while fetched supported scan file types.'
|
|
8586
8600
|
)
|
|
8587
8601
|
if (!result.success) {
|
|
8588
8602
|
handleUnsuccessfulApiResponse('getReportSupportedFiles', result)
|
|
8589
|
-
return
|
|
8590
8603
|
}
|
|
8591
8604
|
return result.data
|
|
8592
8605
|
}
|
|
@@ -8624,7 +8637,6 @@ async function handleCreateNewScan({
|
|
|
8624
8637
|
cwd,
|
|
8625
8638
|
targets,
|
|
8626
8639
|
supportedFileNames
|
|
8627
|
-
// socketConfig
|
|
8628
8640
|
)
|
|
8629
8641
|
handleBadInput({
|
|
8630
8642
|
nook: true,
|
|
@@ -8688,7 +8700,7 @@ async function suggestOrgSlug() {
|
|
|
8688
8700
|
}
|
|
8689
8701
|
} else {
|
|
8690
8702
|
logger.logger.fail(
|
|
8691
|
-
'Failed to lookup organization list from API, unable to suggest
|
|
8703
|
+
'Failed to lookup organization list from API, unable to suggest'
|
|
8692
8704
|
)
|
|
8693
8705
|
}
|
|
8694
8706
|
}
|
|
@@ -8943,6 +8955,10 @@ const config$7 = {
|
|
|
8943
8955
|
Usage
|
|
8944
8956
|
$ ${command} [...options] <org> <TARGET> [TARGET...]
|
|
8945
8957
|
|
|
8958
|
+
API Token Requirements
|
|
8959
|
+
- Quota: 1 unit
|
|
8960
|
+
- Permissions: full-scans:create
|
|
8961
|
+
|
|
8946
8962
|
Uploads the specified "package.json" and lock files for JavaScript, Python,
|
|
8947
8963
|
Go, Scala, Gradle, and Kotlin dependency manifests.
|
|
8948
8964
|
If any folder is specified, the ones found in there recursively are uploaded.
|
|
@@ -8984,7 +9000,7 @@ async function run$7(argv, importMeta, { parentName }) {
|
|
|
8984
9000
|
cwdOverride && cwdOverride !== 'process.cwd()'
|
|
8985
9001
|
? String(cwdOverride)
|
|
8986
9002
|
: process.cwd()
|
|
8987
|
-
let { branch: branchName, repo: repoName } = cli.flags
|
|
9003
|
+
let { branch: branchName = '', repo: repoName = '' } = cli.flags
|
|
8988
9004
|
|
|
8989
9005
|
// We're going to need an api token to suggest data because those suggestions
|
|
8990
9006
|
// must come from data we already know. Don't error on missing api token yet.
|
|
@@ -9112,7 +9128,6 @@ async function fetchDeleteOrgFullScan(orgSlug, scanId) {
|
|
|
9112
9128
|
spinner.successAndStop('Received response for deleting a scan.')
|
|
9113
9129
|
if (!result.success) {
|
|
9114
9130
|
handleUnsuccessfulApiResponse('deleteOrgFullScan', result)
|
|
9115
|
-
return
|
|
9116
9131
|
}
|
|
9117
9132
|
return result.data
|
|
9118
9133
|
}
|
|
@@ -9142,6 +9157,10 @@ const config$6 = {
|
|
|
9142
9157
|
Usage
|
|
9143
9158
|
$ ${command} <org slug> <scan ID>
|
|
9144
9159
|
|
|
9160
|
+
API Token Requirements
|
|
9161
|
+
- Quota: 1 unit
|
|
9162
|
+
- Permissions: full-scans:delete
|
|
9163
|
+
|
|
9145
9164
|
Options
|
|
9146
9165
|
${getFlagListOutput(config.flags, 6)}
|
|
9147
9166
|
|
|
@@ -9224,7 +9243,6 @@ async function fetchListScans({
|
|
|
9224
9243
|
spinner.successAndStop(`Received response for list of scans.`)
|
|
9225
9244
|
if (!result.success) {
|
|
9226
9245
|
handleUnsuccessfulApiResponse('getOrgFullScanList', result)
|
|
9227
|
-
return
|
|
9228
9246
|
}
|
|
9229
9247
|
return result.data
|
|
9230
9248
|
}
|
|
@@ -9345,6 +9363,10 @@ const config$5 = {
|
|
|
9345
9363
|
Usage
|
|
9346
9364
|
$ ${command} <org slug>
|
|
9347
9365
|
|
|
9366
|
+
API Token Requirements
|
|
9367
|
+
- Quota: 1 unit
|
|
9368
|
+
- Permissions: full-scans:list
|
|
9369
|
+
|
|
9348
9370
|
Options
|
|
9349
9371
|
${getFlagListOutput(config.flags, 6)}
|
|
9350
9372
|
|
|
@@ -9423,7 +9445,6 @@ async function fetchScanMetadata(orgSlug, scanId) {
|
|
|
9423
9445
|
spinner.successAndStop('Received response for scan meta data.')
|
|
9424
9446
|
if (!result.success) {
|
|
9425
9447
|
handleUnsuccessfulApiResponse('getOrgFullScanMetadata', result)
|
|
9426
|
-
return
|
|
9427
9448
|
}
|
|
9428
9449
|
return result.data
|
|
9429
9450
|
}
|
|
@@ -9485,6 +9506,10 @@ const config$4 = {
|
|
|
9485
9506
|
Usage
|
|
9486
9507
|
$ ${command} <org slug> <scan id>
|
|
9487
9508
|
|
|
9509
|
+
API Token Requirements
|
|
9510
|
+
- Quota: 1 unit
|
|
9511
|
+
- Permissions: full-scans:list
|
|
9512
|
+
|
|
9488
9513
|
Options
|
|
9489
9514
|
${getFlagListOutput(config.flags, 6)}
|
|
9490
9515
|
|
|
@@ -9556,14 +9581,8 @@ async function run$4(argv, importMeta, { parentName }) {
|
|
|
9556
9581
|
/**
|
|
9557
9582
|
* This fetches all the relevant pieces of data to generate a report, given a
|
|
9558
9583
|
* full scan ID.
|
|
9559
|
-
* It can optionally only fetch the security or license side of things.
|
|
9560
9584
|
*/
|
|
9561
|
-
async function fetchReportData(
|
|
9562
|
-
orgSlug,
|
|
9563
|
-
scanId,
|
|
9564
|
-
// includeLicensePolicy: boolean,
|
|
9565
|
-
includeSecurityPolicy
|
|
9566
|
-
) {
|
|
9585
|
+
async function fetchReportData(orgSlug, scanId, includeLicensePolicy) {
|
|
9567
9586
|
const apiToken = shadowNpmInject.getDefaultToken()
|
|
9568
9587
|
if (!apiToken) {
|
|
9569
9588
|
throw new shadowNpmInject.AuthError(
|
|
@@ -9572,7 +9591,6 @@ async function fetchReportData(
|
|
|
9572
9591
|
}
|
|
9573
9592
|
const sockSdk = await shadowNpmInject.setupSdk(apiToken)
|
|
9574
9593
|
let haveScan = false
|
|
9575
|
-
// let haveLicensePolicy = false
|
|
9576
9594
|
let haveSecurityPolicy = false
|
|
9577
9595
|
|
|
9578
9596
|
// Lazily access constants.spinner.
|
|
@@ -9580,48 +9598,26 @@ async function fetchReportData(
|
|
|
9580
9598
|
function updateProgress() {
|
|
9581
9599
|
const needs = [
|
|
9582
9600
|
!haveScan ? 'scan' : undefined,
|
|
9583
|
-
|
|
9584
|
-
includeSecurityPolicy && !haveSecurityPolicy
|
|
9585
|
-
? 'security policy'
|
|
9586
|
-
: undefined
|
|
9601
|
+
!haveSecurityPolicy ? 'security policy' : undefined
|
|
9587
9602
|
].filter(Boolean)
|
|
9588
|
-
if (needs.length > 2) {
|
|
9589
|
-
// .toOxford()
|
|
9590
|
-
needs[needs.length - 1] = `and ${needs[needs.length - 1]}`
|
|
9591
|
-
}
|
|
9592
9603
|
const haves = [
|
|
9593
9604
|
haveScan ? 'scan' : undefined,
|
|
9594
|
-
|
|
9595
|
-
includeSecurityPolicy && haveSecurityPolicy
|
|
9596
|
-
? 'security policy'
|
|
9597
|
-
: undefined
|
|
9605
|
+
haveSecurityPolicy ? 'security policy' : undefined
|
|
9598
9606
|
].filter(Boolean)
|
|
9599
|
-
if (haves.length > 2) {
|
|
9600
|
-
// .toOxford()
|
|
9601
|
-
haves[haves.length - 1] = `and ${haves[haves.length - 1]}`
|
|
9602
|
-
}
|
|
9603
9607
|
if (needs.length) {
|
|
9604
9608
|
spinner.start(
|
|
9605
|
-
`Fetching ${needs.join(
|
|
9609
|
+
`Fetching ${needs.join(' and ')}...${haves.length ? ` Completed fetching ${haves.join(' and ')}.` : ''}`
|
|
9606
9610
|
)
|
|
9607
9611
|
} else {
|
|
9608
|
-
spinner.successAndStop(
|
|
9609
|
-
`Completed fetching ${haves.join(haves.length > 2 ? ', ' : ' and ')}.`
|
|
9610
|
-
)
|
|
9612
|
+
spinner.successAndStop(`Completed fetching ${haves.join(' and ')}.`)
|
|
9611
9613
|
}
|
|
9612
9614
|
}
|
|
9613
9615
|
updateProgress()
|
|
9614
|
-
|
|
9615
|
-
// @ts-ignore
|
|
9616
|
-
const [
|
|
9617
|
-
scan,
|
|
9618
|
-
// licensePolicyMaybe,
|
|
9619
|
-
securityPolicyMaybe
|
|
9620
|
-
] = await Promise.all([
|
|
9616
|
+
const [scan, securityPolicyMaybe] = await Promise.all([
|
|
9621
9617
|
(async () => {
|
|
9622
9618
|
try {
|
|
9623
9619
|
const response = await queryApi(
|
|
9624
|
-
`orgs/${orgSlug}/full-scans/${encodeURIComponent(scanId)}`,
|
|
9620
|
+
`orgs/${orgSlug}/full-scans/${encodeURIComponent(scanId)}${includeLicensePolicy ? '?include_license_details=true' : ''}`,
|
|
9625
9621
|
apiToken
|
|
9626
9622
|
)
|
|
9627
9623
|
haveScan = true
|
|
@@ -9647,32 +9643,16 @@ async function fetchReportData(
|
|
|
9647
9643
|
})
|
|
9648
9644
|
return data
|
|
9649
9645
|
} catch (e) {
|
|
9650
|
-
spinner.errorAndStop(
|
|
9651
|
-
'There was an issue while fetching full scan data.'
|
|
9652
|
-
)
|
|
9646
|
+
spinner.errorAndStop('There was an issue while fetching full scan data')
|
|
9653
9647
|
throw e
|
|
9654
9648
|
}
|
|
9655
9649
|
})(),
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
|
|
9660
|
-
|
|
9661
|
-
|
|
9662
|
-
// r,
|
|
9663
|
-
// "looking up organization's license policy"
|
|
9664
|
-
// )
|
|
9665
|
-
// })(),
|
|
9666
|
-
includeSecurityPolicy &&
|
|
9667
|
-
(async () => {
|
|
9668
|
-
const r = await sockSdk.getOrgSecurityPolicy(orgSlug)
|
|
9669
|
-
haveSecurityPolicy = true
|
|
9670
|
-
updateProgress()
|
|
9671
|
-
return await handleApiCall(
|
|
9672
|
-
r,
|
|
9673
|
-
"looking up organization's security policy"
|
|
9674
|
-
)
|
|
9675
|
-
})()
|
|
9650
|
+
(async () => {
|
|
9651
|
+
const r = await sockSdk.getOrgSecurityPolicy(orgSlug)
|
|
9652
|
+
haveSecurityPolicy = true
|
|
9653
|
+
updateProgress()
|
|
9654
|
+
return await handleApiCall(r, "looking up organization's security policy")
|
|
9655
|
+
})()
|
|
9676
9656
|
]).finally(() => spinner.stop())
|
|
9677
9657
|
if (!Array.isArray(scan)) {
|
|
9678
9658
|
logger.logger.error('Was unable to fetch scan, bailing')
|
|
@@ -9680,55 +9660,30 @@ async function fetchReportData(
|
|
|
9680
9660
|
return {
|
|
9681
9661
|
ok: false,
|
|
9682
9662
|
scan: undefined,
|
|
9683
|
-
// licensePolicy: undefined,
|
|
9684
9663
|
securityPolicy: undefined
|
|
9685
9664
|
}
|
|
9686
9665
|
}
|
|
9687
|
-
|
|
9688
|
-
// // Note: security->license once the api ships in the sdk
|
|
9689
|
-
// let licensePolicy: undefined | SocketSdkReturnType<'getOrgSecurityPolicy'> =
|
|
9690
|
-
// undefined
|
|
9691
|
-
// if (includeLicensePolicy) {
|
|
9692
|
-
// if (licensePolicyMaybe && licensePolicyMaybe.success) {
|
|
9693
|
-
// licensePolicy = licensePolicyMaybe
|
|
9694
|
-
// } else {
|
|
9695
|
-
// logger.error('Was unable to fetch license policy, bailing')
|
|
9696
|
-
// process.exitCode = 1
|
|
9697
|
-
// return {
|
|
9698
|
-
// ok: false,
|
|
9699
|
-
// scan: undefined,
|
|
9700
|
-
// licensePolicy: undefined,
|
|
9701
|
-
// securityPolicy: undefined
|
|
9702
|
-
// }
|
|
9703
|
-
// }
|
|
9704
|
-
// }
|
|
9705
|
-
|
|
9706
9666
|
let securityPolicy = undefined
|
|
9707
|
-
if (
|
|
9708
|
-
|
|
9709
|
-
|
|
9710
|
-
|
|
9711
|
-
|
|
9712
|
-
|
|
9713
|
-
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
// licensePolicy: undefined,
|
|
9717
|
-
securityPolicy: undefined
|
|
9718
|
-
}
|
|
9667
|
+
if (securityPolicyMaybe && securityPolicyMaybe.success) {
|
|
9668
|
+
securityPolicy = securityPolicyMaybe
|
|
9669
|
+
} else {
|
|
9670
|
+
logger.logger.error('Was unable to fetch security policy, bailing')
|
|
9671
|
+
process.exitCode = 1
|
|
9672
|
+
return {
|
|
9673
|
+
ok: false,
|
|
9674
|
+
scan: undefined,
|
|
9675
|
+
securityPolicy: undefined
|
|
9719
9676
|
}
|
|
9720
9677
|
}
|
|
9721
9678
|
return {
|
|
9722
9679
|
ok: true,
|
|
9723
9680
|
scan,
|
|
9724
|
-
// licensePolicy,
|
|
9725
9681
|
securityPolicy
|
|
9726
9682
|
}
|
|
9727
9683
|
}
|
|
9728
9684
|
|
|
9729
9685
|
function generateReport(
|
|
9730
9686
|
scan,
|
|
9731
|
-
_licensePolicy,
|
|
9732
9687
|
securityPolicy,
|
|
9733
9688
|
{ fold, orgSlug, reportLevel, scanId, short, spinner }
|
|
9734
9689
|
) {
|
|
@@ -9754,6 +9709,14 @@ function generateReport(
|
|
|
9754
9709
|
// - monitor/ignore: no action
|
|
9755
9710
|
// - defer: unknown (no action)
|
|
9756
9711
|
|
|
9712
|
+
// Note: the server will emit alerts for license policy violations but
|
|
9713
|
+
// those are only included if you set the flag when requesting the scan
|
|
9714
|
+
// data. The alerts map to a single security policy key that determines
|
|
9715
|
+
// what to do with any violation, regardless of the concrete license.
|
|
9716
|
+
// That rule is called "License Policy Violation".
|
|
9717
|
+
// The license policy part is implicitly handled here. Either they are
|
|
9718
|
+
// included and may show up, or they are not and won't show up.
|
|
9719
|
+
|
|
9757
9720
|
const violations = new Map()
|
|
9758
9721
|
let healthy = true
|
|
9759
9722
|
const securityRules = securityPolicy?.data.securityPolicyRules
|
|
@@ -10000,13 +9963,11 @@ function* walkNestedMap(map, keys = []) {
|
|
|
10000
9963
|
|
|
10001
9964
|
async function outputScanReport(
|
|
10002
9965
|
scan,
|
|
10003
|
-
// licensePolicy: undefined | SocketSdkReturnType<'getOrgSecurityPolicy'>,
|
|
10004
9966
|
securityPolicy,
|
|
10005
9967
|
{
|
|
10006
9968
|
filePath,
|
|
10007
9969
|
fold,
|
|
10008
9970
|
includeLicensePolicy,
|
|
10009
|
-
includeSecurityPolicy,
|
|
10010
9971
|
orgSlug,
|
|
10011
9972
|
outputKind,
|
|
10012
9973
|
reportLevel,
|
|
@@ -10014,25 +9975,15 @@ async function outputScanReport(
|
|
|
10014
9975
|
short
|
|
10015
9976
|
}
|
|
10016
9977
|
) {
|
|
10017
|
-
|
|
10018
|
-
|
|
10019
|
-
|
|
10020
|
-
|
|
10021
|
-
|
|
10022
|
-
|
|
10023
|
-
|
|
10024
|
-
|
|
10025
|
-
|
|
10026
|
-
{
|
|
10027
|
-
orgSlug,
|
|
10028
|
-
scanId,
|
|
10029
|
-
fold,
|
|
10030
|
-
reportLevel,
|
|
10031
|
-
short,
|
|
10032
|
-
// Lazily access constants.spinner.
|
|
10033
|
-
spinner: constants.spinner
|
|
10034
|
-
}
|
|
10035
|
-
)
|
|
9978
|
+
const scanReport = generateReport(scan, securityPolicy, {
|
|
9979
|
+
orgSlug,
|
|
9980
|
+
scanId,
|
|
9981
|
+
fold,
|
|
9982
|
+
reportLevel,
|
|
9983
|
+
short,
|
|
9984
|
+
// Lazily access constants.spinner.
|
|
9985
|
+
spinner: constants.spinner
|
|
9986
|
+
})
|
|
10036
9987
|
if (!scanReport.healthy) {
|
|
10037
9988
|
process.exitCode = 1
|
|
10038
9989
|
}
|
|
@@ -10040,7 +9991,9 @@ async function outputScanReport(
|
|
|
10040
9991
|
outputKind === 'json' ||
|
|
10041
9992
|
(outputKind === 'text' && filePath && filePath.endsWith('.json'))
|
|
10042
9993
|
) {
|
|
10043
|
-
const json = short
|
|
9994
|
+
const json = short
|
|
9995
|
+
? JSON.stringify(scanReport)
|
|
9996
|
+
: toJsonReport(scanReport, includeLicensePolicy)
|
|
10044
9997
|
if (filePath !== '-') {
|
|
10045
9998
|
logger.logger.log('Writing json report to', filePath)
|
|
10046
9999
|
return await fs.writeFile(filePath, json)
|
|
@@ -10051,7 +10004,7 @@ async function outputScanReport(
|
|
|
10051
10004
|
if (outputKind === 'markdown' || filePath.endsWith('.md')) {
|
|
10052
10005
|
const md = short
|
|
10053
10006
|
? `healthy = ${scanReport.healthy}`
|
|
10054
|
-
: toMarkdownReport(scanReport)
|
|
10007
|
+
: toMarkdownReport(scanReport, includeLicensePolicy)
|
|
10055
10008
|
if (filePath !== '-') {
|
|
10056
10009
|
logger.logger.log('Writing markdown report to', filePath)
|
|
10057
10010
|
return await fs.writeFile(filePath, md)
|
|
@@ -10067,10 +10020,11 @@ async function outputScanReport(
|
|
|
10067
10020
|
})
|
|
10068
10021
|
}
|
|
10069
10022
|
}
|
|
10070
|
-
function toJsonReport(report) {
|
|
10023
|
+
function toJsonReport(report, includeLicensePolicy) {
|
|
10071
10024
|
const obj = mapToObject(report.alerts)
|
|
10072
10025
|
const json = JSON.stringify(
|
|
10073
10026
|
{
|
|
10027
|
+
includeLicensePolicy,
|
|
10074
10028
|
...report,
|
|
10075
10029
|
alerts: obj
|
|
10076
10030
|
},
|
|
@@ -10079,7 +10033,7 @@ function toJsonReport(report) {
|
|
|
10079
10033
|
)
|
|
10080
10034
|
return json
|
|
10081
10035
|
}
|
|
10082
|
-
function toMarkdownReport(report) {
|
|
10036
|
+
function toMarkdownReport(report, includeLicensePolicy) {
|
|
10083
10037
|
const flatData = Array.from(walkNestedMap(report.alerts)).map(
|
|
10084
10038
|
({ keys, value }) => {
|
|
10085
10039
|
const { manifest, policy, type, url } = value
|
|
@@ -10098,11 +10052,11 @@ function toMarkdownReport(report) {
|
|
|
10098
10052
|
# Scan Policy Report
|
|
10099
10053
|
|
|
10100
10054
|
This report tells you whether the results of a Socket scan results violate the
|
|
10101
|
-
security or license policy set by your organization.
|
|
10055
|
+
security${includeLicensePolicy ? ' or license' : ''} policy set by your organization.
|
|
10102
10056
|
|
|
10103
10057
|
## Health status
|
|
10104
10058
|
|
|
10105
|
-
${report.healthy ?
|
|
10059
|
+
${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.'}
|
|
10106
10060
|
|
|
10107
10061
|
## Settings
|
|
10108
10062
|
|
|
@@ -10112,6 +10066,7 @@ Configuration used to generate this report:
|
|
|
10112
10066
|
- Scan ID: ${report.scanId}
|
|
10113
10067
|
- Alert folding: ${report.options.fold === 'none' ? 'none' : `up to ${report.options.fold}`}
|
|
10114
10068
|
- Minimal policy level for alert to be included in report: ${report.options.reportLevel === 'defer' ? 'everything' : report.options.reportLevel}
|
|
10069
|
+
- Include license alerts: ${includeLicensePolicy ? 'yes' : 'no'}
|
|
10115
10070
|
|
|
10116
10071
|
## Alerts
|
|
10117
10072
|
|
|
@@ -10126,27 +10081,16 @@ async function handleScanReport({
|
|
|
10126
10081
|
filePath,
|
|
10127
10082
|
fold,
|
|
10128
10083
|
includeLicensePolicy,
|
|
10129
|
-
includeSecurityPolicy,
|
|
10130
10084
|
orgSlug,
|
|
10131
10085
|
outputKind,
|
|
10132
10086
|
reportLevel,
|
|
10133
10087
|
scanId,
|
|
10134
10088
|
short
|
|
10135
10089
|
}) {
|
|
10136
|
-
|
|
10137
|
-
process.exitCode = 1
|
|
10138
|
-
return // caller should assert
|
|
10139
|
-
}
|
|
10140
|
-
const {
|
|
10141
|
-
// licensePolicy,
|
|
10142
|
-
ok,
|
|
10143
|
-
scan,
|
|
10144
|
-
securityPolicy
|
|
10145
|
-
} = await fetchReportData(
|
|
10090
|
+
const { ok, scan, securityPolicy } = await fetchReportData(
|
|
10146
10091
|
orgSlug,
|
|
10147
10092
|
scanId,
|
|
10148
|
-
|
|
10149
|
-
includeSecurityPolicy
|
|
10093
|
+
includeLicensePolicy
|
|
10150
10094
|
)
|
|
10151
10095
|
if (!ok) {
|
|
10152
10096
|
return
|
|
@@ -10156,7 +10100,6 @@ async function handleScanReport({
|
|
|
10156
10100
|
fold,
|
|
10157
10101
|
scanId: scanId,
|
|
10158
10102
|
includeLicensePolicy,
|
|
10159
|
-
includeSecurityPolicy,
|
|
10160
10103
|
orgSlug,
|
|
10161
10104
|
outputKind,
|
|
10162
10105
|
reportLevel,
|
|
@@ -10169,8 +10112,7 @@ const config$3 = {
|
|
|
10169
10112
|
commandName: 'report',
|
|
10170
10113
|
description:
|
|
10171
10114
|
'Check whether a scan result passes the organizational policies (security, license)',
|
|
10172
|
-
hidden:
|
|
10173
|
-
// [beta]
|
|
10115
|
+
hidden: false,
|
|
10174
10116
|
flags: {
|
|
10175
10117
|
...commonFlags,
|
|
10176
10118
|
...outputFlags,
|
|
@@ -10189,31 +10131,23 @@ const config$3 = {
|
|
|
10189
10131
|
default: false,
|
|
10190
10132
|
description: 'Report only the healthy status'
|
|
10191
10133
|
},
|
|
10192
|
-
|
|
10193
|
-
// type: 'boolean',
|
|
10194
|
-
// default: true,
|
|
10195
|
-
// description: 'Report the license policy status. Default: true'
|
|
10196
|
-
// },
|
|
10197
|
-
security: {
|
|
10134
|
+
license: {
|
|
10198
10135
|
type: 'boolean',
|
|
10199
|
-
default:
|
|
10200
|
-
description: '
|
|
10136
|
+
default: false,
|
|
10137
|
+
description: 'Also report the license policy status. Default: false'
|
|
10201
10138
|
}
|
|
10202
10139
|
},
|
|
10203
10140
|
help: (command, config) => `
|
|
10204
10141
|
Usage
|
|
10205
10142
|
$ ${command} <org slug> <scan ID> [path to output file]
|
|
10206
10143
|
|
|
10144
|
+
API Token Requirements
|
|
10145
|
+
- Quota: 2 units
|
|
10146
|
+
- Permissions: full-scans:list security-policy:read
|
|
10147
|
+
|
|
10207
10148
|
Options
|
|
10208
10149
|
${getFlagListOutput(config.flags, 6)}
|
|
10209
10150
|
|
|
10210
|
-
This consumes 1 quota unit plus 1 for each of the requested policy types.
|
|
10211
|
-
|
|
10212
|
-
Note: By default it reports both so by default it consumes 3 quota units.
|
|
10213
|
-
|
|
10214
|
-
Your API token will need the \`full-scans:list\` scope regardless. Additionally
|
|
10215
|
-
it needs \`security-policy:read\` to report on the security policy.
|
|
10216
|
-
|
|
10217
10151
|
By default the result is a nested object that looks like this:
|
|
10218
10152
|
\`{[ecosystem]: {[pkgName]: {[version]: {[file]: {[type:loc]: policy}}}}\`
|
|
10219
10153
|
You can fold this up to given level: 'pkg', 'version', 'file', and 'none'.
|
|
@@ -10225,6 +10159,7 @@ const config$3 = {
|
|
|
10225
10159
|
|
|
10226
10160
|
Examples
|
|
10227
10161
|
$ ${command} FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 --json --fold=version
|
|
10162
|
+
$ ${command} FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 --license --markdown --short
|
|
10228
10163
|
`
|
|
10229
10164
|
}
|
|
10230
10165
|
const cmdScanReport = {
|
|
@@ -10242,10 +10177,9 @@ async function run$3(argv, importMeta, { parentName }) {
|
|
|
10242
10177
|
const {
|
|
10243
10178
|
fold = 'none',
|
|
10244
10179
|
json,
|
|
10245
|
-
|
|
10180
|
+
license,
|
|
10246
10181
|
markdown,
|
|
10247
|
-
reportLevel = 'warn'
|
|
10248
|
-
security
|
|
10182
|
+
reportLevel = 'warn'
|
|
10249
10183
|
} = cli.flags
|
|
10250
10184
|
const defaultOrgSlug = shadowNpmInject.getConfigValue('defaultOrg')
|
|
10251
10185
|
const orgSlug = defaultOrgSlug || cli.input[0] || ''
|
|
@@ -10292,9 +10226,7 @@ async function run$3(argv, importMeta, { parentName }) {
|
|
|
10292
10226
|
await handleScanReport({
|
|
10293
10227
|
orgSlug,
|
|
10294
10228
|
scanId: scanId,
|
|
10295
|
-
includeLicensePolicy:
|
|
10296
|
-
// !!license,
|
|
10297
|
-
includeSecurityPolicy: typeof security === 'boolean' ? security : true,
|
|
10229
|
+
includeLicensePolicy: !!license,
|
|
10298
10230
|
outputKind: json ? 'json' : markdown ? 'markdown' : 'text',
|
|
10299
10231
|
filePath: file,
|
|
10300
10232
|
fold: fold,
|
|
@@ -10303,6 +10235,46 @@ async function run$3(argv, importMeta, { parentName }) {
|
|
|
10303
10235
|
})
|
|
10304
10236
|
}
|
|
10305
10237
|
|
|
10238
|
+
async function fetchScan(orgSlug, scanId) {
|
|
10239
|
+
const apiToken = shadowNpmInject.getDefaultToken()
|
|
10240
|
+
if (!apiToken) {
|
|
10241
|
+
throw new shadowNpmInject.AuthError(
|
|
10242
|
+
'User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.'
|
|
10243
|
+
)
|
|
10244
|
+
}
|
|
10245
|
+
|
|
10246
|
+
// Lazily access constants.spinner.
|
|
10247
|
+
const { spinner } = constants
|
|
10248
|
+
spinner.start('Fetching scan data...')
|
|
10249
|
+
const response = await queryApi(
|
|
10250
|
+
`orgs/${orgSlug}/full-scans/${encodeURIComponent(scanId)}`,
|
|
10251
|
+
apiToken
|
|
10252
|
+
)
|
|
10253
|
+
spinner.successAndStop('Received response while fetching scan data.')
|
|
10254
|
+
if (!response.ok) {
|
|
10255
|
+
const err = await handleApiError(response.status)
|
|
10256
|
+
logger.logger.fail(
|
|
10257
|
+
failMsgWithBadge(response.statusText, `Fetch error: ${err}`)
|
|
10258
|
+
)
|
|
10259
|
+
return
|
|
10260
|
+
}
|
|
10261
|
+
|
|
10262
|
+
// This is nd-json; each line is a json object
|
|
10263
|
+
const jsons = await response.text()
|
|
10264
|
+
const lines = jsons.split('\n').filter(Boolean)
|
|
10265
|
+
const data = lines.map(line => {
|
|
10266
|
+
try {
|
|
10267
|
+
return JSON.parse(line)
|
|
10268
|
+
} catch {
|
|
10269
|
+
console.error(
|
|
10270
|
+
'At least one line item was returned that could not be parsed as JSON...'
|
|
10271
|
+
)
|
|
10272
|
+
return {}
|
|
10273
|
+
}
|
|
10274
|
+
})
|
|
10275
|
+
return data
|
|
10276
|
+
}
|
|
10277
|
+
|
|
10306
10278
|
async function outputScanView(artifacts, orgSlug, scanId, filePath) {
|
|
10307
10279
|
const display = artifacts.map(art => {
|
|
10308
10280
|
const author = Array.isArray(art.author)
|
|
@@ -10363,7 +10335,6 @@ async function streamScan(orgSlug, scanId, file) {
|
|
|
10363
10335
|
spinner.successAndStop(`Full scan details written to ${file}`)
|
|
10364
10336
|
if (!data?.success) {
|
|
10365
10337
|
handleUnsuccessfulApiResponse('getOrgFullScan', data)
|
|
10366
|
-
return
|
|
10367
10338
|
}
|
|
10368
10339
|
return data
|
|
10369
10340
|
}
|
|
@@ -10381,6 +10352,10 @@ const config$2 = {
|
|
|
10381
10352
|
Usage
|
|
10382
10353
|
$ ${command} <org slug> <scan ID> [path to output file]
|
|
10383
10354
|
|
|
10355
|
+
API Token Requirements
|
|
10356
|
+
- Quota: 1 unit
|
|
10357
|
+
- Permissions: full-scans:list
|
|
10358
|
+
|
|
10384
10359
|
When no output path is given the contents is sent to stdout.
|
|
10385
10360
|
|
|
10386
10361
|
Options
|
|
@@ -10730,6 +10705,11 @@ const config$1 = {
|
|
|
10730
10705
|
Usage
|
|
10731
10706
|
$ ${command}
|
|
10732
10707
|
|
|
10708
|
+
API Token Requirements
|
|
10709
|
+
- Quota: 1 unit
|
|
10710
|
+
- Permissions: threat-feed:list
|
|
10711
|
+
- Special access
|
|
10712
|
+
|
|
10733
10713
|
This feature requires a Threat Feed license. Please contact
|
|
10734
10714
|
sales@socket.dev if you are interested in purchasing this access.
|
|
10735
10715
|
|
|
@@ -10848,7 +10828,7 @@ function checkSocketWrapperSetup(file) {
|
|
|
10848
10828
|
)
|
|
10849
10829
|
if (linesWithSocketAlias.length) {
|
|
10850
10830
|
logger.logger.log(
|
|
10851
|
-
`The Socket npm/npx wrapper is set up in your bash profile (${file})
|
|
10831
|
+
`The Socket npm/npx wrapper is set up in your bash profile (${file})`
|
|
10852
10832
|
)
|
|
10853
10833
|
return true
|
|
10854
10834
|
}
|
|
@@ -11030,7 +11010,7 @@ void (async () => {
|
|
|
11030
11010
|
await updateNotifier({
|
|
11031
11011
|
name: SOCKET_CLI_BIN_NAME,
|
|
11032
11012
|
// The '@rollup/plugin-replace' will replace "process.env['INLINED_SOCKET_CLI_VERSION']".
|
|
11033
|
-
version: '0.14.
|
|
11013
|
+
version: '0.14.69',
|
|
11034
11014
|
ttl: 86_400_000 /* 24 hours in milliseconds */
|
|
11035
11015
|
})
|
|
11036
11016
|
try {
|
|
@@ -11101,5 +11081,5 @@ void (async () => {
|
|
|
11101
11081
|
await shadowNpmInject.captureException(e)
|
|
11102
11082
|
}
|
|
11103
11083
|
})()
|
|
11104
|
-
//# debugId=
|
|
11084
|
+
//# debugId=aabf095d-4c7e-4f8b-86c6-75307bc026c5
|
|
11105
11085
|
//# sourceMappingURL=cli.js.map
|