@openrewrite/recipes-nodejs 0.37.0-20260106-082310 → 0.37.0-20260106-104324
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/security/dependency-vulnerability-check.d.ts +6 -54
- package/dist/security/dependency-vulnerability-check.d.ts.map +1 -1
- package/dist/security/dependency-vulnerability-check.js +133 -259
- package/dist/security/dependency-vulnerability-check.js.map +1 -1
- package/dist/security/index.d.ts +3 -0
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +3 -0
- package/dist/security/index.js.map +1 -1
- package/dist/security/npm-utils.d.ts +8 -2
- package/dist/security/npm-utils.d.ts.map +1 -1
- package/dist/security/npm-utils.js +114 -14
- package/dist/security/npm-utils.js.map +1 -1
- package/dist/security/override-utils.d.ts +23 -0
- package/dist/security/override-utils.d.ts.map +1 -0
- package/dist/security/override-utils.js +169 -0
- package/dist/security/override-utils.js.map +1 -0
- package/dist/security/remove-redundant-overrides.d.ts +1 -10
- package/dist/security/remove-redundant-overrides.d.ts.map +1 -1
- package/dist/security/remove-redundant-overrides.js +4 -152
- package/dist/security/remove-redundant-overrides.js.map +1 -1
- package/dist/security/types.d.ts +42 -0
- package/dist/security/types.d.ts.map +1 -0
- package/dist/security/types.js +7 -0
- package/dist/security/types.js.map +1 -0
- package/dist/security/version-utils.d.ts +13 -0
- package/dist/security/version-utils.d.ts.map +1 -0
- package/dist/security/version-utils.js +173 -0
- package/dist/security/version-utils.js.map +1 -0
- package/package.json +1 -1
- package/src/security/dependency-vulnerability-check.ts +232 -485
- package/src/security/index.ts +3 -0
- package/src/security/npm-utils.ts +172 -37
- package/src/security/override-utils.ts +253 -0
- package/src/security/remove-redundant-overrides.ts +9 -211
- package/src/security/types.ts +116 -0
- package/src/security/version-utils.ts +198 -0
|
@@ -49,8 +49,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
49
49
|
};
|
|
50
50
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
51
51
|
exports.DependencyVulnerabilityCheck = void 0;
|
|
52
|
-
exports.extractVersionPrefix = extractVersionPrefix;
|
|
53
|
-
exports.applyVersionPrefix = applyVersionPrefix;
|
|
54
52
|
const rewrite_1 = require("@openrewrite/rewrite");
|
|
55
53
|
const json_1 = require("@openrewrite/rewrite/json");
|
|
56
54
|
const text_1 = require("@openrewrite/rewrite/text");
|
|
@@ -60,9 +58,9 @@ const semver = __importStar(require("semver"));
|
|
|
60
58
|
const path = __importStar(require("path"));
|
|
61
59
|
const vulnerability_1 = require("./vulnerability");
|
|
62
60
|
const npm_utils_1 = require("./npm-utils");
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
const version_utils_1 = require("./version-utils");
|
|
62
|
+
const types_1 = require("./types");
|
|
63
|
+
const override_utils_1 = require("./override-utils");
|
|
66
64
|
class VulnerabilityReportRow {
|
|
67
65
|
constructor(sourcePath, cve, packageName, version, fixedVersion, lastAffectedVersion, upgradeable, summary, severity, depth, cwes, isDirect, dependencyPath) {
|
|
68
66
|
this.sourcePath = sourcePath;
|
|
@@ -189,9 +187,6 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
189
187
|
shouldScanTransitives() {
|
|
190
188
|
return this.transitiveFixStrategy !== 'report';
|
|
191
189
|
}
|
|
192
|
-
shouldFixTransitives() {
|
|
193
|
-
return this.transitiveFixStrategy !== 'report';
|
|
194
|
-
}
|
|
195
190
|
shouldVerifyTransitiveFixes() {
|
|
196
191
|
return this.transitiveFixStrategy === 'override' ||
|
|
197
192
|
this.transitiveFixStrategy === 'prefer-direct-upgrade';
|
|
@@ -199,7 +194,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
199
194
|
filterRemainingTransitiveFixes(fixes, lockFileContent, packageManager, db) {
|
|
200
195
|
const result = [];
|
|
201
196
|
for (const fix of fixes) {
|
|
202
|
-
if (!fix.isTransitive || fix.
|
|
197
|
+
if (!fix.isTransitive || (fix.fixViaDirectUpgrades && fix.fixViaDirectUpgrades.length > 0)) {
|
|
203
198
|
result.push(fix);
|
|
204
199
|
continue;
|
|
205
200
|
}
|
|
@@ -217,7 +212,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
217
212
|
isVersionStillVulnerable(packageName, version, cves, db) {
|
|
218
213
|
const vulns = db.getVulnerabilities(packageName);
|
|
219
214
|
for (const vuln of vulns) {
|
|
220
|
-
if (cves.includes(vuln.cve) &&
|
|
215
|
+
if (cves.includes(vuln.cve) && (0, version_utils_1.isVersionAffected)(version, vuln)) {
|
|
221
216
|
return true;
|
|
222
217
|
}
|
|
223
218
|
}
|
|
@@ -235,100 +230,6 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
235
230
|
}
|
|
236
231
|
return this.cvePatternRegex.test(vulnerability.cve);
|
|
237
232
|
}
|
|
238
|
-
isVersionAffected(version, vulnerability) {
|
|
239
|
-
try {
|
|
240
|
-
const v = semver.parse(version);
|
|
241
|
-
if (!v)
|
|
242
|
-
return false;
|
|
243
|
-
if (vulnerability.introducedVersion && vulnerability.introducedVersion !== '0') {
|
|
244
|
-
const introduced = semver.parse(vulnerability.introducedVersion);
|
|
245
|
-
if (introduced && semver.lt(v, introduced)) {
|
|
246
|
-
return false;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
if (vulnerability.fixedVersion) {
|
|
250
|
-
const fixed = semver.parse(vulnerability.fixedVersion);
|
|
251
|
-
if (fixed && semver.gte(v, fixed)) {
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
254
|
-
return true;
|
|
255
|
-
}
|
|
256
|
-
if (vulnerability.lastAffectedVersion) {
|
|
257
|
-
const lastAffected = semver.parse(vulnerability.lastAffectedVersion);
|
|
258
|
-
if (lastAffected && semver.gt(v, lastAffected)) {
|
|
259
|
-
return false;
|
|
260
|
-
}
|
|
261
|
-
return true;
|
|
262
|
-
}
|
|
263
|
-
return true;
|
|
264
|
-
}
|
|
265
|
-
catch (_a) {
|
|
266
|
-
return false;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
isUpgradeableWithinDelta(currentVersion, vulnerability) {
|
|
270
|
-
if (this.isReportOnly()) {
|
|
271
|
-
return false;
|
|
272
|
-
}
|
|
273
|
-
try {
|
|
274
|
-
const current = semver.parse(currentVersion);
|
|
275
|
-
if (!current)
|
|
276
|
-
return false;
|
|
277
|
-
const delta = this.maximumUpgradeDelta;
|
|
278
|
-
if (vulnerability.fixedVersion) {
|
|
279
|
-
const fixed = semver.parse(vulnerability.fixedVersion);
|
|
280
|
-
if (!fixed)
|
|
281
|
-
return false;
|
|
282
|
-
switch (delta) {
|
|
283
|
-
case 'patch':
|
|
284
|
-
return current.major === fixed.major && current.minor === fixed.minor;
|
|
285
|
-
case 'minor':
|
|
286
|
-
return current.major === fixed.major;
|
|
287
|
-
case 'major':
|
|
288
|
-
return true;
|
|
289
|
-
case 'none':
|
|
290
|
-
return false;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
if (vulnerability.lastAffectedVersion) {
|
|
294
|
-
const lastAffected = semver.parse(vulnerability.lastAffectedVersion);
|
|
295
|
-
if (!lastAffected)
|
|
296
|
-
return false;
|
|
297
|
-
switch (delta) {
|
|
298
|
-
case 'patch':
|
|
299
|
-
return current.major === lastAffected.major &&
|
|
300
|
-
current.minor === lastAffected.minor;
|
|
301
|
-
case 'minor':
|
|
302
|
-
return current.major === lastAffected.major;
|
|
303
|
-
case 'major':
|
|
304
|
-
return true;
|
|
305
|
-
case 'none':
|
|
306
|
-
return false;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
return false;
|
|
310
|
-
}
|
|
311
|
-
catch (_a) {
|
|
312
|
-
return false;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
getUpgradeVersion(vulnerability) {
|
|
316
|
-
if (vulnerability.fixedVersion) {
|
|
317
|
-
return vulnerability.fixedVersion;
|
|
318
|
-
}
|
|
319
|
-
return undefined;
|
|
320
|
-
}
|
|
321
|
-
getVersionPrefixForDelta() {
|
|
322
|
-
switch (this.maximumUpgradeDelta) {
|
|
323
|
-
case 'patch':
|
|
324
|
-
return '~';
|
|
325
|
-
case 'minor':
|
|
326
|
-
case 'major':
|
|
327
|
-
return '^';
|
|
328
|
-
default:
|
|
329
|
-
return '';
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
233
|
renderPath(scope, path) {
|
|
333
234
|
const parts = [];
|
|
334
235
|
if (scope) {
|
|
@@ -339,6 +240,39 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
339
240
|
}
|
|
340
241
|
return parts.join(' > ');
|
|
341
242
|
}
|
|
243
|
+
findAllDirectDepsForTransitive(marker, transitivePackageName, scopesToCheck) {
|
|
244
|
+
const results = [];
|
|
245
|
+
for (const scope of scopesToCheck) {
|
|
246
|
+
const deps = marker[scope] || [];
|
|
247
|
+
for (const dep of deps) {
|
|
248
|
+
if (dep.resolved && this.hasTransitiveInTree(dep.resolved, transitivePackageName, new Set())) {
|
|
249
|
+
results.push({
|
|
250
|
+
name: dep.resolved.name,
|
|
251
|
+
version: dep.resolved.version,
|
|
252
|
+
scope
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return results;
|
|
258
|
+
}
|
|
259
|
+
hasTransitiveInTree(resolved, targetPackageName, visited) {
|
|
260
|
+
const key = `${resolved.name}@${resolved.version}`;
|
|
261
|
+
if (visited.has(key))
|
|
262
|
+
return false;
|
|
263
|
+
visited.add(key);
|
|
264
|
+
if (resolved.dependencies) {
|
|
265
|
+
for (const child of resolved.dependencies) {
|
|
266
|
+
if (child.name === targetPackageName) {
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
if (child.resolved && this.hasTransitiveInTree(child.resolved, targetPackageName, visited)) {
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
342
276
|
findVulnerabilities(resolved, db, depth, isDirect, scope, path, visited, results) {
|
|
343
277
|
const key = `${resolved.name}@${resolved.version}`;
|
|
344
278
|
if (visited.has(key))
|
|
@@ -353,7 +287,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
353
287
|
if (!this.matchesCvePattern(vuln)) {
|
|
354
288
|
continue;
|
|
355
289
|
}
|
|
356
|
-
if (
|
|
290
|
+
if ((0, version_utils_1.isVersionAffected)(resolved.version, vuln)) {
|
|
357
291
|
results.push({
|
|
358
292
|
resolved,
|
|
359
293
|
vulnerability: vuln,
|
|
@@ -385,7 +319,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
385
319
|
for (const dep of deps) {
|
|
386
320
|
if (!dep.resolved)
|
|
387
321
|
continue;
|
|
388
|
-
const declaredMinVersion =
|
|
322
|
+
const declaredMinVersion = (0, version_utils_1.extractMinimumVersion)(dep.versionConstraint);
|
|
389
323
|
if (!declaredMinVersion)
|
|
390
324
|
continue;
|
|
391
325
|
if (declaredMinVersion === dep.resolved.version)
|
|
@@ -401,8 +335,8 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
401
335
|
if (!this.matchesCvePattern(vuln)) {
|
|
402
336
|
continue;
|
|
403
337
|
}
|
|
404
|
-
if (
|
|
405
|
-
!
|
|
338
|
+
if ((0, version_utils_1.isVersionAffected)(declaredMinVersion, vuln) &&
|
|
339
|
+
!(0, version_utils_1.isVersionAffected)(dep.resolved.version, vuln)) {
|
|
406
340
|
affectedCves.push(vuln.cve);
|
|
407
341
|
affectedCveSummaries.set(vuln.cve, vuln.summary);
|
|
408
342
|
const fixVersion = vuln.fixedVersion;
|
|
@@ -433,20 +367,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
433
367
|
if (this.isReportOnly()) {
|
|
434
368
|
return false;
|
|
435
369
|
}
|
|
436
|
-
return
|
|
437
|
-
}
|
|
438
|
-
extractMinimumVersion(constraint) {
|
|
439
|
-
if (!constraint)
|
|
440
|
-
return undefined;
|
|
441
|
-
if (semver.valid(constraint)) {
|
|
442
|
-
return constraint;
|
|
443
|
-
}
|
|
444
|
-
const match = constraint.match(/^[~^>=<]*\s*(\d+\.\d+\.\d+(?:-[a-zA-Z0-9.]+)?)/);
|
|
445
|
-
if (match && semver.valid(match[1])) {
|
|
446
|
-
return match[1];
|
|
447
|
-
}
|
|
448
|
-
const coerced = semver.coerce(constraint);
|
|
449
|
-
return coerced === null || coerced === void 0 ? void 0 : coerced.version;
|
|
370
|
+
return (0, version_utils_1.isVersionWithinDelta)(fromVersion, toVersion, this.maximumUpgradeDelta);
|
|
450
371
|
}
|
|
451
372
|
findHighestSafeVersion(packageName, originalVersion, initialFixVersion, db, visited = new Set()) {
|
|
452
373
|
if (visited.has(initialFixVersion)) {
|
|
@@ -454,15 +375,15 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
454
375
|
}
|
|
455
376
|
visited.add(initialFixVersion);
|
|
456
377
|
const vulnsInFixVersion = db.getVulnerabilities(packageName)
|
|
457
|
-
.filter(v =>
|
|
378
|
+
.filter(v => (0, version_utils_1.isVersionAffected)(initialFixVersion, v));
|
|
458
379
|
if (vulnsInFixVersion.length === 0) {
|
|
459
380
|
return initialFixVersion;
|
|
460
381
|
}
|
|
461
382
|
let highestFixVersion = initialFixVersion;
|
|
462
383
|
for (const vuln of vulnsInFixVersion) {
|
|
463
|
-
const fixVersion =
|
|
384
|
+
const fixVersion = (0, version_utils_1.getUpgradeVersion)(vuln);
|
|
464
385
|
if (fixVersion && semver.valid(fixVersion)) {
|
|
465
|
-
if (
|
|
386
|
+
if ((0, version_utils_1.isVersionWithinDelta)(originalVersion, fixVersion, this.maximumUpgradeDelta)) {
|
|
466
387
|
if (semver.gt(fixVersion, highestFixVersion)) {
|
|
467
388
|
highestFixVersion = fixVersion;
|
|
468
389
|
}
|
|
@@ -474,29 +395,6 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
474
395
|
}
|
|
475
396
|
return initialFixVersion;
|
|
476
397
|
}
|
|
477
|
-
isVersionWithinDelta(originalVersion, targetVersion) {
|
|
478
|
-
try {
|
|
479
|
-
const original = semver.parse(originalVersion);
|
|
480
|
-
const target = semver.parse(targetVersion);
|
|
481
|
-
if (!original || !target)
|
|
482
|
-
return false;
|
|
483
|
-
switch (this.maximumUpgradeDelta) {
|
|
484
|
-
case 'patch':
|
|
485
|
-
return original.major === target.major && original.minor === target.minor;
|
|
486
|
-
case 'minor':
|
|
487
|
-
return original.major === target.major;
|
|
488
|
-
case 'major':
|
|
489
|
-
return true;
|
|
490
|
-
case 'none':
|
|
491
|
-
return false;
|
|
492
|
-
default:
|
|
493
|
-
return false;
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
catch (_a) {
|
|
497
|
-
return false;
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
398
|
computeFixes(vulnerabilities, db, projectContext) {
|
|
501
399
|
return __awaiter(this, void 0, void 0, function* () {
|
|
502
400
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
@@ -531,23 +429,27 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
531
429
|
let isTransitive = true;
|
|
532
430
|
let scope;
|
|
533
431
|
let originalVersion;
|
|
534
|
-
|
|
432
|
+
const directDepInfosMap = new Map();
|
|
535
433
|
for (const vuln of vulns) {
|
|
536
434
|
if (!originalVersion) {
|
|
537
435
|
originalVersion = vuln.resolved.version;
|
|
538
436
|
}
|
|
539
|
-
if (!vuln.isDirect && vuln.path.length > 0
|
|
437
|
+
if (!vuln.isDirect && vuln.path.length > 0) {
|
|
540
438
|
const directDep = vuln.path[0];
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
439
|
+
const depScope = vuln.scope || 'dependencies';
|
|
440
|
+
const key = `${directDep.name}@${depScope}`;
|
|
441
|
+
if (!directDepInfosMap.has(key)) {
|
|
442
|
+
directDepInfosMap.set(key, {
|
|
443
|
+
name: directDep.name,
|
|
444
|
+
version: directDep.version,
|
|
445
|
+
scope: depScope
|
|
446
|
+
});
|
|
447
|
+
}
|
|
546
448
|
}
|
|
547
|
-
if (
|
|
449
|
+
if (this.isReportOnly() || !(0, version_utils_1.isUpgradeableWithinDelta)(vuln.resolved.version, vuln.vulnerability, this.maximumUpgradeDelta)) {
|
|
548
450
|
continue;
|
|
549
451
|
}
|
|
550
|
-
const fixVersion =
|
|
452
|
+
const fixVersion = (0, version_utils_1.getUpgradeVersion)(vuln.vulnerability);
|
|
551
453
|
if (fixVersion) {
|
|
552
454
|
const fixMajor = (_g = semver.parse(fixVersion)) === null || _g === void 0 ? void 0 : _g.major;
|
|
553
455
|
const shouldConsiderFix = hasMultipleMajorVersions
|
|
@@ -566,8 +468,18 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
566
468
|
scope = vuln.scope;
|
|
567
469
|
}
|
|
568
470
|
}
|
|
471
|
+
if (isTransitive && (projectContext === null || projectContext === void 0 ? void 0 : projectContext.marker) && (projectContext === null || projectContext === void 0 ? void 0 : projectContext.scopesToCheck)) {
|
|
472
|
+
const allDirectDeps = this.findAllDirectDepsForTransitive(projectContext.marker, packageName, projectContext.scopesToCheck);
|
|
473
|
+
for (const dep of allDirectDeps) {
|
|
474
|
+
const key = `${dep.name}@${dep.scope}`;
|
|
475
|
+
if (!directDepInfosMap.has(key)) {
|
|
476
|
+
directDepInfosMap.set(key, dep);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
569
480
|
if (highestFixVersion && cves.length > 0 && originalVersion) {
|
|
570
481
|
const safeVersion = this.findHighestSafeVersion(packageName, originalVersion, highestFixVersion, db);
|
|
482
|
+
const directDepInfosArray = Array.from(directDepInfosMap.values());
|
|
571
483
|
const fix = {
|
|
572
484
|
packageName,
|
|
573
485
|
newVersion: safeVersion || highestFixVersion,
|
|
@@ -576,11 +488,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
576
488
|
cveSummaries,
|
|
577
489
|
scope,
|
|
578
490
|
originalMajorVersion: originalMajor,
|
|
579
|
-
|
|
580
|
-
name: directDepInfo.name,
|
|
581
|
-
version: directDepInfo.version,
|
|
582
|
-
scope: directDepInfo.scope
|
|
583
|
-
} : undefined
|
|
491
|
+
directDepInfos: isTransitive && directDepInfosArray.length > 0 ? directDepInfosArray : undefined
|
|
584
492
|
};
|
|
585
493
|
fixes.push(fix);
|
|
586
494
|
}
|
|
@@ -588,47 +496,50 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
588
496
|
return fixes;
|
|
589
497
|
});
|
|
590
498
|
}
|
|
591
|
-
|
|
592
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
593
|
-
const isVulnerable = (version) => {
|
|
594
|
-
try {
|
|
595
|
-
return semver.lt(version, requiredFixVersion);
|
|
596
|
-
}
|
|
597
|
-
catch (_a) {
|
|
598
|
-
return true;
|
|
599
|
-
}
|
|
600
|
-
};
|
|
601
|
-
const isWithinDelta = (from, to) => {
|
|
602
|
-
return this.isVersionWithinDelta(from, to);
|
|
603
|
-
};
|
|
604
|
-
try {
|
|
605
|
-
const upgradeVersion = yield (0, npm_utils_1.findDirectUpgradeThatFixesTransitive)(projectContext.packageManager, directDepInfo.name, directDepInfo.version, transitivePackageName, isVulnerable, isWithinDelta, projectContext.originalPackageJson, directDepInfo.scope, projectContext.configFiles);
|
|
606
|
-
return upgradeVersion;
|
|
607
|
-
}
|
|
608
|
-
catch (_a) {
|
|
609
|
-
return undefined;
|
|
610
|
-
}
|
|
611
|
-
});
|
|
612
|
-
}
|
|
613
|
-
tryDirectUpgradesForTransitives(fixes, updateInfo, db) {
|
|
499
|
+
tryDirectUpgradesForTransitives(fixes, updateInfo) {
|
|
614
500
|
return __awaiter(this, void 0, void 0, function* () {
|
|
615
501
|
const result = [];
|
|
616
502
|
for (const fix of fixes) {
|
|
617
|
-
if (!fix.
|
|
503
|
+
if (!fix.directDepInfos || fix.directDepInfos.length === 0) {
|
|
618
504
|
result.push(fix);
|
|
619
505
|
continue;
|
|
620
506
|
}
|
|
621
|
-
const
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
507
|
+
const candidateUpgrades = [];
|
|
508
|
+
const isVulnerable = (version) => {
|
|
509
|
+
try {
|
|
510
|
+
return semver.lt(version, fix.newVersion);
|
|
511
|
+
}
|
|
512
|
+
catch (_a) {
|
|
513
|
+
return true;
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
const isWithinDelta = (from, to) => {
|
|
517
|
+
return (0, version_utils_1.isVersionWithinDelta)(from, to, this.maximumUpgradeDelta);
|
|
518
|
+
};
|
|
519
|
+
for (const directDepInfo of fix.directDepInfos) {
|
|
520
|
+
const directUpgradeVersion = yield (0, npm_utils_1.findDirectUpgradeWithSafeTransitiveInIsolation)(updateInfo.packageManager, directDepInfo.name, directDepInfo.version, fix.packageName, isVulnerable, isWithinDelta, directDepInfo.scope, updateInfo.configFiles);
|
|
521
|
+
if (directUpgradeVersion) {
|
|
522
|
+
candidateUpgrades.push({
|
|
523
|
+
directDepName: directDepInfo.name,
|
|
629
524
|
directDepVersion: directUpgradeVersion,
|
|
630
|
-
directDepScope:
|
|
631
|
-
}
|
|
525
|
+
directDepScope: directDepInfo.scope
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
if (candidateUpgrades.length > 0) {
|
|
530
|
+
const foundAllUpgrades = candidateUpgrades.length === fix.directDepInfos.length;
|
|
531
|
+
if (foundAllUpgrades) {
|
|
532
|
+
const allFixed = yield (0, npm_utils_1.verifyAllUpgradesFixTransitive)(updateInfo.packageManager, candidateUpgrades.map(u => ({
|
|
533
|
+
name: u.directDepName,
|
|
534
|
+
version: u.directDepVersion,
|
|
535
|
+
scope: u.directDepScope
|
|
536
|
+
})), fix.packageName, isVulnerable, updateInfo.originalPackageJson, updateInfo.configFiles);
|
|
537
|
+
if (allFixed) {
|
|
538
|
+
result.push(Object.assign(Object.assign({}, fix), { fixViaDirectUpgrades: candidateUpgrades }));
|
|
539
|
+
continue;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
result.push(Object.assign(Object.assign({}, fix), { fixViaDirectUpgrades: candidateUpgrades }));
|
|
632
543
|
}
|
|
633
544
|
else {
|
|
634
545
|
result.push(fix);
|
|
@@ -680,7 +591,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
680
591
|
const visited = new Set();
|
|
681
592
|
const scopesToCheck = recipe.scope
|
|
682
593
|
? [recipe.scope]
|
|
683
|
-
: ALL_DEPENDENCY_SCOPES;
|
|
594
|
+
: types_1.ALL_DEPENDENCY_SCOPES;
|
|
684
595
|
for (const scope of scopesToCheck) {
|
|
685
596
|
const deps = marker[scope] || [];
|
|
686
597
|
for (const dep of deps) {
|
|
@@ -713,7 +624,9 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
713
624
|
fixes = yield recipe.computeFixes(vulnerabilities, acc.db, {
|
|
714
625
|
packageManager: pm,
|
|
715
626
|
originalPackageJson,
|
|
716
|
-
configFiles: Object.keys(configFiles).length > 0 ? configFiles : undefined
|
|
627
|
+
configFiles: Object.keys(configFiles).length > 0 ? configFiles : undefined,
|
|
628
|
+
marker,
|
|
629
|
+
scopesToCheck
|
|
717
630
|
});
|
|
718
631
|
}
|
|
719
632
|
if (recipe.fixDeclaredVersions) {
|
|
@@ -844,7 +757,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
844
757
|
const vulnerabilities = acc.vulnerableByProject.get(doc.sourcePath);
|
|
845
758
|
if (vulnerabilities && vulnerabilities.length > 0) {
|
|
846
759
|
for (const vuln of vulnerabilities) {
|
|
847
|
-
const upgradeable = recipe.isUpgradeableWithinDelta(vuln.resolved.version, vuln.vulnerability);
|
|
760
|
+
const upgradeable = !recipe.isReportOnly() && (0, version_utils_1.isUpgradeableWithinDelta)(vuln.resolved.version, vuln.vulnerability, recipe.maximumUpgradeDelta);
|
|
848
761
|
recipe.vulnerabilityReport.insertRow(ctx, new VulnerabilityReportRow(doc.sourcePath, vuln.vulnerability.cve, vuln.resolved.name, vuln.resolved.version, vuln.vulnerability.fixedVersion || '', vuln.vulnerability.lastAffectedVersion || '', upgradeable, vuln.vulnerability.summary, vuln.vulnerability.severity, vuln.depth, vuln.vulnerability.cwes, vuln.isDirect, recipe.renderPath(vuln.scope, vuln.path)));
|
|
849
762
|
}
|
|
850
763
|
}
|
|
@@ -1011,8 +924,8 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
1011
924
|
}
|
|
1012
925
|
runPackageManagerInstall(acc, updateInfo, fixes) {
|
|
1013
926
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1014
|
-
const directFixes = fixes.filter(f => !f.isTransitive || f.
|
|
1015
|
-
const transitiveFixes = fixes.filter(f => f.isTransitive && !f.
|
|
927
|
+
const directFixes = fixes.filter(f => !f.isTransitive || (f.fixViaDirectUpgrades && f.fixViaDirectUpgrades.length > 0));
|
|
928
|
+
const transitiveFixes = fixes.filter(f => f.isTransitive && (!f.fixViaDirectUpgrades || f.fixViaDirectUpgrades.length === 0));
|
|
1016
929
|
if (this.shouldVerifyTransitiveFixes() && transitiveFixes.length > 0) {
|
|
1017
930
|
const phase1PackageJson = this.createModifiedPackageJson(updateInfo.originalPackageJson, directFixes, updateInfo.packageManager);
|
|
1018
931
|
const phase1Result = yield (0, javascript_1.runInstallInTempDir)(updateInfo.packageManager, phase1PackageJson, {
|
|
@@ -1032,7 +945,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
1032
945
|
return;
|
|
1033
946
|
}
|
|
1034
947
|
if (this.transitiveFixStrategy === 'prefer-direct-upgrade') {
|
|
1035
|
-
remainingTransitiveFixes = yield this.tryDirectUpgradesForTransitives(remainingTransitiveFixes, updateInfo
|
|
948
|
+
remainingTransitiveFixes = yield this.tryDirectUpgradesForTransitives(remainingTransitiveFixes, updateInfo);
|
|
1036
949
|
}
|
|
1037
950
|
const finalFixes = [...directFixes, ...remainingTransitiveFixes];
|
|
1038
951
|
const finalPackageJson = this.createModifiedPackageJson(updateInfo.originalPackageJson, finalFixes, updateInfo.packageManager);
|
|
@@ -1053,21 +966,18 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
1053
966
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1054
967
|
const memberPaths = acc.workspaceRoots.get(rootPath) || [];
|
|
1055
968
|
const pm = rootUpdateInfo.packageManager;
|
|
1056
|
-
const allDirectFixes = [];
|
|
1057
969
|
const allTransitiveFixes = [];
|
|
1058
970
|
const rootFixes = acc.fixesByProject.get(rootPath) || [];
|
|
1059
|
-
const rootDirectFixes = rootFixes.filter(f => !f.isTransitive || f.
|
|
1060
|
-
const rootTransitiveFixes = rootFixes.filter(f => f.isTransitive && !f.
|
|
1061
|
-
allDirectFixes.push(...rootDirectFixes);
|
|
971
|
+
const rootDirectFixes = rootFixes.filter(f => !f.isTransitive || (f.fixViaDirectUpgrades && f.fixViaDirectUpgrades.length > 0));
|
|
972
|
+
const rootTransitiveFixes = rootFixes.filter(f => f.isTransitive && (!f.fixViaDirectUpgrades || f.fixViaDirectUpgrades.length === 0));
|
|
1062
973
|
allTransitiveFixes.push(...rootTransitiveFixes);
|
|
1063
974
|
const memberDirectFixes = new Map();
|
|
1064
975
|
for (const memberPath of memberPaths) {
|
|
1065
976
|
const memberFixes = acc.fixesByProject.get(memberPath) || [];
|
|
1066
|
-
const directFixes = memberFixes.filter(f => !f.isTransitive || f.
|
|
1067
|
-
const transitiveFixes = memberFixes.filter(f => f.isTransitive && !f.
|
|
977
|
+
const directFixes = memberFixes.filter(f => !f.isTransitive || (f.fixViaDirectUpgrades && f.fixViaDirectUpgrades.length > 0));
|
|
978
|
+
const transitiveFixes = memberFixes.filter(f => f.isTransitive && (!f.fixViaDirectUpgrades || f.fixViaDirectUpgrades.length === 0));
|
|
1068
979
|
if (directFixes.length > 0) {
|
|
1069
980
|
memberDirectFixes.set(memberPath, directFixes);
|
|
1070
|
-
allDirectFixes.push(...directFixes);
|
|
1071
981
|
}
|
|
1072
982
|
allTransitiveFixes.push(...transitiveFixes);
|
|
1073
983
|
}
|
|
@@ -1110,7 +1020,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
1110
1020
|
return;
|
|
1111
1021
|
}
|
|
1112
1022
|
if (this.transitiveFixStrategy === 'prefer-direct-upgrade') {
|
|
1113
|
-
remainingTransitiveFixes = yield this.tryDirectUpgradesForTransitives(remainingTransitiveFixes, rootUpdateInfo
|
|
1023
|
+
remainingTransitiveFixes = yield this.tryDirectUpgradesForTransitives(remainingTransitiveFixes, rootUpdateInfo);
|
|
1114
1024
|
}
|
|
1115
1025
|
const finalRootPackageJson = this.createModifiedPackageJson(rootOriginalContent, [...rootDirectFixes, ...remainingTransitiveFixes], pm);
|
|
1116
1026
|
const finalResult = yield (0, javascript_1.runWorkspaceInstallInTempDir)(pm, finalRootPackageJson, {
|
|
@@ -1134,7 +1044,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
1134
1044
|
if (!fix.isTransitive && fix.scope) {
|
|
1135
1045
|
if (packageJson[fix.scope] && packageJson[fix.scope][fix.packageName]) {
|
|
1136
1046
|
const originalVersion = packageJson[fix.scope][fix.packageName];
|
|
1137
|
-
packageJson[fix.scope][fix.packageName] = applyVersionPrefix(originalVersion, fix.newVersion);
|
|
1047
|
+
packageJson[fix.scope][fix.packageName] = (0, version_utils_1.applyVersionPrefix)(originalVersion, fix.newVersion);
|
|
1138
1048
|
}
|
|
1139
1049
|
}
|
|
1140
1050
|
}
|
|
@@ -1154,19 +1064,21 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
1154
1064
|
if (!fix.isTransitive && fix.scope) {
|
|
1155
1065
|
if (packageJson[fix.scope] && packageJson[fix.scope][fix.packageName]) {
|
|
1156
1066
|
const originalVersion = packageJson[fix.scope][fix.packageName];
|
|
1157
|
-
packageJson[fix.scope][fix.packageName] = applyVersionPrefix(originalVersion, fix.newVersion);
|
|
1067
|
+
packageJson[fix.scope][fix.packageName] = (0, version_utils_1.applyVersionPrefix)(originalVersion, fix.newVersion);
|
|
1158
1068
|
}
|
|
1159
1069
|
}
|
|
1160
1070
|
else if (fix.isTransitive) {
|
|
1161
|
-
if (fix.
|
|
1162
|
-
const
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1071
|
+
if (fix.fixViaDirectUpgrades && fix.fixViaDirectUpgrades.length > 0) {
|
|
1072
|
+
for (const upgrade of fix.fixViaDirectUpgrades) {
|
|
1073
|
+
const { directDepName, directDepVersion, directDepScope } = upgrade;
|
|
1074
|
+
if ((_a = packageJson[directDepScope]) === null || _a === void 0 ? void 0 : _a[directDepName]) {
|
|
1075
|
+
const originalVersion = packageJson[directDepScope][directDepName];
|
|
1076
|
+
packageJson[directDepScope][directDepName] = (0, version_utils_1.applyVersionPrefix)(originalVersion, directDepVersion);
|
|
1077
|
+
}
|
|
1167
1078
|
}
|
|
1079
|
+
continue;
|
|
1168
1080
|
}
|
|
1169
|
-
const directDepScope = findDirectDependencyScope(packageJson, fix.packageName);
|
|
1081
|
+
const directDepScope = (0, override_utils_1.findDirectDependencyScope)(packageJson, fix.packageName);
|
|
1170
1082
|
if (directDepScope) {
|
|
1171
1083
|
const directVersion = packageJson[directDepScope][fix.packageName];
|
|
1172
1084
|
const directMajor = semver.major(semver.coerce(directVersion) || '0.0.0');
|
|
@@ -1182,13 +1094,13 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
1182
1094
|
}
|
|
1183
1095
|
continue;
|
|
1184
1096
|
}
|
|
1185
|
-
packageJson[directDepScope][fix.packageName] = applyVersionPrefix(directVersion, fix.newVersion);
|
|
1097
|
+
packageJson[directDepScope][fix.packageName] = (0, version_utils_1.applyVersionPrefix)(directVersion, fix.newVersion);
|
|
1186
1098
|
continue;
|
|
1187
1099
|
}
|
|
1188
1100
|
const packageFixes = fixesByPackage.get(fix.packageName) || [];
|
|
1189
1101
|
const hasMultipleMajorVersions = packageFixes.length > 1 &&
|
|
1190
1102
|
new Set(packageFixes.map(f => f.originalMajorVersion)).size > 1;
|
|
1191
|
-
const existingOverrides = getOverridesFromPackageJson(packageJson, packageManager);
|
|
1103
|
+
const existingOverrides = (0, override_utils_1.getOverridesFromPackageJson)(packageJson, packageManager);
|
|
1192
1104
|
const hasExistingVersionSpecificOverrides = existingOverrides &&
|
|
1193
1105
|
Object.keys(existingOverrides).some(key => key.startsWith(`${fix.packageName}@`));
|
|
1194
1106
|
const isYarn = packageManager === "YarnClassic" ||
|
|
@@ -1338,42 +1250,4 @@ __decorate([
|
|
|
1338
1250
|
example: "true"
|
|
1339
1251
|
})
|
|
1340
1252
|
], DependencyVulnerabilityCheck.prototype, "addOverrideComments", void 0);
|
|
1341
|
-
function extractVersionPrefix(versionString) {
|
|
1342
|
-
const match = versionString.match(/^([~^]|>=?|<=?|=)?(.*)$/);
|
|
1343
|
-
if (match) {
|
|
1344
|
-
return {
|
|
1345
|
-
prefix: match[1] || '',
|
|
1346
|
-
version: match[2]
|
|
1347
|
-
};
|
|
1348
|
-
}
|
|
1349
|
-
return { prefix: '', version: versionString };
|
|
1350
|
-
}
|
|
1351
|
-
function applyVersionPrefix(originalVersion, newVersion) {
|
|
1352
|
-
const { prefix } = extractVersionPrefix(originalVersion);
|
|
1353
|
-
return prefix + newVersion;
|
|
1354
|
-
}
|
|
1355
|
-
function findDirectDependencyScope(packageJson, packageName) {
|
|
1356
|
-
var _a;
|
|
1357
|
-
for (const scope of ALL_DEPENDENCY_SCOPES) {
|
|
1358
|
-
if ((_a = packageJson[scope]) === null || _a === void 0 ? void 0 : _a[packageName]) {
|
|
1359
|
-
return scope;
|
|
1360
|
-
}
|
|
1361
|
-
}
|
|
1362
|
-
return undefined;
|
|
1363
|
-
}
|
|
1364
|
-
function getOverridesFromPackageJson(packageJson, packageManager) {
|
|
1365
|
-
var _a;
|
|
1366
|
-
switch (packageManager) {
|
|
1367
|
-
case "Npm":
|
|
1368
|
-
case "Bun":
|
|
1369
|
-
return packageJson.overrides;
|
|
1370
|
-
case "Pnpm":
|
|
1371
|
-
return (_a = packageJson.pnpm) === null || _a === void 0 ? void 0 : _a.overrides;
|
|
1372
|
-
case "YarnClassic":
|
|
1373
|
-
case "YarnBerry":
|
|
1374
|
-
return packageJson.resolutions;
|
|
1375
|
-
default:
|
|
1376
|
-
return undefined;
|
|
1377
|
-
}
|
|
1378
|
-
}
|
|
1379
1253
|
//# sourceMappingURL=dependency-vulnerability-check.js.map
|