@socketsecurity/cli-with-sentry 1.0.111 → 1.1.0
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/cli.js +148 -1295
- package/dist/cli.js.map +1 -1
- package/dist/constants.js +6 -5
- package/dist/constants.js.map +1 -1
- package/dist/shadow-npm-bin.js +10 -4
- package/dist/shadow-npm-bin.js.map +1 -1
- package/dist/shadow-npm-inject.js +21 -240
- package/dist/shadow-npm-inject.js.map +1 -1
- package/dist/tsconfig.dts.tsbuildinfo +1 -1
- package/dist/types/commands/fix/cmd-fix.d.mts.map +1 -1
- package/dist/types/commands/fix/coana-fix.d.mts +1 -1
- package/dist/types/commands/fix/coana-fix.d.mts.map +1 -1
- package/dist/types/commands/fix/handle-fix.d.mts +1 -1
- package/dist/types/commands/fix/handle-fix.d.mts.map +1 -1
- package/dist/types/commands/fix/types.d.mts +18 -0
- package/dist/types/commands/fix/types.d.mts.map +1 -0
- package/dist/types/constants.d.mts.map +1 -1
- package/dist/types/shadow/npm/arborist/lib/arborist/index.d.mts.map +1 -1
- package/dist/types/shadow/npm/arborist-helpers.d.mts +1 -1
- package/dist/types/shadow/npm/arborist-helpers.d.mts.map +1 -1
- package/dist/types/shadow/npm/bin.d.mts.map +1 -1
- package/dist/types/utils/alerts-map.d.mts.map +1 -1
- package/dist/types/utils/fs.d.mts +3 -1
- package/dist/types/utils/fs.d.mts.map +1 -1
- package/dist/utils.js +990 -1222
- package/dist/utils.js.map +1 -1
- package/dist/vendor.js +111951 -119286
- package/package.json +6 -6
- package/dist/types/commands/fix/agent-fix.d.mts +0 -42
- package/dist/types/commands/fix/agent-fix.d.mts.map +0 -1
- package/dist/types/commands/fix/get-actual-tree.d.mts +0 -3
- package/dist/types/commands/fix/get-actual-tree.d.mts.map +0 -1
- package/dist/types/commands/fix/npm-fix.d.mts +0 -7
- package/dist/types/commands/fix/npm-fix.d.mts.map +0 -1
- package/dist/types/commands/fix/pnpm-fix.d.mts +0 -7
- package/dist/types/commands/fix/pnpm-fix.d.mts.map +0 -1
- package/dist/types/commands/fix/shared.d.mts +0 -10
- package/dist/types/commands/fix/shared.d.mts.map +0 -1
package/dist/utils.js
CHANGED
|
@@ -19,12 +19,11 @@ var spawn = require('../external/@socketsecurity/registry/lib/spawn');
|
|
|
19
19
|
var fs = require('../external/@socketsecurity/registry/lib/fs');
|
|
20
20
|
var shadowNpmBin = require('./shadow-npm-bin.js');
|
|
21
21
|
var fs$1 = require('node:fs');
|
|
22
|
-
var
|
|
23
|
-
var packages = require('../external/@socketsecurity/registry/lib/packages');
|
|
22
|
+
var promises = require('node:timers/promises');
|
|
24
23
|
var npm = require('../external/@socketsecurity/registry/lib/npm');
|
|
24
|
+
var packages = require('../external/@socketsecurity/registry/lib/packages');
|
|
25
25
|
var streams = require('../external/@socketsecurity/registry/lib/streams');
|
|
26
26
|
var globs = require('../external/@socketsecurity/registry/lib/globs');
|
|
27
|
-
var promises = require('node:timers/promises');
|
|
28
27
|
|
|
29
28
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
30
29
|
const sensitiveConfigKeyLookup = new Set(['apiToken']);
|
|
@@ -2266,13 +2265,6 @@ async function globWithGitIgnore(patterns, options) {
|
|
|
2266
2265
|
}
|
|
2267
2266
|
return filtered;
|
|
2268
2267
|
}
|
|
2269
|
-
async function globStreamNodeModules(cwd = process.cwd()) {
|
|
2270
|
-
return vendor.outExports.globStream('**/node_modules', {
|
|
2271
|
-
absolute: true,
|
|
2272
|
-
cwd,
|
|
2273
|
-
onlyDirectories: true
|
|
2274
|
-
});
|
|
2275
|
-
}
|
|
2276
2268
|
async function globWorkspace(agent, cwd = process.cwd()) {
|
|
2277
2269
|
const workspaceGlobs = await getWorkspaceGlobs(agent, cwd);
|
|
2278
2270
|
return workspaceGlobs.length ? await vendor.outExports.glob(workspaceGlobs, {
|
|
@@ -2496,6 +2488,52 @@ function isHelpFlag(cmdArg) {
|
|
|
2496
2488
|
return helpFlags.has(cmdArg);
|
|
2497
2489
|
}
|
|
2498
2490
|
|
|
2491
|
+
async function findUp(name, options) {
|
|
2492
|
+
const opts = {
|
|
2493
|
+
__proto__: null,
|
|
2494
|
+
...options
|
|
2495
|
+
};
|
|
2496
|
+
const {
|
|
2497
|
+
cwd = process.cwd(),
|
|
2498
|
+
signal = constants.abortSignal
|
|
2499
|
+
} = opts;
|
|
2500
|
+
let {
|
|
2501
|
+
onlyDirectories = false,
|
|
2502
|
+
onlyFiles = true
|
|
2503
|
+
} = opts;
|
|
2504
|
+
if (onlyDirectories) {
|
|
2505
|
+
onlyFiles = false;
|
|
2506
|
+
}
|
|
2507
|
+
if (onlyFiles) {
|
|
2508
|
+
onlyDirectories = false;
|
|
2509
|
+
}
|
|
2510
|
+
let dir = path.resolve(cwd);
|
|
2511
|
+
const {
|
|
2512
|
+
root
|
|
2513
|
+
} = path.parse(dir);
|
|
2514
|
+
const names = [name].flat();
|
|
2515
|
+
while (dir && dir !== root) {
|
|
2516
|
+
for (const name of names) {
|
|
2517
|
+
if (signal?.aborted) {
|
|
2518
|
+
return undefined;
|
|
2519
|
+
}
|
|
2520
|
+
const thePath = path.join(dir, name);
|
|
2521
|
+
try {
|
|
2522
|
+
// eslint-disable-next-line no-await-in-loop
|
|
2523
|
+
const stats = await fs$1.promises.stat(thePath);
|
|
2524
|
+
if (!onlyDirectories && (stats.isFile() || stats.isSymbolicLink())) {
|
|
2525
|
+
return thePath;
|
|
2526
|
+
}
|
|
2527
|
+
if (!onlyFiles && stats.isDirectory()) {
|
|
2528
|
+
return thePath;
|
|
2529
|
+
}
|
|
2530
|
+
} catch {}
|
|
2531
|
+
}
|
|
2532
|
+
dir = path.dirname(dir);
|
|
2533
|
+
}
|
|
2534
|
+
return undefined;
|
|
2535
|
+
}
|
|
2536
|
+
|
|
2499
2537
|
function extractTier1ReachabilityScanId(socketFactsFile) {
|
|
2500
2538
|
const json = fs.readJsonSync(socketFactsFile, {
|
|
2501
2539
|
throws: false
|
|
@@ -2678,1332 +2716,1072 @@ async function writeSocketJson(cwd, sockJson) {
|
|
|
2678
2716
|
};
|
|
2679
2717
|
}
|
|
2680
2718
|
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
}
|
|
2687
|
-
|
|
2688
|
-
function createEnum(obj) {
|
|
2689
|
-
return Object.freeze({
|
|
2690
|
-
__proto__: null,
|
|
2691
|
-
...obj
|
|
2692
|
-
});
|
|
2719
|
+
const RangeStyles = ['caret', 'gt', 'gte', 'lt', 'lte', 'pin', 'preserve', 'tilde'];
|
|
2720
|
+
function getMajor(version) {
|
|
2721
|
+
try {
|
|
2722
|
+
const coerced = vendor.semverExports.coerce(version);
|
|
2723
|
+
return coerced ? vendor.semverExports.major(coerced) : null;
|
|
2724
|
+
} catch {}
|
|
2725
|
+
return null;
|
|
2693
2726
|
}
|
|
2694
2727
|
|
|
2695
|
-
const
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
low: 'low'
|
|
2706
|
-
});
|
|
2707
|
-
|
|
2708
|
-
class ColorOrMarkdown {
|
|
2709
|
-
constructor(useMarkdown) {
|
|
2710
|
-
this.useMarkdown = !!useMarkdown;
|
|
2711
|
-
}
|
|
2712
|
-
bold(text) {
|
|
2713
|
-
return this.useMarkdown ? `**${text}**` : vendor.yoctocolorsCjsExports.bold(`${text}`);
|
|
2714
|
-
}
|
|
2715
|
-
header(text, level = 1) {
|
|
2716
|
-
return this.useMarkdown ? `\n${''.padStart(level, '#')} ${text}\n` : vendor.yoctocolorsCjsExports.underline(`\n${level === 1 ? vendor.yoctocolorsCjsExports.bold(text) : text}\n`);
|
|
2717
|
-
}
|
|
2718
|
-
hyperlink(text, url, {
|
|
2719
|
-
fallback = true,
|
|
2720
|
-
fallbackToUrl
|
|
2721
|
-
} = {}) {
|
|
2722
|
-
if (url) {
|
|
2723
|
-
return this.useMarkdown ? `[${text}](${url})` : vendor.terminalLinkExports(text, url, {
|
|
2724
|
-
fallback: fallbackToUrl ? (_text, url) => url : fallback
|
|
2725
|
-
});
|
|
2726
|
-
}
|
|
2727
|
-
return text;
|
|
2728
|
-
}
|
|
2729
|
-
indent(...args) {
|
|
2730
|
-
return vendor.indentStringExports(...args);
|
|
2731
|
-
}
|
|
2732
|
-
italic(text) {
|
|
2733
|
-
return this.useMarkdown ? `_${text}_` : vendor.yoctocolorsCjsExports.italic(`${text}`);
|
|
2728
|
+
const COMPLETION_CMD_PREFIX = 'complete -F _socket_completion';
|
|
2729
|
+
function getCompletionSourcingCommand() {
|
|
2730
|
+
// Note: this is exported to distPath in .config/rollup.dist.config.mjs
|
|
2731
|
+
const completionScriptExportPath = path.join(constants.distPath, 'socket-completion.bash');
|
|
2732
|
+
if (!fs$1.existsSync(completionScriptExportPath)) {
|
|
2733
|
+
return {
|
|
2734
|
+
ok: false,
|
|
2735
|
+
message: 'Tab Completion script not found',
|
|
2736
|
+
cause: `Expected to find completion script at \`${completionScriptExportPath}\` but it was not there`
|
|
2737
|
+
};
|
|
2734
2738
|
}
|
|
2735
|
-
|
|
2736
|
-
|
|
2739
|
+
return {
|
|
2740
|
+
ok: true,
|
|
2741
|
+
data: `source ${completionScriptExportPath}`
|
|
2742
|
+
};
|
|
2743
|
+
}
|
|
2744
|
+
function getBashrcDetails(targetCommandName) {
|
|
2745
|
+
const sourcingCommand = getCompletionSourcingCommand();
|
|
2746
|
+
if (!sourcingCommand.ok) {
|
|
2747
|
+
return sourcingCommand;
|
|
2737
2748
|
}
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2749
|
+
const {
|
|
2750
|
+
socketAppDataPath
|
|
2751
|
+
} = constants;
|
|
2752
|
+
if (!socketAppDataPath) {
|
|
2753
|
+
return {
|
|
2754
|
+
ok: false,
|
|
2755
|
+
message: 'Could not determine config directory',
|
|
2756
|
+
cause: 'Failed to get config path'
|
|
2757
|
+
};
|
|
2741
2758
|
}
|
|
2742
|
-
}
|
|
2743
2759
|
|
|
2744
|
-
function
|
|
2745
|
-
const
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
const
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2760
|
+
// _socket_completion is the function defined in our completion bash script
|
|
2761
|
+
const completionCommand = `${COMPLETION_CMD_PREFIX} ${targetCommandName}`;
|
|
2762
|
+
|
|
2763
|
+
// Location of completion script in config after installing
|
|
2764
|
+
const completionScriptPath = path.join(path.dirname(socketAppDataPath), 'completion', 'socket-completion.bash');
|
|
2765
|
+
const bashrcContent = `# Socket CLI completion for "${targetCommandName}"
|
|
2766
|
+
if [ -f "${completionScriptPath}" ]; then
|
|
2767
|
+
# Load the tab completion script
|
|
2768
|
+
source "${completionScriptPath}"
|
|
2769
|
+
# Tell bash to use this function for tab completion of this function
|
|
2770
|
+
${completionCommand}
|
|
2771
|
+
fi
|
|
2772
|
+
`;
|
|
2773
|
+
return {
|
|
2774
|
+
ok: true,
|
|
2775
|
+
data: {
|
|
2776
|
+
sourcingCommand: sourcingCommand.data,
|
|
2777
|
+
completionCommand,
|
|
2778
|
+
toAddToBashrc: bashrcContent,
|
|
2779
|
+
targetName: targetCommandName,
|
|
2780
|
+
targetPath: completionScriptPath
|
|
2753
2781
|
}
|
|
2754
|
-
}
|
|
2755
|
-
return normalized;
|
|
2782
|
+
};
|
|
2756
2783
|
}
|
|
2757
2784
|
|
|
2758
|
-
const
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
case 'lte':
|
|
2770
|
-
return `<=${version}`;
|
|
2771
|
-
case 'preserve':
|
|
2772
|
-
{
|
|
2773
|
-
const range = new vendor.semverExports.Range(refRange);
|
|
2774
|
-
const {
|
|
2775
|
-
raw
|
|
2776
|
-
} = range;
|
|
2777
|
-
const comparators = range.set.flat();
|
|
2778
|
-
const {
|
|
2779
|
-
length
|
|
2780
|
-
} = comparators;
|
|
2781
|
-
if (length === 1) {
|
|
2782
|
-
const char = /^[<>]=?/.exec(raw)?.[0];
|
|
2783
|
-
if (char) {
|
|
2784
|
-
return `${char}${version}`;
|
|
2785
|
-
}
|
|
2786
|
-
} else if (length === 2) {
|
|
2787
|
-
const char = /^[~^]/.exec(raw)?.[0];
|
|
2788
|
-
if (char) {
|
|
2789
|
-
return `${char}${version}`;
|
|
2790
|
-
}
|
|
2791
|
-
}
|
|
2792
|
-
return version;
|
|
2793
|
-
}
|
|
2794
|
-
case 'tilde':
|
|
2795
|
-
return `~${version}`;
|
|
2796
|
-
case 'pin':
|
|
2797
|
-
default:
|
|
2798
|
-
return version;
|
|
2785
|
+
const {
|
|
2786
|
+
kInternalsSymbol,
|
|
2787
|
+
[kInternalsSymbol]: {
|
|
2788
|
+
getSentry
|
|
2789
|
+
}
|
|
2790
|
+
} = constants;
|
|
2791
|
+
class AuthError extends Error {}
|
|
2792
|
+
class InputError extends Error {
|
|
2793
|
+
constructor(message, body) {
|
|
2794
|
+
super(message);
|
|
2795
|
+
this.body = body;
|
|
2799
2796
|
}
|
|
2800
2797
|
}
|
|
2801
|
-
function
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2798
|
+
async function captureException(exception, hint) {
|
|
2799
|
+
const result = captureExceptionSync(exception, hint);
|
|
2800
|
+
// "Sleep" for a second, just in case, hopefully enough time to initiate fetch.
|
|
2801
|
+
await promises.setTimeout(1000);
|
|
2802
|
+
return result;
|
|
2803
|
+
}
|
|
2804
|
+
function captureExceptionSync(exception, hint) {
|
|
2805
|
+
const Sentry = getSentry();
|
|
2806
|
+
if (!Sentry) {
|
|
2807
|
+
return '';
|
|
2808
|
+
}
|
|
2809
|
+
require$$9.debugFn('notice', 'send: exception to Sentry');
|
|
2810
|
+
return Sentry.captureException(exception, hint);
|
|
2807
2811
|
}
|
|
2808
|
-
|
|
2812
|
+
|
|
2813
|
+
function npa(...args) {
|
|
2809
2814
|
try {
|
|
2810
|
-
return vendor.
|
|
2815
|
+
return Reflect.apply(vendor.npaExports, undefined, args);
|
|
2811
2816
|
} catch {}
|
|
2812
2817
|
return null;
|
|
2813
2818
|
}
|
|
2814
2819
|
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
}
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
critical: 'magenta',
|
|
2826
|
-
high: 'red',
|
|
2827
|
-
middle: 'yellow',
|
|
2828
|
-
low: 'white'
|
|
2829
|
-
});
|
|
2830
|
-
const ALERT_SEVERITY_ORDER = createEnum({
|
|
2831
|
-
critical: 0,
|
|
2832
|
-
high: 1,
|
|
2833
|
-
middle: 2,
|
|
2834
|
-
low: 3,
|
|
2835
|
-
none: 4
|
|
2836
|
-
});
|
|
2837
|
-
const MIN_ABOVE_THE_FOLD_COUNT = 3;
|
|
2838
|
-
const MIN_ABOVE_THE_FOLD_ALERT_COUNT = 1;
|
|
2839
|
-
const format = new ColorOrMarkdown(false);
|
|
2840
|
-
function getHiddenRiskCounts(hiddenAlerts) {
|
|
2841
|
-
const riskCounts = {
|
|
2842
|
-
critical: 0,
|
|
2843
|
-
high: 0,
|
|
2844
|
-
middle: 0,
|
|
2845
|
-
low: 0
|
|
2820
|
+
function shadowNpmInstall(options) {
|
|
2821
|
+
const {
|
|
2822
|
+
agentExecPath = getNpmBinPath(),
|
|
2823
|
+
args = [],
|
|
2824
|
+
ipc,
|
|
2825
|
+
spinner,
|
|
2826
|
+
...spawnOpts
|
|
2827
|
+
} = {
|
|
2828
|
+
__proto__: null,
|
|
2829
|
+
...options
|
|
2846
2830
|
};
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2831
|
+
const useDebug = require$$9.isDebug('stdio');
|
|
2832
|
+
const terminatorPos = args.indexOf('--');
|
|
2833
|
+
const rawBinArgs = terminatorPos === -1 ? args : args.slice(0, terminatorPos);
|
|
2834
|
+
const binArgs = rawBinArgs.filter(a => !npm.isNpmAuditFlag(a) && !npm.isNpmFundFlag(a) && !npm.isNpmProgressFlag(a));
|
|
2835
|
+
const otherArgs = terminatorPos === -1 ? [] : args.slice(terminatorPos);
|
|
2836
|
+
const progressArg = rawBinArgs.findLast(npm.isNpmProgressFlag) !== '--no-progress';
|
|
2837
|
+
const isSilent = !useDebug && !binArgs.some(npm.isNpmLoglevelFlag);
|
|
2838
|
+
const logLevelArgs = isSilent ? ['--loglevel', 'silent'] : [];
|
|
2839
|
+
const useIpc = require$$10.isObject(ipc);
|
|
2840
|
+
|
|
2841
|
+
// Include 'ipc' in the spawnOpts.stdio when an options.ipc object is provided.
|
|
2842
|
+
// See https://github.com/nodejs/node/blob/v23.6.0/lib/child_process.js#L161-L166
|
|
2843
|
+
// and https://github.com/nodejs/node/blob/v23.6.0/lib/internal/child_process.js#L238.
|
|
2844
|
+
let stdio = require$$10.getOwn(spawnOpts, 'stdio');
|
|
2845
|
+
if (typeof stdio === 'string') {
|
|
2846
|
+
stdio = useIpc ? [stdio, stdio, stdio, 'ipc'] : [stdio, stdio, stdio];
|
|
2847
|
+
} else if (Array.isArray(stdio)) {
|
|
2848
|
+
if (useIpc && !stdio.includes('ipc')) {
|
|
2849
|
+
stdio = stdio.concat('ipc');
|
|
2861
2850
|
}
|
|
2851
|
+
} else {
|
|
2852
|
+
stdio = useIpc ? ['pipe', 'pipe', 'pipe', 'ipc'] : 'pipe';
|
|
2862
2853
|
}
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2854
|
+
const spawnPromise = spawn.spawn(constants.execPath, [...constants.nodeNoWarningsFlags, ...constants.nodeDebugFlags, ...constants.nodeHardenFlags, ...constants.nodeMemoryFlags, ...(constants.ENV.INLINED_SOCKET_CLI_SENTRY_BUILD ? ['--require', constants.instrumentWithSentryPath] : []), '--require', constants.shadowNpmInjectPath, npm.resolveBinPathSync(agentExecPath), 'install',
|
|
2855
|
+
// Avoid code paths for 'audit' and 'fund'.
|
|
2856
|
+
'--no-audit', '--no-fund',
|
|
2857
|
+
// Add '--no-progress' to fix input being swallowed by the npm spinner.
|
|
2858
|
+
'--no-progress',
|
|
2859
|
+
// Add '--loglevel=silent' if a loglevel flag is not provided and the
|
|
2860
|
+
// SOCKET_CLI_DEBUG environment variable is not truthy.
|
|
2861
|
+
...logLevelArgs, ...binArgs, ...otherArgs], {
|
|
2862
|
+
...spawnOpts,
|
|
2863
|
+
env: {
|
|
2864
|
+
...process.env,
|
|
2865
|
+
...constants.processEnv,
|
|
2866
|
+
...require$$10.getOwn(spawnOpts, 'env')
|
|
2867
|
+
},
|
|
2868
|
+
spinner,
|
|
2869
|
+
stdio
|
|
2870
|
+
});
|
|
2871
|
+
if (useIpc) {
|
|
2872
|
+
spawnPromise.process.send({
|
|
2873
|
+
[constants.SOCKET_IPC_HANDSHAKE]: {
|
|
2874
|
+
[constants.SOCKET_CLI_SHADOW_BIN]: 'npm',
|
|
2875
|
+
[constants.SOCKET_CLI_SHADOW_PROGRESS]: progressArg,
|
|
2876
|
+
...ipc
|
|
2877
|
+
}
|
|
2878
|
+
});
|
|
2878
2879
|
}
|
|
2879
|
-
return
|
|
2880
|
+
return spawnPromise;
|
|
2880
2881
|
}
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
if (!artifact.name || !artifact.version || !artifact.alerts?.length) {
|
|
2884
|
-
return alertsByPurl;
|
|
2885
|
-
}
|
|
2882
|
+
|
|
2883
|
+
function runAgentInstall(pkgEnvDetails, options) {
|
|
2886
2884
|
const {
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
} =
|
|
2885
|
+
agent,
|
|
2886
|
+
agentExecPath
|
|
2887
|
+
} = pkgEnvDetails;
|
|
2888
|
+
const isNpm = agent === 'npm';
|
|
2889
|
+
const isPnpm = agent === 'pnpm';
|
|
2890
|
+
// All package managers support the "install" command.
|
|
2891
|
+
if (isNpm) {
|
|
2892
|
+
return shadowNpmInstall({
|
|
2893
|
+
agentExecPath,
|
|
2894
|
+
...options
|
|
2895
|
+
});
|
|
2896
|
+
}
|
|
2890
2897
|
const {
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2898
|
+
args = [],
|
|
2899
|
+
spinner,
|
|
2900
|
+
...spawnOpts
|
|
2894
2901
|
} = {
|
|
2895
2902
|
__proto__: null,
|
|
2896
2903
|
...options
|
|
2897
2904
|
};
|
|
2898
|
-
const
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
...
|
|
2905
|
+
const skipNodeHardenFlags = isPnpm && pkgEnvDetails.agentVersion.major < 11;
|
|
2906
|
+
return spawn.spawn(agentExecPath, ['install', ...args], {
|
|
2907
|
+
shell: constants.WIN32,
|
|
2908
|
+
spinner,
|
|
2909
|
+
stdio: 'inherit',
|
|
2910
|
+
...spawnOpts,
|
|
2911
|
+
env: {
|
|
2912
|
+
...process.env,
|
|
2913
|
+
...constants.processEnv,
|
|
2914
|
+
NODE_OPTIONS: cmdFlagsToString([...(skipNodeHardenFlags ? [] : constants.nodeHardenFlags), ...constants.nodeNoWarningsFlags]),
|
|
2915
|
+
...require$$10.getOwn(spawnOpts, 'env')
|
|
2916
|
+
}
|
|
2904
2917
|
});
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2918
|
+
}
|
|
2919
|
+
|
|
2920
|
+
const {
|
|
2921
|
+
BINARY_LOCK_EXT,
|
|
2922
|
+
BUN,
|
|
2923
|
+
HIDDEN_PACKAGE_LOCK_JSON,
|
|
2924
|
+
LOCK_EXT,
|
|
2925
|
+
NPM,
|
|
2926
|
+
NPM_BUGGY_OVERRIDES_PATCHED_VERSION,
|
|
2927
|
+
PACKAGE_JSON,
|
|
2928
|
+
PNPM,
|
|
2929
|
+
VLT,
|
|
2930
|
+
YARN,
|
|
2931
|
+
YARN_BERRY,
|
|
2932
|
+
YARN_CLASSIC
|
|
2933
|
+
} = constants;
|
|
2934
|
+
const AGENTS = [BUN, NPM, PNPM, YARN_BERRY, YARN_CLASSIC, VLT];
|
|
2935
|
+
const binByAgent = new Map([[BUN, BUN], [NPM, NPM], [PNPM, PNPM], [YARN_BERRY, YARN], [YARN_CLASSIC, YARN], [VLT, VLT]]);
|
|
2936
|
+
const readLockFileByAgent = (() => {
|
|
2937
|
+
function wrapReader(reader) {
|
|
2938
|
+
return async (...args) => {
|
|
2939
|
+
try {
|
|
2940
|
+
return await reader(...args);
|
|
2941
|
+
} catch {}
|
|
2942
|
+
return undefined;
|
|
2943
|
+
};
|
|
2944
|
+
}
|
|
2945
|
+
const binaryReader = wrapReader(fs.readFileBinary);
|
|
2946
|
+
const defaultReader = wrapReader(async lockPath => await fs.readFileUtf8(lockPath));
|
|
2947
|
+
return new Map([[BUN, wrapReader(async (lockPath, agentExecPath, cwd = process.cwd()) => {
|
|
2948
|
+
const ext = path.extname(lockPath);
|
|
2949
|
+
if (ext === LOCK_EXT) {
|
|
2950
|
+
return await defaultReader(lockPath);
|
|
2915
2951
|
}
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
blocked,
|
|
2931
|
-
critical,
|
|
2932
|
-
ecosystem,
|
|
2933
|
-
fixable,
|
|
2934
|
-
raw: alert,
|
|
2935
|
-
upgradable
|
|
2936
|
-
});
|
|
2952
|
+
if (ext === BINARY_LOCK_EXT) {
|
|
2953
|
+
const lockBuffer = await binaryReader(lockPath);
|
|
2954
|
+
if (lockBuffer) {
|
|
2955
|
+
try {
|
|
2956
|
+
return vendor.hyrious__bun_lockbExports.parse(lockBuffer);
|
|
2957
|
+
} catch {}
|
|
2958
|
+
}
|
|
2959
|
+
// To print a Yarn lockfile to your console without writing it to disk
|
|
2960
|
+
// use `bun bun.lockb`.
|
|
2961
|
+
// https://bun.sh/guides/install/yarnlock
|
|
2962
|
+
return (await spawn.spawn(agentExecPath, [lockPath], {
|
|
2963
|
+
cwd,
|
|
2964
|
+
shell: constants.WIN32
|
|
2965
|
+
})).stdout;
|
|
2937
2966
|
}
|
|
2967
|
+
return undefined;
|
|
2968
|
+
})], [NPM, defaultReader], [PNPM, defaultReader], [VLT, defaultReader], [YARN_BERRY, defaultReader], [YARN_CLASSIC, defaultReader]]);
|
|
2969
|
+
})();
|
|
2970
|
+
|
|
2971
|
+
// The order of LOCKS properties IS significant as it affects iteration order.
|
|
2972
|
+
const LOCKS = {
|
|
2973
|
+
[`bun${LOCK_EXT}`]: BUN,
|
|
2974
|
+
[`bun${BINARY_LOCK_EXT}`]: BUN,
|
|
2975
|
+
// If both package-lock.json and npm-shrinkwrap.json are present in the root
|
|
2976
|
+
// of a project, npm-shrinkwrap.json will take precedence and package-lock.json
|
|
2977
|
+
// will be ignored.
|
|
2978
|
+
// https://docs.npmjs.com/cli/v10/configuring-npm/package-lock-json#package-lockjson-vs-npm-shrinkwrapjson
|
|
2979
|
+
'npm-shrinkwrap.json': NPM,
|
|
2980
|
+
'package-lock.json': NPM,
|
|
2981
|
+
'pnpm-lock.yaml': PNPM,
|
|
2982
|
+
'pnpm-lock.yml': PNPM,
|
|
2983
|
+
[`yarn${LOCK_EXT}`]: YARN_CLASSIC,
|
|
2984
|
+
'vlt-lock.json': VLT,
|
|
2985
|
+
// Lastly, look for a hidden lock file which is present if .npmrc has package-lock=false:
|
|
2986
|
+
// https://docs.npmjs.com/cli/v10/configuring-npm/package-lock-json#hidden-lockfiles
|
|
2987
|
+
//
|
|
2988
|
+
// Unlike the other LOCKS keys this key contains a directory AND filename so
|
|
2989
|
+
// it has to be handled differently.
|
|
2990
|
+
'node_modules/.package-lock.json': NPM
|
|
2991
|
+
};
|
|
2992
|
+
async function getAgentExecPath(agent) {
|
|
2993
|
+
const binName = binByAgent.get(agent);
|
|
2994
|
+
if (binName === NPM) {
|
|
2995
|
+
return constants.npmExecPath;
|
|
2938
2996
|
}
|
|
2939
|
-
|
|
2940
|
-
|
|
2997
|
+
return (await vendor.libExports$1(binName, {
|
|
2998
|
+
nothrow: true
|
|
2999
|
+
})) ?? binName;
|
|
3000
|
+
}
|
|
3001
|
+
async function getAgentVersion(agent, agentExecPath, cwd) {
|
|
3002
|
+
let result;
|
|
3003
|
+
const quotedCmd = `\`${agent} --version\``;
|
|
3004
|
+
require$$9.debugFn('stdio', `spawn: ${quotedCmd}`);
|
|
3005
|
+
try {
|
|
3006
|
+
result =
|
|
3007
|
+
// Coerce version output into a valid semver version by passing it through
|
|
3008
|
+
// semver.coerce which strips leading v's, carets (^), comparators (<,<=,>,>=,=),
|
|
3009
|
+
// and tildes (~).
|
|
3010
|
+
vendor.semverExports.coerce(
|
|
3011
|
+
// All package managers support the "--version" flag.
|
|
3012
|
+
(await spawn.spawn(agentExecPath, ['--version'], {
|
|
3013
|
+
cwd,
|
|
3014
|
+
shell: constants.WIN32
|
|
3015
|
+
})).stdout) ?? undefined;
|
|
3016
|
+
} catch (e) {
|
|
3017
|
+
require$$9.debugFn('error', `caught: ${quotedCmd} failed`);
|
|
3018
|
+
require$$9.debugDir('inspect', {
|
|
3019
|
+
error: e
|
|
3020
|
+
});
|
|
2941
3021
|
}
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
const highest = highestForUpgrade.get(major)?.version ?? '0.0.0';
|
|
2974
|
-
if (vendor.semverExports.gt(version, highest)) {
|
|
2975
|
-
highestForUpgrade.set(major, {
|
|
2976
|
-
alert: sockPkgAlert,
|
|
2977
|
-
version
|
|
2978
|
-
});
|
|
2979
|
-
}
|
|
2980
|
-
} else {
|
|
2981
|
-
unfixableAlerts.push(sockPkgAlert);
|
|
3022
|
+
return result;
|
|
3023
|
+
}
|
|
3024
|
+
async function detectPackageEnvironment({
|
|
3025
|
+
cwd = process.cwd(),
|
|
3026
|
+
onUnknown
|
|
3027
|
+
} = {}) {
|
|
3028
|
+
let lockPath = await findUp(Object.keys(LOCKS), {
|
|
3029
|
+
cwd
|
|
3030
|
+
});
|
|
3031
|
+
let lockName = lockPath ? path.basename(lockPath) : undefined;
|
|
3032
|
+
const isHiddenLockFile = lockName === HIDDEN_PACKAGE_LOCK_JSON;
|
|
3033
|
+
const pkgJsonPath = lockPath ? path.resolve(lockPath, `${isHiddenLockFile ? '../' : ''}../${PACKAGE_JSON}`) : await findUp(PACKAGE_JSON, {
|
|
3034
|
+
cwd
|
|
3035
|
+
});
|
|
3036
|
+
const pkgPath = pkgJsonPath && fs$1.existsSync(pkgJsonPath) ? path.dirname(pkgJsonPath) : undefined;
|
|
3037
|
+
const editablePkgJson = pkgPath ? await packages.readPackageJson(pkgPath, {
|
|
3038
|
+
editable: true
|
|
3039
|
+
}) : undefined;
|
|
3040
|
+
// Read Corepack `packageManager` field in package.json:
|
|
3041
|
+
// https://nodejs.org/api/packages.html#packagemanager
|
|
3042
|
+
const pkgManager = strings.isNonEmptyString(editablePkgJson?.content?.packageManager) ? editablePkgJson.content.packageManager : undefined;
|
|
3043
|
+
let agent;
|
|
3044
|
+
if (pkgManager) {
|
|
3045
|
+
// A valid "packageManager" field value is "<package manager name>@<version>".
|
|
3046
|
+
// https://nodejs.org/api/packages.html#packagemanager
|
|
3047
|
+
const atSignIndex = pkgManager.lastIndexOf('@');
|
|
3048
|
+
if (atSignIndex !== -1) {
|
|
3049
|
+
const name = pkgManager.slice(0, atSignIndex);
|
|
3050
|
+
const version = pkgManager.slice(atSignIndex + 1);
|
|
3051
|
+
if (version && AGENTS.includes(name)) {
|
|
3052
|
+
agent = name;
|
|
2982
3053
|
}
|
|
2983
3054
|
}
|
|
2984
|
-
sockPkgAlerts = [
|
|
2985
|
-
// Sort CVE alerts by severity: critical, high, middle, then low.
|
|
2986
|
-
...Array.from(highestForCve.values()).map(d => d.alert).sort(alertSeverityComparator), ...Array.from(highestForUpgrade.values()).map(d => d.alert), ...unfixableAlerts];
|
|
2987
|
-
} else {
|
|
2988
|
-
sockPkgAlerts.sort((a, b) => sorts.naturalCompare(a.type, b.type));
|
|
2989
3055
|
}
|
|
2990
|
-
if (
|
|
2991
|
-
|
|
3056
|
+
if (agent === undefined && !isHiddenLockFile && typeof pkgJsonPath === 'string' && typeof lockName === 'string') {
|
|
3057
|
+
agent = LOCKS[lockName];
|
|
3058
|
+
}
|
|
3059
|
+
if (agent === undefined) {
|
|
3060
|
+
agent = NPM;
|
|
3061
|
+
onUnknown?.(pkgManager);
|
|
3062
|
+
}
|
|
3063
|
+
const agentExecPath = await getAgentExecPath(agent);
|
|
3064
|
+
const agentVersion = await getAgentVersion(agent, agentExecPath, cwd);
|
|
3065
|
+
if (agent === YARN_CLASSIC && (agentVersion?.major ?? 0) > 1) {
|
|
3066
|
+
agent = YARN_BERRY;
|
|
2992
3067
|
}
|
|
2993
|
-
return alertsByPurl;
|
|
2994
|
-
}
|
|
2995
|
-
function alertsHaveBlocked(alerts) {
|
|
2996
|
-
return alerts.find(a => a.blocked) !== undefined;
|
|
2997
|
-
}
|
|
2998
|
-
function alertsHaveSeverity(alerts, severity) {
|
|
2999
|
-
return alerts.find(a => a.raw.severity === severity) !== undefined;
|
|
3000
|
-
}
|
|
3001
|
-
function alertSeverityComparator(a, b) {
|
|
3002
|
-
// Put the most severe first.
|
|
3003
|
-
return getAlertSeverityOrder(a) - getAlertSeverityOrder(b);
|
|
3004
|
-
}
|
|
3005
|
-
function getAlertSeverityOrder(alert) {
|
|
3006
|
-
// The more severe, the lower the sort number.
|
|
3007
3068
|
const {
|
|
3008
|
-
|
|
3009
|
-
} =
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
let
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
const
|
|
3025
|
-
const
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
if (
|
|
3032
|
-
|
|
3069
|
+
maintainedNodeVersions
|
|
3070
|
+
} = constants;
|
|
3071
|
+
const minSupportedAgentVersion = constants.minimumVersionByAgent.get(agent);
|
|
3072
|
+
const minSupportedNodeMajor = vendor.semverExports.major(maintainedNodeVersions.last);
|
|
3073
|
+
const minSupportedNodeVersion = `${minSupportedNodeMajor}.0.0`;
|
|
3074
|
+
const minSupportedNodeRange = `>=${minSupportedNodeMajor}`;
|
|
3075
|
+
const nodeVersion = vendor.semverExports.coerce(process.version);
|
|
3076
|
+
let lockSrc;
|
|
3077
|
+
let pkgAgentRange;
|
|
3078
|
+
let pkgNodeRange;
|
|
3079
|
+
let pkgMinAgentVersion = minSupportedAgentVersion;
|
|
3080
|
+
let pkgMinNodeVersion = minSupportedNodeVersion;
|
|
3081
|
+
if (editablePkgJson?.content) {
|
|
3082
|
+
const {
|
|
3083
|
+
engines
|
|
3084
|
+
} = editablePkgJson.content;
|
|
3085
|
+
const engineAgentRange = engines?.[agent];
|
|
3086
|
+
const engineNodeRange = engines?.['node'];
|
|
3087
|
+
if (strings.isNonEmptyString(engineAgentRange)) {
|
|
3088
|
+
pkgAgentRange = engineAgentRange;
|
|
3089
|
+
// Roughly check agent range as semver.coerce will strip leading
|
|
3090
|
+
// v's, carets (^), comparators (<,<=,>,>=,=), and tildes (~).
|
|
3091
|
+
const coerced = vendor.semverExports.coerce(pkgAgentRange);
|
|
3092
|
+
if (coerced && vendor.semverExports.lt(coerced, pkgMinAgentVersion)) {
|
|
3093
|
+
pkgMinAgentVersion = coerced.version;
|
|
3033
3094
|
}
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3095
|
+
}
|
|
3096
|
+
if (strings.isNonEmptyString(engineNodeRange)) {
|
|
3097
|
+
pkgNodeRange = engineNodeRange;
|
|
3098
|
+
// Roughly check Node range as semver.coerce will strip leading
|
|
3099
|
+
// v's, carets (^), comparators (<,<=,>,>=,=), and tildes (~).
|
|
3100
|
+
const coerced = vendor.semverExports.coerce(pkgNodeRange);
|
|
3101
|
+
if (coerced && vendor.semverExports.lt(coerced, pkgMinNodeVersion)) {
|
|
3102
|
+
pkgMinNodeVersion = coerced.version;
|
|
3038
3103
|
}
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
//
|
|
3046
|
-
const
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
if (firstPatchedVersionIdentifier && vulnerableVersionRange) {
|
|
3050
|
-
try {
|
|
3051
|
-
infos.set(key, {
|
|
3052
|
-
firstPatchedVersionIdentifier,
|
|
3053
|
-
vulnerableVersionRange: new vendor.semverExports.Range(
|
|
3054
|
-
// Replace ', ' in a range like '>= 1.0.0, < 1.8.2' with ' ' so that
|
|
3055
|
-
// semver.Range will parse it without erroring.
|
|
3056
|
-
vulnerableVersionRange.replace(/, +/g, ' ').replace(/; +/g, ' || ')).format()
|
|
3057
|
-
});
|
|
3058
|
-
continue sockPkgAlertsLoop;
|
|
3059
|
-
} catch (e) {
|
|
3060
|
-
error = e;
|
|
3061
|
-
}
|
|
3104
|
+
}
|
|
3105
|
+
const browserslistQuery = editablePkgJson.content['browserslist'];
|
|
3106
|
+
if (Array.isArray(browserslistQuery)) {
|
|
3107
|
+
// List Node targets in ascending version order.
|
|
3108
|
+
const browserslistNodeTargets = vendor.browserslistExports(browserslistQuery).filter(v => /^node /i.test(v)).map(v => v.slice(5 /*'node '.length*/)).sort(sorts.naturalCompare);
|
|
3109
|
+
if (browserslistNodeTargets.length) {
|
|
3110
|
+
// browserslistNodeTargets[0] is the lowest Node target version.
|
|
3111
|
+
const coerced = vendor.semverExports.coerce(browserslistNodeTargets[0]);
|
|
3112
|
+
if (coerced && vendor.semverExports.lt(coerced, pkgMinNodeVersion)) {
|
|
3113
|
+
pkgMinNodeVersion = coerced.version;
|
|
3062
3114
|
}
|
|
3063
|
-
require$$9.debugFn('error', 'fail: invalid SocketPackageAlert');
|
|
3064
|
-
require$$9.debugDir('inspect', {
|
|
3065
|
-
alert,
|
|
3066
|
-
error
|
|
3067
|
-
});
|
|
3068
3115
|
}
|
|
3069
3116
|
}
|
|
3117
|
+
lockSrc = typeof lockPath === 'string' ? await readLockFileByAgent.get(agent)(lockPath, agentExecPath, cwd) : undefined;
|
|
3118
|
+
} else {
|
|
3119
|
+
lockName = undefined;
|
|
3120
|
+
lockPath = undefined;
|
|
3070
3121
|
}
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3122
|
+
|
|
3123
|
+
// Does the system agent version meet our minimum supported agent version?
|
|
3124
|
+
const agentSupported = !!agentVersion && vendor.semverExports.satisfies(agentVersion, `>=${minSupportedAgentVersion}`);
|
|
3125
|
+
// Does the system Node version meet our minimum supported Node version?
|
|
3126
|
+
const nodeSupported = vendor.semverExports.satisfies(nodeVersion, minSupportedNodeRange);
|
|
3127
|
+
const npmExecPath = agent === NPM ? agentExecPath : await getAgentExecPath(NPM);
|
|
3128
|
+
const npmBuggyOverrides = agent === NPM && !!agentVersion && vendor.semverExports.lt(agentVersion, NPM_BUGGY_OVERRIDES_PATCHED_VERSION);
|
|
3129
|
+
const pkgMinAgentRange = `>=${pkgMinAgentVersion}`;
|
|
3130
|
+
const pkgMinNodeRange = `>=${vendor.semverExports.major(pkgMinNodeVersion)}`;
|
|
3131
|
+
return {
|
|
3132
|
+
agent,
|
|
3133
|
+
agentExecPath,
|
|
3134
|
+
agentSupported,
|
|
3135
|
+
agentVersion,
|
|
3136
|
+
editablePkgJson,
|
|
3137
|
+
features: {
|
|
3138
|
+
npmBuggyOverrides
|
|
3139
|
+
},
|
|
3140
|
+
lockName,
|
|
3141
|
+
lockPath,
|
|
3142
|
+
lockSrc,
|
|
3143
|
+
nodeSupported,
|
|
3144
|
+
nodeVersion,
|
|
3145
|
+
npmExecPath,
|
|
3146
|
+
pkgPath,
|
|
3147
|
+
pkgRequirements: {
|
|
3148
|
+
agent: pkgAgentRange ?? pkgMinAgentRange,
|
|
3149
|
+
node: pkgNodeRange ?? pkgMinNodeRange
|
|
3150
|
+
},
|
|
3151
|
+
pkgSupports: {
|
|
3152
|
+
// Does our minimum supported agent version meet the package's requirements?
|
|
3153
|
+
agent: vendor.semverExports.satisfies(minSupportedAgentVersion, pkgMinAgentRange),
|
|
3154
|
+
// Does our supported Node versions meet the package's requirements?
|
|
3155
|
+
node: maintainedNodeVersions.some(v => vendor.semverExports.satisfies(v, pkgMinNodeRange))
|
|
3156
|
+
}
|
|
3157
|
+
};
|
|
3075
3158
|
}
|
|
3076
|
-
function
|
|
3159
|
+
async function detectAndValidatePackageEnvironment(cwd, options) {
|
|
3077
3160
|
const {
|
|
3078
|
-
|
|
3079
|
-
|
|
3161
|
+
cmdName = '',
|
|
3162
|
+
logger,
|
|
3163
|
+
prod
|
|
3080
3164
|
} = {
|
|
3081
3165
|
__proto__: null,
|
|
3082
3166
|
...options
|
|
3083
3167
|
};
|
|
3084
|
-
const
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
const hiddenAlertsByPurl = new Map();
|
|
3089
|
-
for (let i = 0, {
|
|
3090
|
-
length
|
|
3091
|
-
} = sortedEntries; i < length; i += 1) {
|
|
3092
|
-
const {
|
|
3093
|
-
0: purl,
|
|
3094
|
-
1: alerts
|
|
3095
|
-
} = sortedEntries[i];
|
|
3096
|
-
const hiddenAlerts = [];
|
|
3097
|
-
const viewableAlerts = alerts.filter(a => {
|
|
3098
|
-
const keep = a.blocked || getAlertSeverityOrder(a) < ALERT_SEVERITY_ORDER[hideAt];
|
|
3099
|
-
if (!keep) {
|
|
3100
|
-
hiddenAlerts.push(a);
|
|
3101
|
-
}
|
|
3102
|
-
return keep;
|
|
3103
|
-
});
|
|
3104
|
-
if (hiddenAlerts.length) {
|
|
3105
|
-
hiddenAlertsByPurl.set(purl, hiddenAlerts.sort(alertSeverityComparator));
|
|
3106
|
-
}
|
|
3107
|
-
if (!viewableAlerts.length) {
|
|
3108
|
-
continue;
|
|
3109
|
-
}
|
|
3110
|
-
viewableAlerts.sort(alertSeverityComparator);
|
|
3111
|
-
viewableAlertsByPurl.set(purl, viewableAlerts);
|
|
3112
|
-
if (viewableAlerts.find(a => a.blocked || getAlertSeverityOrder(a) < ALERT_SEVERITY_ORDER.middle)) {
|
|
3113
|
-
aboveTheFoldPurls.add(purl);
|
|
3168
|
+
const details = await detectPackageEnvironment({
|
|
3169
|
+
cwd,
|
|
3170
|
+
onUnknown(pkgManager) {
|
|
3171
|
+
logger?.warn(cmdPrefixMessage(cmdName, `Unknown package manager${pkgManager ? ` ${pkgManager}` : ''}, defaulting to npm`));
|
|
3114
3172
|
}
|
|
3173
|
+
});
|
|
3174
|
+
const {
|
|
3175
|
+
agent,
|
|
3176
|
+
nodeVersion,
|
|
3177
|
+
pkgRequirements
|
|
3178
|
+
} = details;
|
|
3179
|
+
const agentVersion = details.agentVersion ?? 'unknown';
|
|
3180
|
+
if (!details.agentSupported) {
|
|
3181
|
+
const minVersion = constants.minimumVersionByAgent.get(agent);
|
|
3182
|
+
return {
|
|
3183
|
+
ok: false,
|
|
3184
|
+
message: 'Version mismatch',
|
|
3185
|
+
cause: cmdPrefixMessage(cmdName, `Requires ${agent} >=${minVersion}. Current version: ${agentVersion}.`)
|
|
3186
|
+
};
|
|
3115
3187
|
}
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
}
|
|
3124
|
-
aboveTheFoldPurls.add(purl);
|
|
3125
|
-
}
|
|
3126
|
-
// If MIN_ABOVE_THE_FOLD_COUNT is STILL NOT met add more from hidden pkg ids.
|
|
3127
|
-
for (const {
|
|
3128
|
-
0: purl,
|
|
3129
|
-
1: hiddenAlerts
|
|
3130
|
-
} of hiddenAlertsByPurl.entries()) {
|
|
3131
|
-
if (aboveTheFoldPurls.size >= MIN_ABOVE_THE_FOLD_COUNT) {
|
|
3132
|
-
break;
|
|
3133
|
-
}
|
|
3134
|
-
aboveTheFoldPurls.add(purl);
|
|
3135
|
-
const viewableAlerts = viewableAlertsByPurl.get(purl) ?? [];
|
|
3136
|
-
if (viewableAlerts.length < MIN_ABOVE_THE_FOLD_ALERT_COUNT) {
|
|
3137
|
-
const neededCount = MIN_ABOVE_THE_FOLD_ALERT_COUNT - viewableAlerts.length;
|
|
3138
|
-
let removedHiddenAlerts;
|
|
3139
|
-
if (hiddenAlerts.length - neededCount > 0) {
|
|
3140
|
-
removedHiddenAlerts = hiddenAlerts.splice(0, MIN_ABOVE_THE_FOLD_ALERT_COUNT);
|
|
3141
|
-
} else {
|
|
3142
|
-
removedHiddenAlerts = hiddenAlerts;
|
|
3143
|
-
hiddenAlertsByPurl.delete(purl);
|
|
3144
|
-
}
|
|
3145
|
-
viewableAlertsByPurl.set(purl, [...viewableAlerts, ...removedHiddenAlerts]);
|
|
3146
|
-
}
|
|
3188
|
+
if (!details.nodeSupported) {
|
|
3189
|
+
const minVersion = constants.maintainedNodeVersions.last;
|
|
3190
|
+
return {
|
|
3191
|
+
ok: false,
|
|
3192
|
+
message: 'Version mismatch',
|
|
3193
|
+
cause: cmdPrefixMessage(cmdName, `Requires Node >=${minVersion}. Current version: ${nodeVersion}.`)
|
|
3194
|
+
};
|
|
3147
3195
|
}
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
1: alerts
|
|
3155
|
-
} = entries[i];
|
|
3156
|
-
const lines = new Set();
|
|
3157
|
-
for (const alert of alerts) {
|
|
3158
|
-
const {
|
|
3159
|
-
type
|
|
3160
|
-
} = alert;
|
|
3161
|
-
const severity = alert.raw.severity ?? '';
|
|
3162
|
-
const attributes = [...(severity ? [vendor.yoctocolorsCjsExports[ALERT_SEVERITY_COLOR[severity]](getSeverityLabel(severity))] : []), ...(alert.blocked ? [vendor.yoctocolorsCjsExports.bold(vendor.yoctocolorsCjsExports.red('blocked'))] : []), ...(alert.fixable ? ['fixable'] : [])];
|
|
3163
|
-
const maybeAttributes = attributes.length ? ` ${vendor.yoctocolorsCjsExports.italic(`(${attributes.join('; ')})`)}` : '';
|
|
3164
|
-
// Based data from { pageProps: { alertTypes } } of:
|
|
3165
|
-
// https://socket.dev/_next/data/9a6db8224b68b6da0eb9f7dbb17aff7e51568ac2/en-US.json
|
|
3166
|
-
const info = translations.alerts[type];
|
|
3167
|
-
const title = info?.title ?? type;
|
|
3168
|
-
const maybeDesc = info?.description ? ` - ${info.description}` : '';
|
|
3169
|
-
const content = `${title}${maybeAttributes}${maybeDesc}`;
|
|
3170
|
-
// TODO: An added emoji seems to mis-align terminals sometimes.
|
|
3171
|
-
lines.add(` ${content}`);
|
|
3172
|
-
}
|
|
3173
|
-
const purlObj = getPurlObject(purl);
|
|
3174
|
-
const pkgName = packages.resolvePackageName(purlObj);
|
|
3175
|
-
const hyperlink = format.hyperlink(pkgName, getSocketDevPackageOverviewUrl(purlObj.type, pkgName, purlObj.version));
|
|
3176
|
-
const isAboveTheFold = aboveTheFoldPurls.has(purl);
|
|
3177
|
-
if (isAboveTheFold) {
|
|
3178
|
-
aboveTheFoldPurls.add(purl);
|
|
3179
|
-
output.write(`${i ? '\n' : ''}${hyperlink}:\n`);
|
|
3180
|
-
} else {
|
|
3181
|
-
output.write(`${prevAboveTheFold ? '\n' : ''}${hyperlink}:\n`);
|
|
3182
|
-
}
|
|
3183
|
-
for (const line of lines) {
|
|
3184
|
-
output.write(`${line}\n`);
|
|
3185
|
-
}
|
|
3186
|
-
const hiddenAlerts = hiddenAlertsByPurl.get(purl) ?? [];
|
|
3187
|
-
const {
|
|
3188
|
-
length: hiddenAlertsCount
|
|
3189
|
-
} = hiddenAlerts;
|
|
3190
|
-
if (hiddenAlertsCount) {
|
|
3191
|
-
mentionedPurlsWithHiddenAlerts.add(purl);
|
|
3192
|
-
if (hiddenAlertsCount === 1) {
|
|
3193
|
-
output.write(` ${vendor.yoctocolorsCjsExports.dim(`+1 Hidden ${getSeverityLabel(hiddenAlerts[0].raw.severity ?? 'low')} risk alert`)}\n`);
|
|
3194
|
-
} else {
|
|
3195
|
-
output.write(` ${vendor.yoctocolorsCjsExports.dim(`+${hiddenAlertsCount} Hidden alerts ${vendor.yoctocolorsCjsExports.italic(getHiddenRisksDescription(getHiddenRiskCounts(hiddenAlerts)))}`)}\n`);
|
|
3196
|
-
}
|
|
3197
|
-
}
|
|
3198
|
-
prevAboveTheFold = isAboveTheFold;
|
|
3196
|
+
if (!details.pkgSupports.agent) {
|
|
3197
|
+
return {
|
|
3198
|
+
ok: false,
|
|
3199
|
+
message: 'Engine mismatch',
|
|
3200
|
+
cause: cmdPrefixMessage(cmdName, `Package engine "${agent}" requires ${pkgRequirements.agent}. Current version: ${agentVersion}`)
|
|
3201
|
+
};
|
|
3199
3202
|
}
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
middle: 0,
|
|
3206
|
-
low: 0
|
|
3203
|
+
if (!details.pkgSupports.node) {
|
|
3204
|
+
return {
|
|
3205
|
+
ok: false,
|
|
3206
|
+
message: 'Version mismatch',
|
|
3207
|
+
cause: cmdPrefixMessage(cmdName, `Package engine "node" requires ${pkgRequirements.node}. Current version: ${nodeVersion}`)
|
|
3207
3208
|
};
|
|
3208
|
-
for (const {
|
|
3209
|
-
0: purl,
|
|
3210
|
-
1: alerts
|
|
3211
|
-
} of hiddenAlertsByPurl.entries()) {
|
|
3212
|
-
if (mentionedPurlsWithHiddenAlerts.has(purl)) {
|
|
3213
|
-
continue;
|
|
3214
|
-
}
|
|
3215
|
-
const riskCounts = getHiddenRiskCounts(alerts);
|
|
3216
|
-
totalRiskCounts.critical += riskCounts.critical;
|
|
3217
|
-
totalRiskCounts.high += riskCounts.high;
|
|
3218
|
-
totalRiskCounts.middle += riskCounts.middle;
|
|
3219
|
-
totalRiskCounts.low += riskCounts.low;
|
|
3220
|
-
}
|
|
3221
|
-
output.write(`${aboveTheFoldPurls.size ? '\n' : ''}${vendor.yoctocolorsCjsExports.dim(`${aboveTheFoldPurls.size ? '+' : ''}${additionalHiddenCount} Packages with hidden alerts ${vendor.yoctocolorsCjsExports.italic(getHiddenRisksDescription(totalRiskCounts))}`)}\n`);
|
|
3222
3209
|
}
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
}
|
|
3229
|
-
function idToPurl(id, type) {
|
|
3230
|
-
return `pkg:${type}/${id}`;
|
|
3231
|
-
}
|
|
3232
|
-
|
|
3233
|
-
function extractOverridesFromPnpmLockSrc(lockfileContent) {
|
|
3234
|
-
let match;
|
|
3235
|
-
if (typeof lockfileContent === 'string') {
|
|
3236
|
-
match = /^overrides:(?:\r?\n {2}.+)+(?:\r?\n)*/m.exec(lockfileContent)?.[0];
|
|
3237
|
-
}
|
|
3238
|
-
return match ?? '';
|
|
3239
|
-
}
|
|
3240
|
-
async function extractPurlsFromPnpmLockfile(lockfile) {
|
|
3241
|
-
const packages = lockfile?.packages ?? {};
|
|
3242
|
-
const seen = new Set();
|
|
3243
|
-
const visit = pkgPath => {
|
|
3244
|
-
if (seen.has(pkgPath)) {
|
|
3245
|
-
return;
|
|
3246
|
-
}
|
|
3247
|
-
const pkg = packages[pkgPath];
|
|
3248
|
-
if (!pkg) {
|
|
3249
|
-
return;
|
|
3250
|
-
}
|
|
3251
|
-
seen.add(pkgPath);
|
|
3252
|
-
const deps = {
|
|
3253
|
-
__proto__: null,
|
|
3254
|
-
...pkg.dependencies,
|
|
3255
|
-
...pkg.optionalDependencies,
|
|
3256
|
-
...pkg.devDependencies
|
|
3210
|
+
const lockName = details.lockName ?? 'lock file';
|
|
3211
|
+
if (details.lockName === undefined || details.lockSrc === undefined) {
|
|
3212
|
+
return {
|
|
3213
|
+
ok: false,
|
|
3214
|
+
message: 'Missing lockfile',
|
|
3215
|
+
cause: cmdPrefixMessage(cmdName, `No ${lockName} found`)
|
|
3257
3216
|
};
|
|
3258
|
-
for (const depName in deps) {
|
|
3259
|
-
const ref = deps[depName];
|
|
3260
|
-
const subKey = isPnpmDepPath(ref) ? ref : `/${depName}@${ref}`;
|
|
3261
|
-
visit(subKey);
|
|
3262
|
-
}
|
|
3263
|
-
};
|
|
3264
|
-
for (const pkgPath of Object.keys(packages)) {
|
|
3265
|
-
visit(pkgPath);
|
|
3266
3217
|
}
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
}
|
|
3272
|
-
|
|
3273
|
-
let result;
|
|
3274
|
-
if (typeof lockfileContent === 'string') {
|
|
3275
|
-
try {
|
|
3276
|
-
result = vendor.jsYaml.load(strings.stripBom(lockfileContent));
|
|
3277
|
-
} catch {}
|
|
3218
|
+
if (details.lockSrc.trim() === '') {
|
|
3219
|
+
return {
|
|
3220
|
+
ok: false,
|
|
3221
|
+
message: 'Empty lockfile',
|
|
3222
|
+
cause: cmdPrefixMessage(cmdName, `${lockName} is empty`)
|
|
3223
|
+
};
|
|
3278
3224
|
}
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
return null;
|
|
3286
|
-
}
|
|
3287
|
-
function stripLeadingPnpmDepPathSlash(depPath) {
|
|
3288
|
-
return isPnpmDepPath(depPath) ? depPath.slice(1) : depPath;
|
|
3289
|
-
}
|
|
3290
|
-
function stripPnpmPeerSuffix(depPath) {
|
|
3291
|
-
const parenIndex = depPath.indexOf('(');
|
|
3292
|
-
const index = parenIndex === -1 ? depPath.indexOf('_') : parenIndex;
|
|
3293
|
-
return index === -1 ? depPath : depPath.slice(0, index);
|
|
3294
|
-
}
|
|
3295
|
-
|
|
3296
|
-
async function getAlertsMapFromPnpmLockfile(lockfile, options) {
|
|
3297
|
-
const purls = await extractPurlsFromPnpmLockfile(lockfile);
|
|
3298
|
-
return await getAlertsMapFromPurls(purls, {
|
|
3299
|
-
overrides: lockfile.overrides,
|
|
3300
|
-
...options
|
|
3301
|
-
});
|
|
3302
|
-
}
|
|
3303
|
-
async function getAlertsMapFromPurls(purls, options) {
|
|
3304
|
-
const uniqPurls = arrays.arrayUnique(purls);
|
|
3305
|
-
require$$9.debugDir('silly', {
|
|
3306
|
-
purls: uniqPurls
|
|
3307
|
-
});
|
|
3308
|
-
let {
|
|
3309
|
-
length: remaining
|
|
3310
|
-
} = uniqPurls;
|
|
3311
|
-
const alertsByPurl = new Map();
|
|
3312
|
-
if (!remaining) {
|
|
3313
|
-
return alertsByPurl;
|
|
3225
|
+
if (details.pkgPath === undefined) {
|
|
3226
|
+
return {
|
|
3227
|
+
ok: false,
|
|
3228
|
+
message: 'Missing package.json',
|
|
3229
|
+
cause: cmdPrefixMessage(cmdName, `No ${PACKAGE_JSON} found`)
|
|
3230
|
+
};
|
|
3314
3231
|
}
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
};
|
|
3322
|
-
if (opts.onlyFixable) {
|
|
3323
|
-
opts.filter.fixable = true;
|
|
3232
|
+
if (prod && (agent === BUN || agent === YARN_BERRY)) {
|
|
3233
|
+
return {
|
|
3234
|
+
ok: false,
|
|
3235
|
+
message: 'Bad input',
|
|
3236
|
+
cause: cmdPrefixMessage(cmdName, `--prod not supported for ${agent}${agentVersion ? `@${agentVersion}` : ''}`)
|
|
3237
|
+
};
|
|
3324
3238
|
}
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
} = opts;
|
|
3329
|
-
const getText = () => `Looking up data for ${remaining} packages`;
|
|
3330
|
-
spinner?.start(getText());
|
|
3331
|
-
const sockSdkCResult = await setupSdk({
|
|
3332
|
-
apiToken
|
|
3333
|
-
});
|
|
3334
|
-
if (!sockSdkCResult.ok) {
|
|
3335
|
-
spinner?.stop();
|
|
3336
|
-
throw new Error('Auth error: Run `socket login` first');
|
|
3239
|
+
if (details.lockPath && path.relative(cwd, details.lockPath).startsWith('.')) {
|
|
3240
|
+
// Note: In tests we return <redacted> because otherwise snapshots will fail.
|
|
3241
|
+
logger?.warn(cmdPrefixMessage(cmdName, `Package ${lockName} found at ${constants.ENV.VITEST ? constants.REDACTED : details.lockPath}`));
|
|
3337
3242
|
}
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
overrides: opts.overrides,
|
|
3342
|
-
consolidate: opts.consolidate,
|
|
3343
|
-
filter: opts.filter,
|
|
3344
|
-
socketYml,
|
|
3345
|
-
spinner
|
|
3243
|
+
return {
|
|
3244
|
+
ok: true,
|
|
3245
|
+
data: details
|
|
3346
3246
|
};
|
|
3347
|
-
for await (const batchResult of sockSdk.batchPackageStream({
|
|
3348
|
-
components: uniqPurls.map(purl => ({
|
|
3349
|
-
purl
|
|
3350
|
-
}))
|
|
3351
|
-
}, {
|
|
3352
|
-
queryParams: {
|
|
3353
|
-
alerts: 'true',
|
|
3354
|
-
compact: 'true',
|
|
3355
|
-
...(opts.onlyFixable ? {
|
|
3356
|
-
fixable: 'true '
|
|
3357
|
-
} : {}),
|
|
3358
|
-
...(Array.isArray(opts.filter.actions) ? {
|
|
3359
|
-
actions: opts.filter.actions.join(',')
|
|
3360
|
-
} : {})
|
|
3361
|
-
}
|
|
3362
|
-
})) {
|
|
3363
|
-
if (batchResult.success) {
|
|
3364
|
-
const artifact = batchResult.data;
|
|
3365
|
-
await addArtifactToAlertsMap(artifact, alertsByPurl, alertsMapOptions);
|
|
3366
|
-
} else if (!opts.nothrow) {
|
|
3367
|
-
spinner?.stop();
|
|
3368
|
-
if (strings.isNonEmptyString(batchResult.error)) {
|
|
3369
|
-
throw new Error(batchResult.error);
|
|
3370
|
-
}
|
|
3371
|
-
const statusCode = batchResult.status ?? 'unknown';
|
|
3372
|
-
throw new Error(`Socket API server error (${statusCode}): No status message`);
|
|
3373
|
-
} else {
|
|
3374
|
-
spinner?.stop();
|
|
3375
|
-
logger.logger.fail(`Received a ${batchResult.status} response from Socket API which we consider a permanent failure:`, batchResult.error, batchResult.cause ? `( ${batchResult.cause} )` : '');
|
|
3376
|
-
require$$9.debugDir('inspect', {
|
|
3377
|
-
batchResult
|
|
3378
|
-
});
|
|
3379
|
-
break;
|
|
3380
|
-
}
|
|
3381
|
-
remaining -= 1;
|
|
3382
|
-
if (remaining > 0) {
|
|
3383
|
-
spinner?.start(getText());
|
|
3384
|
-
}
|
|
3385
|
-
}
|
|
3386
|
-
spinner?.stop();
|
|
3387
|
-
return alertsByPurl;
|
|
3388
3247
|
}
|
|
3389
3248
|
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
return null;
|
|
3249
|
+
const ALL_ECOSYSTEMS = ['apk', 'bitbucket', 'cargo', 'chrome', 'cocoapods', 'composer', 'conan', 'conda', 'cran', 'deb', 'docker', 'gem', 'generic', 'github', 'golang', 'hackage', 'hex', 'huggingface', 'maven', 'mlflow', 'npm', 'nuget', 'oci', 'pub', 'pypi', 'qpkg', 'rpm', 'swift', 'swid', 'unknown'];
|
|
3250
|
+
new Set(ALL_ECOSYSTEMS);
|
|
3251
|
+
function getEcosystemChoicesForMeow() {
|
|
3252
|
+
return [...ALL_ECOSYSTEMS];
|
|
3395
3253
|
}
|
|
3396
3254
|
|
|
3397
|
-
|
|
3398
|
-
const
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3255
|
+
function isArtifactAlertCve(alert) {
|
|
3256
|
+
const {
|
|
3257
|
+
type
|
|
3258
|
+
} = alert;
|
|
3259
|
+
return type === constants.ALERT_TYPE_CVE || type === constants.ALERT_TYPE_MEDIUM_CVE || type === constants.ALERT_TYPE_MILD_CVE || type === constants.ALERT_TYPE_CRITICAL_CVE;
|
|
3260
|
+
}
|
|
3261
|
+
|
|
3262
|
+
function createEnum(obj) {
|
|
3263
|
+
return Object.freeze({
|
|
3264
|
+
__proto__: null,
|
|
3265
|
+
...obj
|
|
3404
3266
|
});
|
|
3405
3267
|
}
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3268
|
+
|
|
3269
|
+
const ALERT_FIX_TYPE = createEnum({
|
|
3270
|
+
cve: 'cve',
|
|
3271
|
+
remove: 'remove',
|
|
3272
|
+
upgrade: 'upgrade'
|
|
3273
|
+
});
|
|
3274
|
+
|
|
3275
|
+
const ALERT_SEVERITY = createEnum({
|
|
3276
|
+
critical: 'critical',
|
|
3277
|
+
high: 'high',
|
|
3278
|
+
middle: 'middle',
|
|
3279
|
+
low: 'low'
|
|
3280
|
+
});
|
|
3281
|
+
|
|
3282
|
+
class ColorOrMarkdown {
|
|
3283
|
+
constructor(useMarkdown) {
|
|
3284
|
+
this.useMarkdown = !!useMarkdown;
|
|
3285
|
+
}
|
|
3286
|
+
bold(text) {
|
|
3287
|
+
return this.useMarkdown ? `**${text}**` : vendor.yoctocolorsCjsExports.bold(`${text}`);
|
|
3288
|
+
}
|
|
3289
|
+
header(text, level = 1) {
|
|
3290
|
+
return this.useMarkdown ? `\n${''.padStart(level, '#')} ${text}\n` : vendor.yoctocolorsCjsExports.underline(`\n${level === 1 ? vendor.yoctocolorsCjsExports.bold(text) : text}\n`);
|
|
3291
|
+
}
|
|
3292
|
+
hyperlink(text, url, {
|
|
3293
|
+
fallback = true,
|
|
3294
|
+
fallbackToUrl
|
|
3295
|
+
} = {}) {
|
|
3296
|
+
if (url) {
|
|
3297
|
+
return this.useMarkdown ? `[${text}](${url})` : vendor.terminalLinkExports(text, url, {
|
|
3298
|
+
fallback: fallbackToUrl ? (_text, url) => url : fallback
|
|
3299
|
+
});
|
|
3428
3300
|
}
|
|
3429
|
-
|
|
3301
|
+
return text;
|
|
3302
|
+
}
|
|
3303
|
+
indent(...args) {
|
|
3304
|
+
return vendor.indentStringExports(...args);
|
|
3305
|
+
}
|
|
3306
|
+
italic(text) {
|
|
3307
|
+
return this.useMarkdown ? `_${text}_` : vendor.yoctocolorsCjsExports.italic(`${text}`);
|
|
3308
|
+
}
|
|
3309
|
+
json(value) {
|
|
3310
|
+
return this.useMarkdown ? '```json\n' + JSON.stringify(value) + '\n```' : JSON.stringify(value);
|
|
3311
|
+
}
|
|
3312
|
+
list(items) {
|
|
3313
|
+
const indentedContent = items.map(item => this.indent(item).trimStart());
|
|
3314
|
+
return this.useMarkdown ? `* ${indentedContent.join('\n* ')}\n` : `${indentedContent.join('\n')}\n`;
|
|
3430
3315
|
}
|
|
3431
|
-
return undefined;
|
|
3432
3316
|
}
|
|
3433
3317
|
|
|
3434
|
-
function
|
|
3435
|
-
const {
|
|
3436
|
-
|
|
3437
|
-
args = [],
|
|
3438
|
-
ipc,
|
|
3439
|
-
spinner,
|
|
3440
|
-
...spawnOpts
|
|
3441
|
-
} = {
|
|
3442
|
-
__proto__: null,
|
|
3443
|
-
...options
|
|
3318
|
+
function toFilterConfig(obj) {
|
|
3319
|
+
const normalized = {
|
|
3320
|
+
__proto__: null
|
|
3444
3321
|
};
|
|
3445
|
-
const
|
|
3446
|
-
const
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
const progressArg = rawBinArgs.findLast(npm.isNpmProgressFlag) !== '--no-progress';
|
|
3451
|
-
const isSilent = !useDebug && !binArgs.some(npm.isNpmLoglevelFlag);
|
|
3452
|
-
const logLevelArgs = isSilent ? ['--loglevel', 'silent'] : [];
|
|
3453
|
-
const useIpc = require$$10.isObject(ipc);
|
|
3454
|
-
|
|
3455
|
-
// Include 'ipc' in the spawnOpts.stdio when an options.ipc object is provided.
|
|
3456
|
-
// See https://github.com/nodejs/node/blob/v23.6.0/lib/child_process.js#L161-L166
|
|
3457
|
-
// and https://github.com/nodejs/node/blob/v23.6.0/lib/internal/child_process.js#L238.
|
|
3458
|
-
let stdio = require$$10.getOwn(spawnOpts, 'stdio');
|
|
3459
|
-
if (typeof stdio === 'string') {
|
|
3460
|
-
stdio = useIpc ? [stdio, stdio, stdio, 'ipc'] : [stdio, stdio, stdio];
|
|
3461
|
-
} else if (Array.isArray(stdio)) {
|
|
3462
|
-
if (useIpc && !stdio.includes('ipc')) {
|
|
3463
|
-
stdio = stdio.concat('ipc');
|
|
3322
|
+
const keys = require$$10.isObject(obj) ? Object.keys(obj) : [];
|
|
3323
|
+
for (const key of keys) {
|
|
3324
|
+
const value = obj[key];
|
|
3325
|
+
if (typeof value === 'boolean' || Array.isArray(value)) {
|
|
3326
|
+
normalized[key] = value;
|
|
3464
3327
|
}
|
|
3465
|
-
} else {
|
|
3466
|
-
stdio = useIpc ? ['pipe', 'pipe', 'pipe', 'ipc'] : 'pipe';
|
|
3467
|
-
}
|
|
3468
|
-
const spawnPromise = spawn.spawn(constants.execPath, [...constants.nodeNoWarningsFlags, ...constants.nodeDebugFlags, ...constants.nodeHardenFlags, ...constants.nodeMemoryFlags, ...(constants.ENV.INLINED_SOCKET_CLI_SENTRY_BUILD ? ['--require', constants.instrumentWithSentryPath] : []), '--require', constants.shadowNpmInjectPath, npm.resolveBinPathSync(agentExecPath), 'install',
|
|
3469
|
-
// Avoid code paths for 'audit' and 'fund'.
|
|
3470
|
-
'--no-audit', '--no-fund',
|
|
3471
|
-
// Add '--no-progress' to fix input being swallowed by the npm spinner.
|
|
3472
|
-
'--no-progress',
|
|
3473
|
-
// Add '--loglevel=silent' if a loglevel flag is not provided and the
|
|
3474
|
-
// SOCKET_CLI_DEBUG environment variable is not truthy.
|
|
3475
|
-
...logLevelArgs, ...binArgs, ...otherArgs], {
|
|
3476
|
-
...spawnOpts,
|
|
3477
|
-
env: {
|
|
3478
|
-
...process.env,
|
|
3479
|
-
...constants.processEnv,
|
|
3480
|
-
...require$$10.getOwn(spawnOpts, 'env')
|
|
3481
|
-
},
|
|
3482
|
-
spinner,
|
|
3483
|
-
stdio
|
|
3484
|
-
});
|
|
3485
|
-
if (useIpc) {
|
|
3486
|
-
spawnPromise.process.send({
|
|
3487
|
-
[constants.SOCKET_IPC_HANDSHAKE]: {
|
|
3488
|
-
[constants.SOCKET_CLI_SHADOW_BIN]: 'npm',
|
|
3489
|
-
[constants.SOCKET_CLI_SHADOW_PROGRESS]: progressArg,
|
|
3490
|
-
...ipc
|
|
3491
|
-
}
|
|
3492
|
-
});
|
|
3493
3328
|
}
|
|
3494
|
-
return
|
|
3329
|
+
return normalized;
|
|
3495
3330
|
}
|
|
3496
3331
|
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
const isNpm = agent === 'npm';
|
|
3503
|
-
const isPnpm = agent === 'pnpm';
|
|
3504
|
-
// All package managers support the "install" command.
|
|
3505
|
-
if (isNpm) {
|
|
3506
|
-
return shadowNpmInstall({
|
|
3507
|
-
agentExecPath,
|
|
3508
|
-
...options
|
|
3509
|
-
});
|
|
3332
|
+
const require$1 = Module.createRequire(require('node:url').pathToFileURL(__filename).href);
|
|
3333
|
+
let _translations;
|
|
3334
|
+
function getTranslations() {
|
|
3335
|
+
if (_translations === undefined) {
|
|
3336
|
+
_translations = /*@__PURE__*/require$1(path.join(constants.rootPath, 'translations.json'));
|
|
3510
3337
|
}
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3338
|
+
return _translations;
|
|
3339
|
+
}
|
|
3340
|
+
|
|
3341
|
+
const ALERT_SEVERITY_COLOR = createEnum({
|
|
3342
|
+
critical: 'magenta',
|
|
3343
|
+
high: 'red',
|
|
3344
|
+
middle: 'yellow',
|
|
3345
|
+
low: 'white'
|
|
3346
|
+
});
|
|
3347
|
+
const ALERT_SEVERITY_ORDER = createEnum({
|
|
3348
|
+
critical: 0,
|
|
3349
|
+
high: 1,
|
|
3350
|
+
middle: 2,
|
|
3351
|
+
low: 3,
|
|
3352
|
+
none: 4
|
|
3353
|
+
});
|
|
3354
|
+
const MIN_ABOVE_THE_FOLD_COUNT = 3;
|
|
3355
|
+
const MIN_ABOVE_THE_FOLD_ALERT_COUNT = 1;
|
|
3356
|
+
const format = new ColorOrMarkdown(false);
|
|
3357
|
+
function getHiddenRiskCounts(hiddenAlerts) {
|
|
3358
|
+
const riskCounts = {
|
|
3359
|
+
critical: 0,
|
|
3360
|
+
high: 0,
|
|
3361
|
+
middle: 0,
|
|
3362
|
+
low: 0
|
|
3518
3363
|
};
|
|
3519
|
-
const
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3364
|
+
for (const alert of hiddenAlerts) {
|
|
3365
|
+
switch (getAlertSeverityOrder(alert)) {
|
|
3366
|
+
case ALERT_SEVERITY_ORDER.critical:
|
|
3367
|
+
riskCounts.critical += 1;
|
|
3368
|
+
break;
|
|
3369
|
+
case ALERT_SEVERITY_ORDER.high:
|
|
3370
|
+
riskCounts.high += 1;
|
|
3371
|
+
break;
|
|
3372
|
+
case ALERT_SEVERITY_ORDER.middle:
|
|
3373
|
+
riskCounts.middle += 1;
|
|
3374
|
+
break;
|
|
3375
|
+
case ALERT_SEVERITY_ORDER.low:
|
|
3376
|
+
riskCounts.low += 1;
|
|
3377
|
+
break;
|
|
3530
3378
|
}
|
|
3531
|
-
}
|
|
3379
|
+
}
|
|
3380
|
+
return riskCounts;
|
|
3532
3381
|
}
|
|
3533
|
-
|
|
3534
|
-
|
|
3382
|
+
function getHiddenRisksDescription(riskCounts) {
|
|
3383
|
+
const descriptions = [];
|
|
3384
|
+
if (riskCounts.critical) {
|
|
3385
|
+
descriptions.push(`${riskCounts.critical} ${getSeverityLabel('critical')}`);
|
|
3386
|
+
}
|
|
3387
|
+
if (riskCounts.high) {
|
|
3388
|
+
descriptions.push(`${riskCounts.high} ${getSeverityLabel('high')}`);
|
|
3389
|
+
}
|
|
3390
|
+
if (riskCounts.middle) {
|
|
3391
|
+
descriptions.push(`${riskCounts.middle} ${getSeverityLabel('middle')}`);
|
|
3392
|
+
}
|
|
3393
|
+
if (riskCounts.low) {
|
|
3394
|
+
descriptions.push(`${riskCounts.low} ${getSeverityLabel('low')}`);
|
|
3395
|
+
}
|
|
3396
|
+
return `(${descriptions.join('; ')})`;
|
|
3397
|
+
}
|
|
3398
|
+
async function addArtifactToAlertsMap(artifact, alertsByPurl, options) {
|
|
3399
|
+
// Make TypeScript happy.
|
|
3400
|
+
if (!artifact.name || !artifact.version || !artifact.alerts?.length) {
|
|
3401
|
+
return alertsByPurl;
|
|
3402
|
+
}
|
|
3535
3403
|
const {
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
platform = process.platform
|
|
3404
|
+
type: ecosystem,
|
|
3405
|
+
version
|
|
3406
|
+
} = artifact;
|
|
3407
|
+
const {
|
|
3408
|
+
consolidate = false,
|
|
3409
|
+
overrides,
|
|
3410
|
+
socketYml
|
|
3544
3411
|
} = {
|
|
3545
3412
|
__proto__: null,
|
|
3546
3413
|
...options
|
|
3547
3414
|
};
|
|
3548
|
-
const
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
...env
|
|
3555
|
-
},
|
|
3556
|
-
flatten: vendor.definitionsExports.flatten,
|
|
3557
|
-
npmPath,
|
|
3558
|
-
platform,
|
|
3559
|
-
shorthands: vendor.definitionsExports.shorthands
|
|
3415
|
+
const name = packages.resolvePackageName(artifact);
|
|
3416
|
+
const filterConfig = toFilterConfig({
|
|
3417
|
+
blocked: true,
|
|
3418
|
+
critical: true,
|
|
3419
|
+
cve: true,
|
|
3420
|
+
...require$$10.getOwn(options, 'filter')
|
|
3560
3421
|
});
|
|
3561
|
-
|
|
3562
|
-
const flatConfig = {
|
|
3422
|
+
const enabledState = {
|
|
3563
3423
|
__proto__: null,
|
|
3564
|
-
...
|
|
3424
|
+
...socketYml?.issueRules
|
|
3565
3425
|
};
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
if (npmVersion) {
|
|
3573
|
-
flatConfig.npmVersion = npmVersion.toString();
|
|
3574
|
-
}
|
|
3575
|
-
return flatConfig;
|
|
3576
|
-
}
|
|
3577
|
-
|
|
3578
|
-
async function readLockfile(lockfilePath) {
|
|
3579
|
-
return fs$1.existsSync(lockfilePath) ? await fs.readFileUtf8(lockfilePath) : null;
|
|
3580
|
-
}
|
|
3581
|
-
|
|
3582
|
-
const {
|
|
3583
|
-
BINARY_LOCK_EXT,
|
|
3584
|
-
BUN,
|
|
3585
|
-
HIDDEN_PACKAGE_LOCK_JSON,
|
|
3586
|
-
LOCK_EXT,
|
|
3587
|
-
NPM,
|
|
3588
|
-
NPM_BUGGY_OVERRIDES_PATCHED_VERSION,
|
|
3589
|
-
PACKAGE_JSON,
|
|
3590
|
-
PNPM,
|
|
3591
|
-
VLT,
|
|
3592
|
-
YARN,
|
|
3593
|
-
YARN_BERRY,
|
|
3594
|
-
YARN_CLASSIC
|
|
3595
|
-
} = constants;
|
|
3596
|
-
const AGENTS = [BUN, NPM, PNPM, YARN_BERRY, YARN_CLASSIC, VLT];
|
|
3597
|
-
const binByAgent = new Map([[BUN, BUN], [NPM, NPM], [PNPM, PNPM], [YARN_BERRY, YARN], [YARN_CLASSIC, YARN], [VLT, VLT]]);
|
|
3598
|
-
const readLockFileByAgent = (() => {
|
|
3599
|
-
function wrapReader(reader) {
|
|
3600
|
-
return async (...args) => {
|
|
3601
|
-
try {
|
|
3602
|
-
return await reader(...args);
|
|
3603
|
-
} catch {}
|
|
3604
|
-
return undefined;
|
|
3605
|
-
};
|
|
3606
|
-
}
|
|
3607
|
-
const binaryReader = wrapReader(fs.readFileBinary);
|
|
3608
|
-
const defaultReader = wrapReader(async lockPath => await fs.readFileUtf8(lockPath));
|
|
3609
|
-
return new Map([[BUN, wrapReader(async (lockPath, agentExecPath, cwd = process.cwd()) => {
|
|
3610
|
-
const ext = path.extname(lockPath);
|
|
3611
|
-
if (ext === LOCK_EXT) {
|
|
3612
|
-
return await defaultReader(lockPath);
|
|
3613
|
-
}
|
|
3614
|
-
if (ext === BINARY_LOCK_EXT) {
|
|
3615
|
-
const lockBuffer = await binaryReader(lockPath);
|
|
3616
|
-
if (lockBuffer) {
|
|
3617
|
-
try {
|
|
3618
|
-
return vendor.hyrious__bun_lockbExports.parse(lockBuffer);
|
|
3619
|
-
} catch {}
|
|
3620
|
-
}
|
|
3621
|
-
// To print a Yarn lockfile to your console without writing it to disk
|
|
3622
|
-
// use `bun bun.lockb`.
|
|
3623
|
-
// https://bun.sh/guides/install/yarnlock
|
|
3624
|
-
return (await spawn.spawn(agentExecPath, [lockPath], {
|
|
3625
|
-
cwd,
|
|
3626
|
-
shell: constants.WIN32
|
|
3627
|
-
})).stdout;
|
|
3426
|
+
let sockPkgAlerts = [];
|
|
3427
|
+
for (const alert of artifact.alerts) {
|
|
3428
|
+
const action = alert.action ?? '';
|
|
3429
|
+
const enabledFlag = enabledState[alert.type];
|
|
3430
|
+
if (action === 'ignore' && enabledFlag !== true || enabledFlag === false) {
|
|
3431
|
+
continue;
|
|
3628
3432
|
}
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
const
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
// Unlike the other LOCKS keys this key contains a directory AND filename so
|
|
3651
|
-
// it has to be handled differently.
|
|
3652
|
-
'node_modules/.package-lock.json': NPM
|
|
3653
|
-
};
|
|
3654
|
-
async function getAgentExecPath(agent) {
|
|
3655
|
-
const binName = binByAgent.get(agent);
|
|
3656
|
-
if (binName === NPM) {
|
|
3657
|
-
return constants.npmExecPath;
|
|
3658
|
-
}
|
|
3659
|
-
return (await vendor.libExports$1(binName, {
|
|
3660
|
-
nothrow: true
|
|
3661
|
-
})) ?? binName;
|
|
3662
|
-
}
|
|
3663
|
-
async function getAgentVersion(agent, agentExecPath, cwd) {
|
|
3664
|
-
let result;
|
|
3665
|
-
const quotedCmd = `\`${agent} --version\``;
|
|
3666
|
-
require$$9.debugFn('stdio', `spawn: ${quotedCmd}`);
|
|
3667
|
-
try {
|
|
3668
|
-
result =
|
|
3669
|
-
// Coerce version output into a valid semver version by passing it through
|
|
3670
|
-
// semver.coerce which strips leading v's, carets (^), comparators (<,<=,>,>=,=),
|
|
3671
|
-
// and tildes (~).
|
|
3672
|
-
vendor.semverExports.coerce(
|
|
3673
|
-
// All package managers support the "--version" flag.
|
|
3674
|
-
(await spawn.spawn(agentExecPath, ['--version'], {
|
|
3675
|
-
cwd,
|
|
3676
|
-
shell: constants.WIN32
|
|
3677
|
-
})).stdout) ?? undefined;
|
|
3678
|
-
} catch (e) {
|
|
3679
|
-
require$$9.debugFn('error', `caught: ${quotedCmd} failed`);
|
|
3680
|
-
require$$9.debugDir('inspect', {
|
|
3681
|
-
error: e
|
|
3682
|
-
});
|
|
3683
|
-
}
|
|
3684
|
-
return result;
|
|
3685
|
-
}
|
|
3686
|
-
async function detectPackageEnvironment({
|
|
3687
|
-
cwd = process.cwd(),
|
|
3688
|
-
onUnknown
|
|
3689
|
-
} = {}) {
|
|
3690
|
-
let lockPath = await findUp(Object.keys(LOCKS), {
|
|
3691
|
-
cwd
|
|
3692
|
-
});
|
|
3693
|
-
let lockName = lockPath ? path.basename(lockPath) : undefined;
|
|
3694
|
-
const isHiddenLockFile = lockName === HIDDEN_PACKAGE_LOCK_JSON;
|
|
3695
|
-
const pkgJsonPath = lockPath ? path.resolve(lockPath, `${isHiddenLockFile ? '../' : ''}../${PACKAGE_JSON}`) : await findUp(PACKAGE_JSON, {
|
|
3696
|
-
cwd
|
|
3697
|
-
});
|
|
3698
|
-
const pkgPath = pkgJsonPath && fs$1.existsSync(pkgJsonPath) ? path.dirname(pkgJsonPath) : undefined;
|
|
3699
|
-
const editablePkgJson = pkgPath ? await packages.readPackageJson(pkgPath, {
|
|
3700
|
-
editable: true
|
|
3701
|
-
}) : undefined;
|
|
3702
|
-
// Read Corepack `packageManager` field in package.json:
|
|
3703
|
-
// https://nodejs.org/api/packages.html#packagemanager
|
|
3704
|
-
const pkgManager = strings.isNonEmptyString(editablePkgJson?.content?.packageManager) ? editablePkgJson.content.packageManager : undefined;
|
|
3705
|
-
let agent;
|
|
3706
|
-
if (pkgManager) {
|
|
3707
|
-
// A valid "packageManager" field value is "<package manager name>@<version>".
|
|
3708
|
-
// https://nodejs.org/api/packages.html#packagemanager
|
|
3709
|
-
const atSignIndex = pkgManager.lastIndexOf('@');
|
|
3710
|
-
if (atSignIndex !== -1) {
|
|
3711
|
-
const name = pkgManager.slice(0, atSignIndex);
|
|
3712
|
-
const version = pkgManager.slice(atSignIndex + 1);
|
|
3713
|
-
if (version && AGENTS.includes(name)) {
|
|
3714
|
-
agent = name;
|
|
3715
|
-
}
|
|
3433
|
+
const blocked = action === 'error';
|
|
3434
|
+
const critical = alert.severity === ALERT_SEVERITY.critical;
|
|
3435
|
+
const cve = isArtifactAlertCve(alert);
|
|
3436
|
+
const fixType = alert.fix?.type ?? '';
|
|
3437
|
+
const fixableCve = fixType === ALERT_FIX_TYPE.cve;
|
|
3438
|
+
const fixableUpgrade = fixType === ALERT_FIX_TYPE.upgrade;
|
|
3439
|
+
const fixable = fixableCve || fixableUpgrade;
|
|
3440
|
+
const upgradable = fixableUpgrade && !require$$10.hasOwn(overrides, name);
|
|
3441
|
+
if (filterConfig.blocked && blocked || filterConfig.critical && critical || filterConfig.cve && cve || filterConfig.fixable && fixable || filterConfig.upgradable && upgradable) {
|
|
3442
|
+
sockPkgAlerts.push({
|
|
3443
|
+
name,
|
|
3444
|
+
version,
|
|
3445
|
+
key: alert.key,
|
|
3446
|
+
type: alert.type,
|
|
3447
|
+
blocked,
|
|
3448
|
+
critical,
|
|
3449
|
+
ecosystem,
|
|
3450
|
+
fixable,
|
|
3451
|
+
raw: alert,
|
|
3452
|
+
upgradable
|
|
3453
|
+
});
|
|
3716
3454
|
}
|
|
3717
3455
|
}
|
|
3718
|
-
if (
|
|
3719
|
-
|
|
3720
|
-
}
|
|
3721
|
-
if (agent === undefined) {
|
|
3722
|
-
agent = NPM;
|
|
3723
|
-
onUnknown?.(pkgManager);
|
|
3724
|
-
}
|
|
3725
|
-
const agentExecPath = await getAgentExecPath(agent);
|
|
3726
|
-
const agentVersion = await getAgentVersion(agent, agentExecPath, cwd);
|
|
3727
|
-
if (agent === YARN_CLASSIC && (agentVersion?.major ?? 0) > 1) {
|
|
3728
|
-
agent = YARN_BERRY;
|
|
3456
|
+
if (!sockPkgAlerts.length) {
|
|
3457
|
+
return alertsByPurl;
|
|
3729
3458
|
}
|
|
3730
|
-
const {
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
const browserslistQuery = editablePkgJson.content['browserslist'];
|
|
3768
|
-
if (Array.isArray(browserslistQuery)) {
|
|
3769
|
-
// List Node targets in ascending version order.
|
|
3770
|
-
const browserslistNodeTargets = vendor.browserslistExports(browserslistQuery).filter(v => /^node /i.test(v)).map(v => v.slice(5 /*'node '.length*/)).sort(sorts.naturalCompare);
|
|
3771
|
-
if (browserslistNodeTargets.length) {
|
|
3772
|
-
// browserslistNodeTargets[0] is the lowest Node target version.
|
|
3773
|
-
const coerced = vendor.semverExports.coerce(browserslistNodeTargets[0]);
|
|
3774
|
-
if (coerced && vendor.semverExports.lt(coerced, pkgMinNodeVersion)) {
|
|
3775
|
-
pkgMinNodeVersion = coerced.version;
|
|
3459
|
+
const purl = `pkg:${ecosystem}/${name}@${version}`;
|
|
3460
|
+
const major = getMajor(version);
|
|
3461
|
+
if (consolidate) {
|
|
3462
|
+
const highestForCve = new Map();
|
|
3463
|
+
const highestForUpgrade = new Map();
|
|
3464
|
+
const unfixableAlerts = [];
|
|
3465
|
+
for (const sockPkgAlert of sockPkgAlerts) {
|
|
3466
|
+
const alert = sockPkgAlert.raw;
|
|
3467
|
+
const fixType = alert.fix?.type ?? '';
|
|
3468
|
+
if (fixType === ALERT_FIX_TYPE.cve) {
|
|
3469
|
+
// An alert with alert.fix.type of 'cve' should have a
|
|
3470
|
+
// alert.props.firstPatchedVersionIdentifier property value.
|
|
3471
|
+
// We're just being cautious.
|
|
3472
|
+
const firstPatchedVersionIdentifier = alert.props?.firstPatchedVersionIdentifier;
|
|
3473
|
+
const patchedMajor = firstPatchedVersionIdentifier ? getMajor(firstPatchedVersionIdentifier) : null;
|
|
3474
|
+
if (typeof patchedMajor === 'number') {
|
|
3475
|
+
// Consolidate to the highest "first patched version" by each major
|
|
3476
|
+
// version number.
|
|
3477
|
+
const highest = highestForCve.get(patchedMajor)?.version ?? '0.0.0';
|
|
3478
|
+
if (vendor.semverExports.gt(firstPatchedVersionIdentifier, highest)) {
|
|
3479
|
+
highestForCve.set(patchedMajor, {
|
|
3480
|
+
alert: sockPkgAlert,
|
|
3481
|
+
version: firstPatchedVersionIdentifier
|
|
3482
|
+
});
|
|
3483
|
+
}
|
|
3484
|
+
} else {
|
|
3485
|
+
unfixableAlerts.push(sockPkgAlert);
|
|
3486
|
+
}
|
|
3487
|
+
} else if (fixType === ALERT_FIX_TYPE.upgrade) {
|
|
3488
|
+
// For Socket Optimize upgrades we assume the highest version available
|
|
3489
|
+
// is compatible. This may change in the future.
|
|
3490
|
+
const highest = highestForUpgrade.get(major)?.version ?? '0.0.0';
|
|
3491
|
+
if (vendor.semverExports.gt(version, highest)) {
|
|
3492
|
+
highestForUpgrade.set(major, {
|
|
3493
|
+
alert: sockPkgAlert,
|
|
3494
|
+
version
|
|
3495
|
+
});
|
|
3776
3496
|
}
|
|
3497
|
+
} else {
|
|
3498
|
+
unfixableAlerts.push(sockPkgAlert);
|
|
3777
3499
|
}
|
|
3778
3500
|
}
|
|
3779
|
-
|
|
3501
|
+
sockPkgAlerts = [
|
|
3502
|
+
// Sort CVE alerts by severity: critical, high, middle, then low.
|
|
3503
|
+
...Array.from(highestForCve.values()).map(d => d.alert).sort(alertSeverityComparator), ...Array.from(highestForUpgrade.values()).map(d => d.alert), ...unfixableAlerts];
|
|
3780
3504
|
} else {
|
|
3781
|
-
|
|
3782
|
-
lockPath = undefined;
|
|
3505
|
+
sockPkgAlerts.sort((a, b) => sorts.naturalCompare(a.type, b.type));
|
|
3783
3506
|
}
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
const nodeSupported = vendor.semverExports.satisfies(nodeVersion, minSupportedNodeRange);
|
|
3789
|
-
const npmExecPath = agent === NPM ? agentExecPath : await getAgentExecPath(NPM);
|
|
3790
|
-
const npmBuggyOverrides = agent === NPM && !!agentVersion && vendor.semverExports.lt(agentVersion, NPM_BUGGY_OVERRIDES_PATCHED_VERSION);
|
|
3791
|
-
const pkgMinAgentRange = `>=${pkgMinAgentVersion}`;
|
|
3792
|
-
const pkgMinNodeRange = `>=${vendor.semverExports.major(pkgMinNodeVersion)}`;
|
|
3793
|
-
return {
|
|
3794
|
-
agent,
|
|
3795
|
-
agentExecPath,
|
|
3796
|
-
agentSupported,
|
|
3797
|
-
agentVersion,
|
|
3798
|
-
editablePkgJson,
|
|
3799
|
-
features: {
|
|
3800
|
-
npmBuggyOverrides
|
|
3801
|
-
},
|
|
3802
|
-
lockName,
|
|
3803
|
-
lockPath,
|
|
3804
|
-
lockSrc,
|
|
3805
|
-
nodeSupported,
|
|
3806
|
-
nodeVersion,
|
|
3807
|
-
npmExecPath,
|
|
3808
|
-
pkgPath,
|
|
3809
|
-
pkgRequirements: {
|
|
3810
|
-
agent: pkgAgentRange ?? pkgMinAgentRange,
|
|
3811
|
-
node: pkgNodeRange ?? pkgMinNodeRange
|
|
3812
|
-
},
|
|
3813
|
-
pkgSupports: {
|
|
3814
|
-
// Does our minimum supported agent version meet the package's requirements?
|
|
3815
|
-
agent: vendor.semverExports.satisfies(minSupportedAgentVersion, pkgMinAgentRange),
|
|
3816
|
-
// Does our supported Node versions meet the package's requirements?
|
|
3817
|
-
node: maintainedNodeVersions.some(v => vendor.semverExports.satisfies(v, pkgMinNodeRange))
|
|
3818
|
-
}
|
|
3819
|
-
};
|
|
3507
|
+
if (sockPkgAlerts.length) {
|
|
3508
|
+
alertsByPurl.set(purl, sockPkgAlerts);
|
|
3509
|
+
}
|
|
3510
|
+
return alertsByPurl;
|
|
3820
3511
|
}
|
|
3821
|
-
|
|
3512
|
+
function alertsHaveBlocked(alerts) {
|
|
3513
|
+
return alerts.find(a => a.blocked) !== undefined;
|
|
3514
|
+
}
|
|
3515
|
+
function alertsHaveSeverity(alerts, severity) {
|
|
3516
|
+
return alerts.find(a => a.raw.severity === severity) !== undefined;
|
|
3517
|
+
}
|
|
3518
|
+
function alertSeverityComparator(a, b) {
|
|
3519
|
+
// Put the most severe first.
|
|
3520
|
+
return getAlertSeverityOrder(a) - getAlertSeverityOrder(b);
|
|
3521
|
+
}
|
|
3522
|
+
function getAlertSeverityOrder(alert) {
|
|
3523
|
+
// The more severe, the lower the sort number.
|
|
3822
3524
|
const {
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3525
|
+
severity
|
|
3526
|
+
} = alert.raw;
|
|
3527
|
+
return severity === ALERT_SEVERITY.critical ? 0 : severity === ALERT_SEVERITY.high ? 1 : severity === ALERT_SEVERITY.middle ? 2 : severity === ALERT_SEVERITY.low ? 3 : 4;
|
|
3528
|
+
}
|
|
3529
|
+
function getAlertsSeverityOrder(alerts) {
|
|
3530
|
+
return alertsHaveBlocked(alerts) || alertsHaveSeverity(alerts, ALERT_SEVERITY.critical) ? 0 : alertsHaveSeverity(alerts, ALERT_SEVERITY.high) ? 1 : alertsHaveSeverity(alerts, ALERT_SEVERITY.middle) ? 2 : alertsHaveSeverity(alerts, ALERT_SEVERITY.low) ? 3 : 4;
|
|
3531
|
+
}
|
|
3532
|
+
function getSeverityLabel(severity) {
|
|
3533
|
+
return severity === 'middle' ? 'moderate' : severity;
|
|
3534
|
+
}
|
|
3535
|
+
function logAlertsMap(alertsMap, options) {
|
|
3536
|
+
const {
|
|
3537
|
+
hideAt = 'middle',
|
|
3538
|
+
output = process.stderr
|
|
3826
3539
|
} = {
|
|
3827
3540
|
__proto__: null,
|
|
3828
3541
|
...options
|
|
3829
3542
|
};
|
|
3830
|
-
const
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3543
|
+
const translations = getTranslations();
|
|
3544
|
+
const sortedEntries = Array.from(alertsMap.entries()).sort((a, b) => getAlertsSeverityOrder(a[1]) - getAlertsSeverityOrder(b[1]));
|
|
3545
|
+
const aboveTheFoldPurls = new Set();
|
|
3546
|
+
const viewableAlertsByPurl = new Map();
|
|
3547
|
+
const hiddenAlertsByPurl = new Map();
|
|
3548
|
+
for (let i = 0, {
|
|
3549
|
+
length
|
|
3550
|
+
} = sortedEntries; i < length; i += 1) {
|
|
3551
|
+
const {
|
|
3552
|
+
0: purl,
|
|
3553
|
+
1: alerts
|
|
3554
|
+
} = sortedEntries[i];
|
|
3555
|
+
const hiddenAlerts = [];
|
|
3556
|
+
const viewableAlerts = alerts.filter(a => {
|
|
3557
|
+
const keep = a.blocked || getAlertSeverityOrder(a) < ALERT_SEVERITY_ORDER[hideAt];
|
|
3558
|
+
if (!keep) {
|
|
3559
|
+
hiddenAlerts.push(a);
|
|
3560
|
+
}
|
|
3561
|
+
return keep;
|
|
3562
|
+
});
|
|
3563
|
+
if (hiddenAlerts.length) {
|
|
3564
|
+
hiddenAlertsByPurl.set(purl, hiddenAlerts.sort(alertSeverityComparator));
|
|
3565
|
+
}
|
|
3566
|
+
if (!viewableAlerts.length) {
|
|
3567
|
+
continue;
|
|
3568
|
+
}
|
|
3569
|
+
viewableAlerts.sort(alertSeverityComparator);
|
|
3570
|
+
viewableAlertsByPurl.set(purl, viewableAlerts);
|
|
3571
|
+
if (viewableAlerts.find(a => a.blocked || getAlertSeverityOrder(a) < ALERT_SEVERITY_ORDER.middle)) {
|
|
3572
|
+
aboveTheFoldPurls.add(purl);
|
|
3834
3573
|
}
|
|
3835
|
-
});
|
|
3836
|
-
const {
|
|
3837
|
-
agent,
|
|
3838
|
-
nodeVersion,
|
|
3839
|
-
pkgRequirements
|
|
3840
|
-
} = details;
|
|
3841
|
-
const agentVersion = details.agentVersion ?? 'unknown';
|
|
3842
|
-
if (!details.agentSupported) {
|
|
3843
|
-
const minVersion = constants.minimumVersionByAgent.get(agent);
|
|
3844
|
-
return {
|
|
3845
|
-
ok: false,
|
|
3846
|
-
message: 'Version mismatch',
|
|
3847
|
-
cause: cmdPrefixMessage(cmdName, `Requires ${agent} >=${minVersion}. Current version: ${agentVersion}.`)
|
|
3848
|
-
};
|
|
3849
|
-
}
|
|
3850
|
-
if (!details.nodeSupported) {
|
|
3851
|
-
const minVersion = constants.maintainedNodeVersions.last;
|
|
3852
|
-
return {
|
|
3853
|
-
ok: false,
|
|
3854
|
-
message: 'Version mismatch',
|
|
3855
|
-
cause: cmdPrefixMessage(cmdName, `Requires Node >=${minVersion}. Current version: ${nodeVersion}.`)
|
|
3856
|
-
};
|
|
3857
|
-
}
|
|
3858
|
-
if (!details.pkgSupports.agent) {
|
|
3859
|
-
return {
|
|
3860
|
-
ok: false,
|
|
3861
|
-
message: 'Engine mismatch',
|
|
3862
|
-
cause: cmdPrefixMessage(cmdName, `Package engine "${agent}" requires ${pkgRequirements.agent}. Current version: ${agentVersion}`)
|
|
3863
|
-
};
|
|
3864
|
-
}
|
|
3865
|
-
if (!details.pkgSupports.node) {
|
|
3866
|
-
return {
|
|
3867
|
-
ok: false,
|
|
3868
|
-
message: 'Version mismatch',
|
|
3869
|
-
cause: cmdPrefixMessage(cmdName, `Package engine "node" requires ${pkgRequirements.node}. Current version: ${nodeVersion}`)
|
|
3870
|
-
};
|
|
3871
|
-
}
|
|
3872
|
-
const lockName = details.lockName ?? 'lock file';
|
|
3873
|
-
if (details.lockName === undefined || details.lockSrc === undefined) {
|
|
3874
|
-
return {
|
|
3875
|
-
ok: false,
|
|
3876
|
-
message: 'Missing lockfile',
|
|
3877
|
-
cause: cmdPrefixMessage(cmdName, `No ${lockName} found`)
|
|
3878
|
-
};
|
|
3879
3574
|
}
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3575
|
+
|
|
3576
|
+
// If MIN_ABOVE_THE_FOLD_COUNT is NOT met add more from viewable pkg ids.
|
|
3577
|
+
for (const {
|
|
3578
|
+
0: purl
|
|
3579
|
+
} of viewableAlertsByPurl.entries()) {
|
|
3580
|
+
if (aboveTheFoldPurls.size >= MIN_ABOVE_THE_FOLD_COUNT) {
|
|
3581
|
+
break;
|
|
3582
|
+
}
|
|
3583
|
+
aboveTheFoldPurls.add(purl);
|
|
3886
3584
|
}
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3585
|
+
// If MIN_ABOVE_THE_FOLD_COUNT is STILL NOT met add more from hidden pkg ids.
|
|
3586
|
+
for (const {
|
|
3587
|
+
0: purl,
|
|
3588
|
+
1: hiddenAlerts
|
|
3589
|
+
} of hiddenAlertsByPurl.entries()) {
|
|
3590
|
+
if (aboveTheFoldPurls.size >= MIN_ABOVE_THE_FOLD_COUNT) {
|
|
3591
|
+
break;
|
|
3592
|
+
}
|
|
3593
|
+
aboveTheFoldPurls.add(purl);
|
|
3594
|
+
const viewableAlerts = viewableAlertsByPurl.get(purl) ?? [];
|
|
3595
|
+
if (viewableAlerts.length < MIN_ABOVE_THE_FOLD_ALERT_COUNT) {
|
|
3596
|
+
const neededCount = MIN_ABOVE_THE_FOLD_ALERT_COUNT - viewableAlerts.length;
|
|
3597
|
+
let removedHiddenAlerts;
|
|
3598
|
+
if (hiddenAlerts.length - neededCount > 0) {
|
|
3599
|
+
removedHiddenAlerts = hiddenAlerts.splice(0, MIN_ABOVE_THE_FOLD_ALERT_COUNT);
|
|
3600
|
+
} else {
|
|
3601
|
+
removedHiddenAlerts = hiddenAlerts;
|
|
3602
|
+
hiddenAlertsByPurl.delete(purl);
|
|
3603
|
+
}
|
|
3604
|
+
viewableAlertsByPurl.set(purl, [...viewableAlerts, ...removedHiddenAlerts]);
|
|
3605
|
+
}
|
|
3893
3606
|
}
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3607
|
+
const mentionedPurlsWithHiddenAlerts = new Set();
|
|
3608
|
+
for (let i = 0, prevAboveTheFold = true, entries = Array.from(viewableAlertsByPurl.entries()), {
|
|
3609
|
+
length
|
|
3610
|
+
} = entries; i < length; i += 1) {
|
|
3611
|
+
const {
|
|
3612
|
+
0: purl,
|
|
3613
|
+
1: alerts
|
|
3614
|
+
} = entries[i];
|
|
3615
|
+
const lines = new Set();
|
|
3616
|
+
for (const alert of alerts) {
|
|
3617
|
+
const {
|
|
3618
|
+
type
|
|
3619
|
+
} = alert;
|
|
3620
|
+
const severity = alert.raw.severity ?? '';
|
|
3621
|
+
const attributes = [...(severity ? [vendor.yoctocolorsCjsExports[ALERT_SEVERITY_COLOR[severity]](getSeverityLabel(severity))] : []), ...(alert.blocked ? [vendor.yoctocolorsCjsExports.bold(vendor.yoctocolorsCjsExports.red('blocked'))] : []), ...(alert.fixable ? ['fixable'] : [])];
|
|
3622
|
+
const maybeAttributes = attributes.length ? ` ${vendor.yoctocolorsCjsExports.italic(`(${attributes.join('; ')})`)}` : '';
|
|
3623
|
+
// Based data from { pageProps: { alertTypes } } of:
|
|
3624
|
+
// https://socket.dev/_next/data/9a6db8224b68b6da0eb9f7dbb17aff7e51568ac2/en-US.json
|
|
3625
|
+
const info = translations.alerts[type];
|
|
3626
|
+
const title = info?.title ?? type;
|
|
3627
|
+
const maybeDesc = info?.description ? ` - ${info.description}` : '';
|
|
3628
|
+
const content = `${title}${maybeAttributes}${maybeDesc}`;
|
|
3629
|
+
// TODO: An added emoji seems to mis-align terminals sometimes.
|
|
3630
|
+
lines.add(` ${content}`);
|
|
3631
|
+
}
|
|
3632
|
+
const purlObj = getPurlObject(purl);
|
|
3633
|
+
const pkgName = packages.resolvePackageName(purlObj);
|
|
3634
|
+
const hyperlink = format.hyperlink(`${pkgName}@${purlObj.version}`, getSocketDevPackageOverviewUrl(purlObj.type, pkgName, purlObj.version));
|
|
3635
|
+
const isAboveTheFold = aboveTheFoldPurls.has(purl);
|
|
3636
|
+
if (isAboveTheFold) {
|
|
3637
|
+
aboveTheFoldPurls.add(purl);
|
|
3638
|
+
output.write(`${i ? '\n' : ''}${hyperlink}:\n`);
|
|
3639
|
+
} else {
|
|
3640
|
+
output.write(`${prevAboveTheFold ? '\n' : ''}${hyperlink}:\n`);
|
|
3641
|
+
}
|
|
3642
|
+
for (const line of lines) {
|
|
3643
|
+
output.write(`${line}\n`);
|
|
3644
|
+
}
|
|
3645
|
+
const hiddenAlerts = hiddenAlertsByPurl.get(purl) ?? [];
|
|
3646
|
+
const {
|
|
3647
|
+
length: hiddenAlertsCount
|
|
3648
|
+
} = hiddenAlerts;
|
|
3649
|
+
if (hiddenAlertsCount) {
|
|
3650
|
+
mentionedPurlsWithHiddenAlerts.add(purl);
|
|
3651
|
+
if (hiddenAlertsCount === 1) {
|
|
3652
|
+
output.write(` ${vendor.yoctocolorsCjsExports.dim(`+1 Hidden ${getSeverityLabel(hiddenAlerts[0].raw.severity ?? 'low')} risk alert`)}\n`);
|
|
3653
|
+
} else {
|
|
3654
|
+
output.write(` ${vendor.yoctocolorsCjsExports.dim(`+${hiddenAlertsCount} Hidden alerts ${vendor.yoctocolorsCjsExports.italic(getHiddenRisksDescription(getHiddenRiskCounts(hiddenAlerts)))}`)}\n`);
|
|
3655
|
+
}
|
|
3656
|
+
}
|
|
3657
|
+
prevAboveTheFold = isAboveTheFold;
|
|
3900
3658
|
}
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3659
|
+
const additionalHiddenCount = hiddenAlertsByPurl.size - mentionedPurlsWithHiddenAlerts.size;
|
|
3660
|
+
if (additionalHiddenCount) {
|
|
3661
|
+
const totalRiskCounts = {
|
|
3662
|
+
critical: 0,
|
|
3663
|
+
high: 0,
|
|
3664
|
+
middle: 0,
|
|
3665
|
+
low: 0
|
|
3666
|
+
};
|
|
3667
|
+
for (const {
|
|
3668
|
+
0: purl,
|
|
3669
|
+
1: alerts
|
|
3670
|
+
} of hiddenAlertsByPurl.entries()) {
|
|
3671
|
+
if (mentionedPurlsWithHiddenAlerts.has(purl)) {
|
|
3672
|
+
continue;
|
|
3673
|
+
}
|
|
3674
|
+
const riskCounts = getHiddenRiskCounts(alerts);
|
|
3675
|
+
totalRiskCounts.critical += riskCounts.critical;
|
|
3676
|
+
totalRiskCounts.high += riskCounts.high;
|
|
3677
|
+
totalRiskCounts.middle += riskCounts.middle;
|
|
3678
|
+
totalRiskCounts.low += riskCounts.low;
|
|
3679
|
+
}
|
|
3680
|
+
output.write(`${aboveTheFoldPurls.size ? '\n' : ''}${vendor.yoctocolorsCjsExports.dim(`${aboveTheFoldPurls.size ? '+' : ''}${additionalHiddenCount} Packages with hidden alerts ${vendor.yoctocolorsCjsExports.italic(getHiddenRisksDescription(totalRiskCounts))}`)}\n`);
|
|
3904
3681
|
}
|
|
3905
|
-
|
|
3906
|
-
ok: true,
|
|
3907
|
-
data: details
|
|
3908
|
-
};
|
|
3682
|
+
output.write('\n');
|
|
3909
3683
|
}
|
|
3910
3684
|
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3685
|
+
function idToNpmPurl(id) {
|
|
3686
|
+
return `pkg:npm/${id}`;
|
|
3687
|
+
}
|
|
3688
|
+
|
|
3689
|
+
async function getAlertsMapFromPurls(purls, options) {
|
|
3690
|
+
const uniqPurls = arrays.arrayUnique(purls);
|
|
3691
|
+
require$$9.debugDir('silly', {
|
|
3692
|
+
purls: uniqPurls
|
|
3693
|
+
});
|
|
3694
|
+
let {
|
|
3695
|
+
length: remaining
|
|
3696
|
+
} = uniqPurls;
|
|
3697
|
+
const alertsByPurl = new Map();
|
|
3698
|
+
if (!remaining) {
|
|
3699
|
+
return alertsByPurl;
|
|
3921
3700
|
}
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3701
|
+
const opts = {
|
|
3702
|
+
__proto__: null,
|
|
3703
|
+
consolidate: false,
|
|
3704
|
+
nothrow: false,
|
|
3705
|
+
...options,
|
|
3706
|
+
filter: toFilterConfig(require$$10.getOwn(options, 'filter'))
|
|
3925
3707
|
};
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
const sourcingCommand = getCompletionSourcingCommand();
|
|
3929
|
-
if (!sourcingCommand.ok) {
|
|
3930
|
-
return sourcingCommand;
|
|
3708
|
+
if (opts.onlyFixable) {
|
|
3709
|
+
opts.filter.fixable = true;
|
|
3931
3710
|
}
|
|
3932
3711
|
const {
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3712
|
+
apiToken = getPublicApiToken(),
|
|
3713
|
+
spinner
|
|
3714
|
+
} = opts;
|
|
3715
|
+
const getText = () => `Looking up data for ${remaining} packages`;
|
|
3716
|
+
spinner?.start(getText());
|
|
3717
|
+
const sockSdkCResult = await setupSdk({
|
|
3718
|
+
apiToken
|
|
3719
|
+
});
|
|
3720
|
+
if (!sockSdkCResult.ok) {
|
|
3721
|
+
spinner?.stop();
|
|
3722
|
+
throw new Error('Auth error: Run `socket login` first');
|
|
3941
3723
|
}
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
const
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
# Load the tab completion script
|
|
3951
|
-
source "${completionScriptPath}"
|
|
3952
|
-
# Tell bash to use this function for tab completion of this function
|
|
3953
|
-
${completionCommand}
|
|
3954
|
-
fi
|
|
3955
|
-
`;
|
|
3956
|
-
return {
|
|
3957
|
-
ok: true,
|
|
3958
|
-
data: {
|
|
3959
|
-
sourcingCommand: sourcingCommand.data,
|
|
3960
|
-
completionCommand,
|
|
3961
|
-
toAddToBashrc: bashrcContent,
|
|
3962
|
-
targetName: targetCommandName,
|
|
3963
|
-
targetPath: completionScriptPath
|
|
3964
|
-
}
|
|
3724
|
+
const sockSdk = sockSdkCResult.data;
|
|
3725
|
+
const socketYml = findSocketYmlSync()?.parsed;
|
|
3726
|
+
const alertsMapOptions = {
|
|
3727
|
+
consolidate: opts.consolidate,
|
|
3728
|
+
filter: opts.filter,
|
|
3729
|
+
overrides: opts.overrides,
|
|
3730
|
+
socketYml,
|
|
3731
|
+
spinner
|
|
3965
3732
|
};
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
}
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
}
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3733
|
+
try {
|
|
3734
|
+
for await (const batchResult of sockSdk.batchPackageStream({
|
|
3735
|
+
components: uniqPurls.map(purl => ({
|
|
3736
|
+
purl
|
|
3737
|
+
}))
|
|
3738
|
+
}, {
|
|
3739
|
+
queryParams: {
|
|
3740
|
+
alerts: 'true',
|
|
3741
|
+
compact: 'true',
|
|
3742
|
+
...(opts.onlyFixable ? {
|
|
3743
|
+
fixable: 'true '
|
|
3744
|
+
} : {}),
|
|
3745
|
+
...(Array.isArray(opts.filter.actions) ? {
|
|
3746
|
+
actions: opts.filter.actions.join(',')
|
|
3747
|
+
} : {})
|
|
3748
|
+
}
|
|
3749
|
+
})) {
|
|
3750
|
+
if (batchResult.success) {
|
|
3751
|
+
const artifact = batchResult.data;
|
|
3752
|
+
await addArtifactToAlertsMap(artifact, alertsByPurl, alertsMapOptions);
|
|
3753
|
+
} else if (!opts.nothrow) {
|
|
3754
|
+
spinner?.stop();
|
|
3755
|
+
if (strings.isNonEmptyString(batchResult.error)) {
|
|
3756
|
+
throw new Error(batchResult.error);
|
|
3757
|
+
}
|
|
3758
|
+
const statusCode = batchResult.status ?? 'unknown';
|
|
3759
|
+
throw new Error(`Socket API server error (${statusCode}): No status message`);
|
|
3760
|
+
} else {
|
|
3761
|
+
spinner?.stop();
|
|
3762
|
+
logger.logger.fail(`Received a ${batchResult.status} response from Socket API which we consider a permanent failure:`, batchResult.error, batchResult.cause ? `( ${batchResult.cause} )` : '');
|
|
3763
|
+
require$$9.debugDir('inspect', {
|
|
3764
|
+
batchResult
|
|
3765
|
+
});
|
|
3766
|
+
break;
|
|
3767
|
+
}
|
|
3768
|
+
remaining -= 1;
|
|
3769
|
+
if (remaining > 0) {
|
|
3770
|
+
spinner?.start(getText());
|
|
3771
|
+
}
|
|
3772
|
+
}
|
|
3773
|
+
} catch (e) {
|
|
3774
|
+
spinner?.stop();
|
|
3775
|
+
throw e;
|
|
3991
3776
|
}
|
|
3992
|
-
|
|
3993
|
-
return
|
|
3994
|
-
}
|
|
3995
|
-
|
|
3996
|
-
const ALL_ECOSYSTEMS = ['apk', 'bitbucket', 'cargo', 'chrome', 'cocoapods', 'composer', 'conan', 'conda', 'cran', 'deb', 'docker', 'gem', 'generic', 'github', 'golang', 'hackage', 'hex', 'huggingface', 'maven', 'mlflow', 'npm', 'nuget', 'oci', 'pub', 'pypi', 'qpkg', 'rpm', 'swift', 'swid', 'unknown'];
|
|
3997
|
-
new Set(ALL_ECOSYSTEMS);
|
|
3998
|
-
function getEcosystemChoicesForMeow() {
|
|
3999
|
-
return [...ALL_ECOSYSTEMS];
|
|
3777
|
+
spinner?.stop();
|
|
3778
|
+
return alertsByPurl;
|
|
4000
3779
|
}
|
|
4001
3780
|
|
|
4002
3781
|
exports.AuthError = AuthError;
|
|
4003
3782
|
exports.COMPLETION_CMD_PREFIX = COMPLETION_CMD_PREFIX;
|
|
4004
3783
|
exports.InputError = InputError;
|
|
4005
3784
|
exports.RangeStyles = RangeStyles;
|
|
4006
|
-
exports.applyRange = applyRange;
|
|
4007
3785
|
exports.captureException = captureException;
|
|
4008
3786
|
exports.checkCommandInput = checkCommandInput;
|
|
4009
3787
|
exports.cmdFlagValueToArray = cmdFlagValueToArray;
|
|
@@ -4013,32 +3791,27 @@ exports.createEnum = createEnum;
|
|
|
4013
3791
|
exports.detectAndValidatePackageEnvironment = detectAndValidatePackageEnvironment;
|
|
4014
3792
|
exports.detectDefaultBranch = detectDefaultBranch;
|
|
4015
3793
|
exports.determineOrgSlug = determineOrgSlug;
|
|
4016
|
-
exports.extractOverridesFromPnpmLockSrc = extractOverridesFromPnpmLockSrc;
|
|
4017
3794
|
exports.extractTier1ReachabilityScanId = extractTier1ReachabilityScanId;
|
|
4018
3795
|
exports.failMsgWithBadge = failMsgWithBadge;
|
|
4019
3796
|
exports.fetchOrganization = fetchOrganization;
|
|
4020
|
-
exports.
|
|
3797
|
+
exports.findUp = findUp;
|
|
4021
3798
|
exports.getAlertsMapFromPurls = getAlertsMapFromPurls;
|
|
4022
3799
|
exports.getBaseBranch = getBaseBranch;
|
|
4023
3800
|
exports.getBashrcDetails = getBashrcDetails;
|
|
4024
3801
|
exports.getConfigValue = getConfigValue;
|
|
4025
3802
|
exports.getConfigValueOrUndef = getConfigValueOrUndef;
|
|
4026
|
-
exports.getCveInfoFromAlertsMap = getCveInfoFromAlertsMap;
|
|
4027
3803
|
exports.getDefaultOrgSlug = getDefaultOrgSlug;
|
|
4028
3804
|
exports.getEcosystemChoicesForMeow = getEcosystemChoicesForMeow;
|
|
4029
3805
|
exports.getEnterpriseOrgs = getEnterpriseOrgs;
|
|
4030
3806
|
exports.getFlagApiRequirementsOutput = getFlagApiRequirementsOutput;
|
|
4031
3807
|
exports.getFlagListOutput = getFlagListOutput;
|
|
4032
3808
|
exports.getMajor = getMajor;
|
|
4033
|
-
exports.getMinVersion = getMinVersion;
|
|
4034
3809
|
exports.getNpmBinPath = getNpmBinPath;
|
|
4035
|
-
exports.getNpmConfig = getNpmConfig;
|
|
4036
3810
|
exports.getNpmRequire = getNpmRequire;
|
|
4037
3811
|
exports.getNpxBinPath = getNpxBinPath;
|
|
4038
3812
|
exports.getOrgSlugs = getOrgSlugs;
|
|
4039
3813
|
exports.getOutputKind = getOutputKind;
|
|
4040
3814
|
exports.getPackageFilesForScan = getPackageFilesForScan;
|
|
4041
|
-
exports.getPkgFullNameFromPurl = getPkgFullNameFromPurl;
|
|
4042
3815
|
exports.getPublicApiToken = getPublicApiToken;
|
|
4043
3816
|
exports.getPurlObject = getPurlObject;
|
|
4044
3817
|
exports.getRepoInfo = getRepoInfo;
|
|
@@ -4062,7 +3835,6 @@ exports.handleApiCallNoSpinner = handleApiCallNoSpinner;
|
|
|
4062
3835
|
exports.hasDefaultApiToken = hasDefaultApiToken;
|
|
4063
3836
|
exports.hasEnterpriseOrgPlan = hasEnterpriseOrgPlan;
|
|
4064
3837
|
exports.idToNpmPurl = idToNpmPurl;
|
|
4065
|
-
exports.idToPurl = idToPurl;
|
|
4066
3838
|
exports.isHelpFlag = isHelpFlag;
|
|
4067
3839
|
exports.isNpmBinPathShadowed = isNpmBinPathShadowed;
|
|
4068
3840
|
exports.isNpxBinPathShadowed = isNpxBinPathShadowed;
|
|
@@ -4079,14 +3851,10 @@ exports.meowOrExit = meowOrExit;
|
|
|
4079
3851
|
exports.meowWithSubcommands = meowWithSubcommands;
|
|
4080
3852
|
exports.msAtHome = msAtHome;
|
|
4081
3853
|
exports.npa = npa;
|
|
4082
|
-
exports.parsePnpmLockfile = parsePnpmLockfile;
|
|
4083
|
-
exports.parsePnpmLockfileVersion = parsePnpmLockfileVersion;
|
|
4084
3854
|
exports.queryApiSafeJson = queryApiSafeJson;
|
|
4085
3855
|
exports.queryApiSafeText = queryApiSafeText;
|
|
4086
|
-
exports.readLockfile = readLockfile;
|
|
4087
3856
|
exports.readOrDefaultSocketJson = readOrDefaultSocketJson;
|
|
4088
3857
|
exports.readSocketJsonSync = readSocketJsonSync;
|
|
4089
|
-
exports.removeNodeModules = removeNodeModules;
|
|
4090
3858
|
exports.runAgentInstall = runAgentInstall;
|
|
4091
3859
|
exports.sendApiRequest = sendApiRequest;
|
|
4092
3860
|
exports.serializeResultJson = serializeResultJson;
|
|
@@ -4098,5 +3866,5 @@ exports.toFilterConfig = toFilterConfig;
|
|
|
4098
3866
|
exports.updateConfigValue = updateConfigValue;
|
|
4099
3867
|
exports.walkNestedMap = walkNestedMap;
|
|
4100
3868
|
exports.writeSocketJson = writeSocketJson;
|
|
4101
|
-
//# debugId=
|
|
3869
|
+
//# debugId=6bbbb6b9-ace3-439a-9c19-0674a8ba872d
|
|
4102
3870
|
//# sourceMappingURL=utils.js.map
|