@socketsecurity/cli-with-sentry 0.14.63 → 0.14.65

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.
@@ -21,9 +21,6 @@ var arrays = require('@socketsecurity/registry/lib/arrays');
21
21
  var debug = require('@socketsecurity/registry/lib/debug');
22
22
  var objects = require('@socketsecurity/registry/lib/objects');
23
23
  var npa = _socketInterop(require('npm-package-arg'));
24
- var events = require('node:events');
25
- var https = require('node:https');
26
- var readline = require('node:readline');
27
24
  var hpagent = _socketInterop(require('hpagent'));
28
25
  var isInteractive = require('@socketregistry/is-interactive/index.cjs');
29
26
  var registryConstants = require('@socketsecurity/registry/lib/constants');
@@ -75,11 +72,11 @@ function isErrnoException(value) {
75
72
  }
76
73
 
77
74
  const {
78
- abortSignal: abortSignal$2
75
+ abortSignal
79
76
  } = constants;
80
77
  async function findUp(name, {
81
78
  cwd = process$1.cwd(),
82
- signal = abortSignal$2
79
+ signal = abortSignal
83
80
  }) {
84
81
  let dir = path.resolve(cwd);
85
82
  const {
@@ -106,14 +103,14 @@ async function findUp(name, {
106
103
  }
107
104
  async function readFileBinary(filepath, options) {
108
105
  return await fs.promises.readFile(filepath, {
109
- signal: abortSignal$2,
106
+ signal: abortSignal,
110
107
  ...options,
111
108
  encoding: 'binary'
112
109
  });
113
110
  }
114
111
  async function readFileUtf8(filepath, options) {
115
112
  return await fs.promises.readFile(filepath, {
116
- signal: abortSignal$2,
113
+ signal: abortSignal,
117
114
  ...options,
118
115
  encoding: 'utf8'
119
116
  });
@@ -122,7 +119,7 @@ async function safeReadFile(filepath, options) {
122
119
  try {
123
120
  return await fs.promises.readFile(filepath, {
124
121
  encoding: 'utf8',
125
- signal: abortSignal$2,
122
+ signal: abortSignal,
126
123
  ...(typeof options === 'string' ? {
127
124
  encoding: options
128
125
  } : options)
@@ -288,7 +285,7 @@ function getDefaultToken() {
288
285
  return _defaultToken;
289
286
  }
290
287
  function getPublicToken() {
291
- return getDefaultToken() ?? registryConstants.SOCKET_PUBLIC_API_TOKEN;
288
+ return (process$1.env['SOCKET_SECURITY_API_TOKEN'] || getDefaultToken()) ?? registryConstants.SOCKET_PUBLIC_API_TOKEN;
292
289
  }
293
290
  async function setupSdk(apiToken = getDefaultToken(), apiBaseUrl = getDefaultApiBaseUrl(), proxy = getDefaultHttpProxy()) {
294
291
  if (typeof apiToken !== 'string' && isInteractive()) {
@@ -309,7 +306,7 @@ async function setupSdk(apiToken = getDefaultToken(), apiBaseUrl = getDefaultApi
309
306
  // The '@rollup/plugin-replace' will replace "process.env['INLINED_SOCKET_CLI_NAME']".
310
307
  name: "@socketsecurity/cli",
311
308
  // The '@rollup/plugin-replace' will replace "process.env['INLINED_SOCKET_CLI_VERSION']".
312
- version: "0.14.63",
309
+ version: "0.14.65",
313
310
  // The '@rollup/plugin-replace' will replace "process.env['INLINED_SOCKET_CLI_HOMEPAGE']".
314
311
  homepage: "https://github.com/SocketDev/socket-cli"
315
312
  })
@@ -1025,132 +1022,15 @@ const {
1025
1022
  ALERT_TYPE_CRITICAL_CVE,
1026
1023
  ALERT_TYPE_CVE,
1027
1024
  ALERT_TYPE_MEDIUM_CVE,
1028
- ALERT_TYPE_MILD_CVE,
1029
- ALERT_TYPE_SOCKET_UPGRADE_AVAILABLE,
1030
- CVE_ALERT_PROPS_FIRST_PATCHED_VERSION_IDENTIFIER: CVE_ALERT_PROPS_FIRST_PATCHED_VERSION_IDENTIFIER$1,
1031
- CVE_ALERT_PROPS_VULNERABLE_VERSION_RANGE,
1032
- abortSignal: abortSignal$1
1025
+ ALERT_TYPE_MILD_CVE
1033
1026
  } = constants;
1034
- async function* createBatchGenerator(chunk) {
1035
- // Adds the first 'abort' listener to abortSignal.
1036
- const req = https
1037
- // Lazily access constants.BATCH_PURL_ENDPOINT.
1038
- .request(constants.BATCH_PURL_ENDPOINT, {
1039
- method: 'POST',
1040
- headers: {
1041
- Authorization: `Basic ${btoa(`${getPublicToken()}:`)}`
1042
- }
1043
- // TODO: Fix to not abort process on network abort.
1044
- // signal: abortSignal
1045
- }).end(JSON.stringify({
1046
- components: chunk.map(id => ({
1047
- purl: `pkg:npm/${id}`
1048
- }))
1049
- }));
1050
- // Adds the second 'abort' listener to abortSignal.
1051
- const {
1052
- 0: res
1053
- } = await events.once(req, 'response', {
1054
- signal: abortSignal$1
1055
- });
1056
- const ok = res.statusCode >= 200 && res.statusCode <= 299;
1057
- if (!ok) {
1058
- throw new Error(`Socket API Error: ${res.statusCode}`);
1059
- }
1060
- const rli = readline.createInterface({
1061
- input: res,
1062
- crlfDelay: Infinity,
1063
- signal: abortSignal$1
1064
- });
1065
- for await (const line of rli) {
1066
- yield JSON.parse(line);
1067
- }
1068
- }
1069
- async function* batchScan(pkgIds, concurrencyLimit = 50) {
1070
- // The createBatchGenerator method will add 2 'abort' event listeners to
1071
- // abortSignal so we multiply the concurrencyLimit by 2.
1072
- const neededMaxListeners = concurrencyLimit * 2;
1073
- // Increase abortSignal max listeners count to avoid Node's MaxListenersExceededWarning.
1074
- const oldAbortSignalMaxListeners = events.getMaxListeners(abortSignal$1);
1075
- let abortSignalMaxListeners = oldAbortSignalMaxListeners;
1076
- if (oldAbortSignalMaxListeners < neededMaxListeners) {
1077
- abortSignalMaxListeners = oldAbortSignalMaxListeners + neededMaxListeners;
1078
- events.setMaxListeners(abortSignalMaxListeners, abortSignal$1);
1079
- }
1080
- const {
1081
- length: pkgIdsCount
1082
- } = pkgIds;
1083
- const running = [];
1084
- let index = 0;
1085
- const enqueueGen = () => {
1086
- if (index >= pkgIdsCount) {
1087
- // No more work to do.
1088
- return;
1089
- }
1090
- const chunk = pkgIds.slice(index, index + 25);
1091
- index += 25;
1092
- const generator = createBatchGenerator(chunk);
1093
- continueGen(generator);
1094
- };
1095
- const continueGen = generator => {
1096
- let resolveFn;
1097
- running.push({
1098
- generator,
1099
- promise: new Promise(resolve => resolveFn = resolve)
1100
- });
1101
- void generator.next().then(res => resolveFn({
1102
- generator,
1103
- iteratorResult: res
1104
- }));
1105
- };
1106
- // Start initial batch of generators.
1107
- while (running.length < concurrencyLimit && index < pkgIdsCount) {
1108
- enqueueGen();
1109
- }
1110
- while (running.length > 0) {
1111
- // eslint-disable-next-line no-await-in-loop
1112
- const {
1113
- generator,
1114
- iteratorResult
1115
- } = await Promise.race(running.map(entry => entry.promise));
1116
- // Remove generator.
1117
- running.splice(running.findIndex(entry => entry.generator === generator), 1);
1118
- if (iteratorResult.done) {
1119
- // Start a new generator if available.
1120
- enqueueGen();
1121
- } else {
1122
- yield iteratorResult.value;
1123
- // Keep fetching values from this generator.
1124
- continueGen(generator);
1125
- }
1126
- }
1127
- // Reset abortSignal max listeners count.
1128
- if (abortSignalMaxListeners > oldAbortSignalMaxListeners) {
1129
- events.setMaxListeners(oldAbortSignalMaxListeners, abortSignal$1);
1130
- }
1131
- }
1132
1027
  function isArtifactAlertCve(alert) {
1133
1028
  const {
1134
1029
  type
1135
1030
  } = alert;
1136
1031
  return type === ALERT_TYPE_CVE || type === ALERT_TYPE_MEDIUM_CVE || type === ALERT_TYPE_MILD_CVE || type === ALERT_TYPE_CRITICAL_CVE;
1137
1032
  }
1138
- function isArtifactAlertCveFixable(alert) {
1139
- if (!isArtifactAlertCve(alert)) {
1140
- return false;
1141
- }
1142
- const {
1143
- props
1144
- } = alert;
1145
- return !!props?.[CVE_ALERT_PROPS_FIRST_PATCHED_VERSION_IDENTIFIER$1] && !!props?.[CVE_ALERT_PROPS_VULNERABLE_VERSION_RANGE];
1146
- }
1147
- function isArtifactAlertUpgrade(alert) {
1148
- return alert.type === ALERT_TYPE_SOCKET_UPGRADE_AVAILABLE;
1149
- }
1150
1033
 
1151
- const {
1152
- abortSignal
1153
- } = constants;
1154
1034
  const ERROR_UX = {
1155
1035
  block: true,
1156
1036
  display: true
@@ -1283,83 +1163,74 @@ function createAlertUXLookup(settings) {
1283
1163
  }
1284
1164
  let _uxLookup;
1285
1165
  async function uxLookup(settings) {
1286
- while (_uxLookup === undefined) {
1287
- // eslint-disable-next-line no-await-in-loop
1288
- await promises.setTimeout(1, {
1289
- signal: abortSignal
1290
- });
1291
- }
1292
- return _uxLookup(settings);
1293
- }
1294
-
1295
- // Start initializing the AlertUxLookupResult immediately.
1296
- void (async () => {
1297
- const {
1298
- orgs,
1299
- settings
1300
- } = await (async () => {
1301
- try {
1302
- const sockSdk = await setupSdk(getPublicToken());
1303
- const orgResult = await sockSdk.getOrganizations();
1304
- if (!orgResult.success) {
1305
- throw new Error(`Failed to fetch Socket organization info: ${orgResult.error.message}`);
1306
- }
1307
- const orgs = [];
1308
- for (const org of Object.values(orgResult.data.organizations)) {
1309
- if (org) {
1310
- orgs.push(org);
1166
+ if (_uxLookup === undefined) {
1167
+ const {
1168
+ orgs,
1169
+ settings
1170
+ } = await (async () => {
1171
+ try {
1172
+ const sockSdk = await setupSdk(getPublicToken());
1173
+ const orgResult = await sockSdk.getOrganizations();
1174
+ if (!orgResult.success) {
1175
+ throw new Error(`Failed to fetch Socket organization info: ${orgResult.error.message}`);
1311
1176
  }
1177
+ const orgs = [];
1178
+ for (const org of Object.values(orgResult.data.organizations)) {
1179
+ if (org) {
1180
+ orgs.push(org);
1181
+ }
1182
+ }
1183
+ const result = await sockSdk.postSettings(orgs.map(org => ({
1184
+ organization: org.id
1185
+ })));
1186
+ if (!result.success) {
1187
+ throw new Error(`Failed to fetch API key settings: ${result.error.message}`);
1188
+ }
1189
+ return {
1190
+ orgs,
1191
+ settings: result.data
1192
+ };
1193
+ } catch (e) {
1194
+ const cause = objects.isObject(e) && 'cause' in e ? e['cause'] : undefined;
1195
+ if (isErrnoException(cause) && (cause.code === 'ENOTFOUND' || cause.code === 'ECONNREFUSED')) {
1196
+ throw new Error('Unable to connect to socket.dev, ensure internet connectivity before retrying', {
1197
+ cause: e
1198
+ });
1199
+ }
1200
+ throw e;
1312
1201
  }
1313
- const result = await sockSdk.postSettings(orgs.map(org => ({
1314
- organization: org.id
1315
- })));
1316
- if (!result.success) {
1317
- throw new Error(`Failed to fetch API key settings: ${result.error.message}`);
1318
- }
1319
- return {
1320
- orgs,
1321
- settings: result.data
1322
- };
1323
- } catch (e) {
1324
- const cause = objects.isObject(e) && 'cause' in e ? e['cause'] : undefined;
1325
- if (isErrnoException(cause) && (cause.code === 'ENOTFOUND' || cause.code === 'ECONNREFUSED')) {
1326
- throw new Error('Unable to connect to socket.dev, ensure internet connectivity before retrying', {
1327
- cause: e
1328
- });
1202
+ })();
1203
+ // Remove any organizations not being enforced.
1204
+ const enforcedOrgs = getSetting('enforcedOrgs') ?? [];
1205
+ for (const {
1206
+ 0: i,
1207
+ 1: org
1208
+ } of orgs.entries()) {
1209
+ if (!enforcedOrgs.includes(org.id)) {
1210
+ settings.entries.splice(i, 1);
1329
1211
  }
1330
- throw e;
1331
1212
  }
1332
- })();
1333
-
1334
- // Remove any organizations not being enforced.
1335
- const enforcedOrgs = getSetting('enforcedOrgs') ?? [];
1336
- for (const {
1337
- 0: i,
1338
- 1: org
1339
- } of orgs.entries()) {
1340
- if (!enforcedOrgs.includes(org.id)) {
1341
- settings.entries.splice(i, 1);
1342
- }
1343
- }
1344
- const socketYml = findSocketYmlSync();
1345
- if (socketYml) {
1346
- settings.entries.push({
1347
- start: socketYml.path,
1348
- settings: {
1349
- [socketYml.path]: {
1350
- deferTo: null,
1351
- // TODO: TypeScript complains about the type not matching. We should
1352
- // figure out why are providing
1353
- // issueRules: { [issueName: string]: boolean }
1354
- // but expecting
1355
- // issueRules: { [issueName: string]: { action: 'defer' | 'error' | 'ignore' | 'monitor' | 'warn' } }
1356
- issueRules: socketYml.parsed.issueRules
1213
+ const socketYml = findSocketYmlSync();
1214
+ if (socketYml) {
1215
+ settings.entries.push({
1216
+ start: socketYml.path,
1217
+ settings: {
1218
+ [socketYml.path]: {
1219
+ deferTo: null,
1220
+ // TODO: TypeScript complains about the type not matching. We should
1221
+ // figure out why are providing
1222
+ // issueRules: { [issueName: string]: boolean }
1223
+ // but expecting
1224
+ // issueRules: { [issueName: string]: { action: 'defer' | 'error' | 'ignore' | 'monitor' | 'warn' } }
1225
+ issueRules: socketYml.parsed.issueRules
1226
+ }
1357
1227
  }
1358
- }
1359
- });
1228
+ });
1229
+ }
1230
+ _uxLookup = createAlertUXLookup(settings);
1360
1231
  }
1361
- _uxLookup = createAlertUXLookup(settings);
1362
- })();
1232
+ return _uxLookup(settings);
1233
+ }
1363
1234
 
1364
1235
  function pick(input, keys) {
1365
1236
  const result = {};
@@ -1488,6 +1359,8 @@ function getTranslations() {
1488
1359
  }
1489
1360
 
1490
1361
  const {
1362
+ ALERT_FIX_TYPE_CVE,
1363
+ ALERT_FIX_TYPE_UPGRADE,
1491
1364
  CVE_ALERT_PROPS_FIRST_PATCHED_VERSION_IDENTIFIER,
1492
1365
  NPM: NPM$2
1493
1366
  } = constants;
@@ -1531,10 +1404,11 @@ async function addArtifactToAlertsMap(artifact, alertsByPkgId, options) {
1531
1404
  type: alert.type
1532
1405
  }
1533
1406
  });
1407
+ const fixType = alert.fix?.type ?? '';
1534
1408
  const critical = alert.severity === SEVERITY.critical;
1535
1409
  const cve = isArtifactAlertCve(alert);
1536
- const fixableCve = isArtifactAlertCveFixable(alert);
1537
- const fixableUpgrade = isArtifactAlertUpgrade(alert);
1410
+ const fixableCve = fixType === ALERT_FIX_TYPE_CVE;
1411
+ const fixableUpgrade = fixType === ALERT_FIX_TYPE_UPGRADE;
1538
1412
  const fixable = fixableCve || fixableUpgrade;
1539
1413
  const upgrade = fixableUpgrade && !objects.hasOwn(overrides, name);
1540
1414
  if (include.cve && cve || include.unfixable && !fixable || include.critical && critical || include.upgrade && upgrade) {
@@ -1560,8 +1434,10 @@ async function addArtifactToAlertsMap(artifact, alertsByPkgId, options) {
1560
1434
  const highestForUpgrade = new Map();
1561
1435
  const unfixableAlerts = [];
1562
1436
  for (const sockPkgAlert of sockPkgAlerts) {
1563
- if (isArtifactAlertCveFixable(sockPkgAlert.raw)) {
1564
- const patchedVersion = sockPkgAlert.raw.props[CVE_ALERT_PROPS_FIRST_PATCHED_VERSION_IDENTIFIER];
1437
+ const alert = sockPkgAlert.raw;
1438
+ const fixType = alert.fix?.type ?? '';
1439
+ if (fixType === ALERT_FIX_TYPE_CVE) {
1440
+ const patchedVersion = alert.props[CVE_ALERT_PROPS_FIRST_PATCHED_VERSION_IDENTIFIER];
1565
1441
  const patchedMajor = semver.major(patchedVersion);
1566
1442
  const oldHighest = highestForCve.get(patchedMajor);
1567
1443
  const highest = oldHighest?.version ?? '0.0.0';
@@ -1571,7 +1447,7 @@ async function addArtifactToAlertsMap(artifact, alertsByPkgId, options) {
1571
1447
  version: patchedVersion
1572
1448
  });
1573
1449
  }
1574
- } else if (isArtifactAlertUpgrade(sockPkgAlert.raw)) {
1450
+ } else if (fixType === ALERT_FIX_TYPE_UPGRADE) {
1575
1451
  const oldHighest = highestForUpgrade.get(major);
1576
1452
  const highest = oldHighest?.version ?? '0.0.0';
1577
1453
  if (semver.gt(version, highest)) {
@@ -1601,11 +1477,12 @@ function getCveInfoByAlertsMap(alertsMap, options) {
1601
1477
  }.exclude
1602
1478
  };
1603
1479
  let infoByPkg = null;
1604
- for (const [pkgId, alerts] of alertsMap) {
1480
+ for (const [pkgId, sockPkgAlerts] of alertsMap) {
1605
1481
  const purlObj = packageurlJs.PackageURL.fromString(`pkg:npm/${pkgId}`);
1606
1482
  const name = packages.resolvePackageName(purlObj);
1607
- for (const alert of alerts) {
1608
- if (!isArtifactAlertCveFixable(alert.raw) || exclude.upgrade && registry.getManifestData(NPM$2, name)) {
1483
+ for (const sockPkgAlert of sockPkgAlerts) {
1484
+ const alert = sockPkgAlert.raw;
1485
+ if (alert.fix?.type !== ALERT_FIX_TYPE_CVE || exclude.upgrade && registry.getManifestData(NPM$2, name)) {
1609
1486
  continue;
1610
1487
  }
1611
1488
  if (!infoByPkg) {
@@ -1619,7 +1496,7 @@ function getCveInfoByAlertsMap(alertsMap, options) {
1619
1496
  const {
1620
1497
  firstPatchedVersionIdentifier,
1621
1498
  vulnerableVersionRange
1622
- } = alert.raw.props;
1499
+ } = alert.props;
1623
1500
  infos.push({
1624
1501
  firstPatchedVersionIdentifier,
1625
1502
  vulnerableVersionRange: new semver.Range(vulnerableVersionRange).format()
@@ -1805,6 +1682,7 @@ async function getAlertsMapFromArborist(arb, options) {
1805
1682
  const include = {
1806
1683
  __proto__: null,
1807
1684
  existing: false,
1685
+ unfixable: true,
1808
1686
  ..._include
1809
1687
  };
1810
1688
  const needInfoOn = getDetailsFromDiff(arb.diff, {
@@ -1829,12 +1707,23 @@ async function getAlertsMapFromArborist(arb, options) {
1829
1707
  return [key, overrideSet.value];
1830
1708
  }));
1831
1709
  }
1710
+ const socketSdk = await setupSdk(getPublicToken());
1832
1711
  const toAlertsMapOptions = {
1833
1712
  overrides,
1834
1713
  ...options
1835
1714
  };
1836
- for await (const artifact of batchScan(pkgIds)) {
1837
- await addArtifactToAlertsMap(artifact, alertsByPkgId, toAlertsMapOptions);
1715
+ for await (const batchPackageFetchResult of socketSdk.batchPackageStream({
1716
+ alerts: 'true',
1717
+ compact: 'true',
1718
+ fixable: include.unfixable ? 'false' : 'true'
1719
+ }, {
1720
+ components: pkgIds.map(id => ({
1721
+ purl: `pkg:npm/${id}`
1722
+ }))
1723
+ })) {
1724
+ if (batchPackageFetchResult.success) {
1725
+ await addArtifactToAlertsMap(batchPackageFetchResult.data, alertsByPkgId, toAlertsMapOptions);
1726
+ }
1838
1727
  remaining -= 1;
1839
1728
  if (spinner && remaining > 0) {
1840
1729
  spinner.start();
@@ -2029,7 +1918,6 @@ exports.SAFE_ARBORIST_REIFY_OPTIONS_OVERRIDES = SAFE_ARBORIST_REIFY_OPTIONS_OVER
2029
1918
  exports.SEVERITY = SEVERITY;
2030
1919
  exports.SafeArborist = SafeArborist;
2031
1920
  exports.addArtifactToAlertsMap = addArtifactToAlertsMap;
2032
- exports.batchScan = batchScan;
2033
1921
  exports.captureException = captureException;
2034
1922
  exports.findBestPatchVersion = findBestPatchVersion;
2035
1923
  exports.findPackageNodes = findPackageNodes;
@@ -2049,5 +1937,5 @@ exports.safeReadFile = safeReadFile;
2049
1937
  exports.setupSdk = setupSdk;
2050
1938
  exports.updateNode = updateNode;
2051
1939
  exports.updateSetting = updateSetting;
2052
- //# debugId=2af8fb11-075f-445a-9006-b004c848e12b
1940
+ //# debugId=10ac7b59-9e2e-4a6a-88ed-ed401e2c65fd
2053
1941
  //# sourceMappingURL=shadow-npm-inject.js.map