dependabot-npm_and_yarn 0.326.1 → 0.328.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.
- checksums.yaml +4 -4
- data/helpers/lib/npm/vulnerability-auditor.js +29 -2
- data/helpers/test/npm/fixtures/vulnerability-auditor/simple/package-lock.json +39 -0
- data/helpers/test/npm/fixtures/vulnerability-auditor/simple/package.json +12 -0
- data/helpers/test/npm/fixtures/vulnerability-auditor/update-needed-across-two-versions/package-lock.json +92 -0
- data/helpers/test/npm/fixtures/vulnerability-auditor/update-needed-across-two-versions/package.json +13 -0
- data/helpers/test/npm/helpers.js +21 -0
- data/helpers/test/npm/vulnerability-auditor.test.js +85 -0
- data/lib/dependabot/npm_and_yarn/file_parser/json_lock.rb +36 -2
- data/lib/dependabot/npm_and_yarn/file_parser.rb +4 -1
- data/lib/dependabot/npm_and_yarn/helpers.rb +16 -6
- data/lib/dependabot/npm_and_yarn/package/registry_finder.rb +1 -1
- data/lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb +15 -1
- data/lib/dependabot/npm_and_yarn/update_checker.rb +7 -1
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e519785e577c328749802bf44c2ef0066c8e4f7823d3c21c36855149986f6ddb
|
4
|
+
data.tar.gz: b33e8268583d2aef788f944a93cc5a824b6bf0b2fa3b06d1250ed852d9d063e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7fd574e8ac36593a84220d970a243f7d03c91ea6c24ffd14211bcbd1781692dc90ae0e5be4e6677ab1460a875927afa883e7143bf41c528dfcf1df6f8717623a
|
7
|
+
data.tar.gz: f160c66603ce809739ad481214c290b58d704861d5bd037177f00bb331f660b6e4c1119d25f1792951ff9da828d39e4eafb3f05e1cc7ea85e30e78fe8fff3d9a
|
@@ -73,7 +73,8 @@ async function findVulnerableDependencies(directory, advisories) {
|
|
73
73
|
return response
|
74
74
|
}
|
75
75
|
const vuln = auditReport.get(name)
|
76
|
-
const
|
76
|
+
const vulnNodesHighestLevelFirst = [...vuln.nodes].sort((a, b) => a.depth - b.depth);
|
77
|
+
const version = vulnNodesHighestLevelFirst[0].version
|
77
78
|
const fixAvailable = vuln.fixAvailable
|
78
79
|
|
79
80
|
response.current_version = version
|
@@ -113,6 +114,7 @@ async function findVulnerableDependencies(directory, advisories) {
|
|
113
114
|
|
114
115
|
response.fix_updates.push({
|
115
116
|
dependency_name: fixUpdateNode.name,
|
117
|
+
dependency_location: fixUpdateNode.location,
|
116
118
|
current_version: fixUpdateNode.version,
|
117
119
|
top_level_ancestors: fixUpdateNodeTopLevelAncestors,
|
118
120
|
})
|
@@ -128,7 +130,8 @@ async function findVulnerableDependencies(directory, advisories) {
|
|
128
130
|
|
129
131
|
for (const update of response.fix_updates) {
|
130
132
|
update.target_version =
|
131
|
-
fixTree
|
133
|
+
lookupChildLocation(fixTree, update.dependency_location)?.version
|
134
|
+
delete update.dependency_location // Not needed in the output.
|
132
135
|
}
|
133
136
|
|
134
137
|
return response
|
@@ -217,6 +220,30 @@ function groupBy(elems, fn) {
|
|
217
220
|
return groups
|
218
221
|
}
|
219
222
|
|
223
|
+
/**
|
224
|
+
* Look up the child node at the given location in the tree rooted at `root`.
|
225
|
+
* `root` is an ArboristNode, and `location` is a string containing the normalized
|
226
|
+
* path to the child node, relative to the root. This string can be taken from
|
227
|
+
* ArboristNode.location and will be of the form "node_modules/foo/node_modules/bar".
|
228
|
+
*/
|
229
|
+
function lookupChildLocation(root, location) {
|
230
|
+
if (!location.startsWith('node_modules/')) {
|
231
|
+
// The location must start with 'node_modules/' to be valid.
|
232
|
+
return null;
|
233
|
+
}
|
234
|
+
const parts = location
|
235
|
+
.substring('node_modules/'.length)
|
236
|
+
.split('/node_modules/')
|
237
|
+
let current = root
|
238
|
+
for (const part of parts) {
|
239
|
+
current = current.children.get(part)
|
240
|
+
if (!current) {
|
241
|
+
return null
|
242
|
+
}
|
243
|
+
}
|
244
|
+
return current
|
245
|
+
}
|
246
|
+
|
220
247
|
async function loadNpmConfig() {
|
221
248
|
const configOutput = await exec('npm config ls --json')
|
222
249
|
return JSON.parse(configOutput.stdout)
|
@@ -0,0 +1,39 @@
|
|
1
|
+
{
|
2
|
+
"name": "test-vulnerability-auditor-simple",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"lockfileVersion": 3,
|
5
|
+
"requires": true,
|
6
|
+
"packages": {
|
7
|
+
"": {
|
8
|
+
"name": "test-vulnerability-auditor-simple",
|
9
|
+
"version": "1.0.0",
|
10
|
+
"dependencies": {
|
11
|
+
"@dependabot-fixtures/npm-parent-dependency": "^2.0.0"
|
12
|
+
}
|
13
|
+
},
|
14
|
+
"node_modules/@dependabot-fixtures/npm-intermediate-dependency": {
|
15
|
+
"version": "0.0.1",
|
16
|
+
"resolved": "https://registry.npmjs.org/@dependabot-fixtures/npm-intermediate-dependency/-/npm-intermediate-dependency-0.0.1.tgz",
|
17
|
+
"integrity": "sha512-/N77Dzpfg8BIfFgpJrMk86ueUYTVhmpc4RobuHpIpKSc3GZr4Ltu4au92brnUGk66UkzgrMmtgqRXO8OrOspKQ==",
|
18
|
+
"license": "ISC",
|
19
|
+
"dependencies": {
|
20
|
+
"@dependabot-fixtures/npm-transitive-dependency": "1.0.0"
|
21
|
+
}
|
22
|
+
},
|
23
|
+
"node_modules/@dependabot-fixtures/npm-parent-dependency": {
|
24
|
+
"version": "2.0.0",
|
25
|
+
"resolved": "https://registry.npmjs.org/@dependabot-fixtures/npm-parent-dependency/-/npm-parent-dependency-2.0.0.tgz",
|
26
|
+
"integrity": "sha512-5LtLEL1yzO2TdkNX3R9cvr+nKmhw5h4xM0wkFTJeK14wxlI9d8gEYA+I2hUi+IP96ucBSztAnOgZVwoJHEZb6A==",
|
27
|
+
"license": "ISC",
|
28
|
+
"dependencies": {
|
29
|
+
"@dependabot-fixtures/npm-intermediate-dependency": "0.0.1"
|
30
|
+
}
|
31
|
+
},
|
32
|
+
"node_modules/@dependabot-fixtures/npm-transitive-dependency": {
|
33
|
+
"version": "1.0.0",
|
34
|
+
"resolved": "https://registry.npmjs.org/@dependabot-fixtures/npm-transitive-dependency/-/npm-transitive-dependency-1.0.0.tgz",
|
35
|
+
"integrity": "sha512-nFbzQH0TRgdzSA2/FH6MPnxZDpD+5Bgz00aD5Edgbc1wY/k8VC9s7lnk22dBTgJLwoY7MgbrnAf9rAvN08hHVg==",
|
36
|
+
"license": "ISC"
|
37
|
+
}
|
38
|
+
}
|
39
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
{
|
2
|
+
"name": "test-vulnerability-auditor-simple",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"private": true,
|
5
|
+
"description": "",
|
6
|
+
"scripts": {
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
8
|
+
},
|
9
|
+
"dependencies": {
|
10
|
+
"@dependabot-fixtures/npm-parent-dependency": "^2.0.0"
|
11
|
+
}
|
12
|
+
}
|
@@ -0,0 +1,92 @@
|
|
1
|
+
{
|
2
|
+
"name": "test-vulnerability-update-needed-across-two-versions",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"lockfileVersion": 3,
|
5
|
+
"requires": true,
|
6
|
+
"packages": {
|
7
|
+
"": {
|
8
|
+
"name": "test-vulnerability-update-needed-across-two-versions",
|
9
|
+
"version": "1.0.0",
|
10
|
+
"dependencies": {
|
11
|
+
"@msgpack/msgpack": "^2.7.2",
|
12
|
+
"wireql-client": "^1.0.3"
|
13
|
+
}
|
14
|
+
},
|
15
|
+
"node_modules/@msgpack/msgpack": {
|
16
|
+
"version": "2.7.2",
|
17
|
+
"resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-2.7.2.tgz",
|
18
|
+
"integrity": "sha512-rYEi46+gIzufyYUAoHDnRzkWGxajpD9vVXFQ3g1vbjrBm6P7MBmm+s/fqPa46sxa+8FOUdEuRQKaugo5a4JWpw==",
|
19
|
+
"license": "ISC",
|
20
|
+
"engines": {
|
21
|
+
"node": ">= 10"
|
22
|
+
}
|
23
|
+
},
|
24
|
+
"node_modules/eventemitter3": {
|
25
|
+
"version": "5.0.1",
|
26
|
+
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
|
27
|
+
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
|
28
|
+
"license": "MIT"
|
29
|
+
},
|
30
|
+
"node_modules/typescript": {
|
31
|
+
"version": "5.9.2",
|
32
|
+
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
|
33
|
+
"integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
|
34
|
+
"license": "Apache-2.0",
|
35
|
+
"peer": true,
|
36
|
+
"bin": {
|
37
|
+
"tsc": "bin/tsc",
|
38
|
+
"tsserver": "bin/tsserver"
|
39
|
+
},
|
40
|
+
"engines": {
|
41
|
+
"node": ">=14.17"
|
42
|
+
}
|
43
|
+
},
|
44
|
+
"node_modules/wireql-client": {
|
45
|
+
"version": "1.0.3",
|
46
|
+
"resolved": "https://registry.npmjs.org/wireql-client/-/wireql-client-1.0.3.tgz",
|
47
|
+
"integrity": "sha512-qHCV0s+QSPEVrg4QXFewW2gPqAunuF7QdEX3Q1mcWr7FpSue6WRendyjRyr/u2vOEKuucF052vf41/dpmgLh8A==",
|
48
|
+
"license": "MIT",
|
49
|
+
"dependencies": {
|
50
|
+
"@msgpack/msgpack": "^3.0.0",
|
51
|
+
"eventemitter3": "^5.0.1",
|
52
|
+
"ws": "^8.16.0"
|
53
|
+
},
|
54
|
+
"engines": {
|
55
|
+
"node": ">=16.0.0"
|
56
|
+
},
|
57
|
+
"peerDependencies": {
|
58
|
+
"typescript": ">=4.5.0"
|
59
|
+
}
|
60
|
+
},
|
61
|
+
"node_modules/wireql-client/node_modules/@msgpack/msgpack": {
|
62
|
+
"version": "3.0.0",
|
63
|
+
"resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-3.0.0.tgz",
|
64
|
+
"integrity": "sha512-s/OZQ1QUtSYr9tgFZh4HSFLvTR2o81r0zfQj7pClC7oFUqZaAgkQ+vADV9JBioJLK9lJoAjBEhuPhVuOIJnbhg==",
|
65
|
+
"license": "ISC",
|
66
|
+
"engines": {
|
67
|
+
"node": ">= 18"
|
68
|
+
}
|
69
|
+
},
|
70
|
+
"node_modules/ws": {
|
71
|
+
"version": "8.18.3",
|
72
|
+
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
|
73
|
+
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
|
74
|
+
"license": "MIT",
|
75
|
+
"engines": {
|
76
|
+
"node": ">=10.0.0"
|
77
|
+
},
|
78
|
+
"peerDependencies": {
|
79
|
+
"bufferutil": "^4.0.1",
|
80
|
+
"utf-8-validate": ">=5.0.2"
|
81
|
+
},
|
82
|
+
"peerDependenciesMeta": {
|
83
|
+
"bufferutil": {
|
84
|
+
"optional": true
|
85
|
+
},
|
86
|
+
"utf-8-validate": {
|
87
|
+
"optional": true
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
}
|
92
|
+
}
|
data/helpers/test/npm/fixtures/vulnerability-auditor/update-needed-across-two-versions/package.json
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
{
|
2
|
+
"name": "test-vulnerability-update-needed-across-two-versions",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"private": true,
|
5
|
+
"description": "",
|
6
|
+
"scripts": {
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
8
|
+
},
|
9
|
+
"dependencies": {
|
10
|
+
"@msgpack/msgpack": "^2.7.2",
|
11
|
+
"wireql-client": "^1.0.3"
|
12
|
+
}
|
13
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
const path = require("path");
|
2
|
+
const fs = require("fs");
|
3
|
+
|
4
|
+
module.exports = {
|
5
|
+
loadFixture: (fixturePath) =>
|
6
|
+
fs.readFileSync(path.join(__dirname, "fixtures", fixturePath)).toString(),
|
7
|
+
|
8
|
+
copyDependencies: (sourceDir, destDir) => {
|
9
|
+
const srcPackageJson = path.join(
|
10
|
+
__dirname,
|
11
|
+
`fixtures/${sourceDir}/package.json`
|
12
|
+
);
|
13
|
+
fs.copyFileSync(srcPackageJson, `${destDir}/package.json`);
|
14
|
+
|
15
|
+
const srcLockfile = path.join(
|
16
|
+
__dirname,
|
17
|
+
`fixtures/${sourceDir}/package-lock.json`
|
18
|
+
);
|
19
|
+
fs.copyFileSync(srcLockfile, `${destDir}/package-lock.json`);
|
20
|
+
},
|
21
|
+
};
|
@@ -0,0 +1,85 @@
|
|
1
|
+
const path = require("path");
|
2
|
+
const os = require("os");
|
3
|
+
const fs = require("fs");
|
4
|
+
const {
|
5
|
+
findVulnerableDependencies,
|
6
|
+
} = require("../../lib/npm/vulnerability-auditor");
|
7
|
+
const helpers = require("./helpers");
|
8
|
+
|
9
|
+
describe("findVulnerableDependencies", () => {
|
10
|
+
let tempDir;
|
11
|
+
beforeEach(() => {
|
12
|
+
tempDir = fs.mkdtempSync(os.tmpdir() + path.sep);
|
13
|
+
});
|
14
|
+
afterEach(() => fs.rm(tempDir, { recursive: true }, () => {}));
|
15
|
+
|
16
|
+
it("finds vulnerable dependencies", async () => {
|
17
|
+
helpers.copyDependencies("vulnerability-auditor/simple", tempDir);
|
18
|
+
|
19
|
+
const advisories = [{
|
20
|
+
dependency_name: "@dependabot-fixtures/npm-parent-dependency",
|
21
|
+
affected_versions: [
|
22
|
+
">= 0, < 2.0.2",
|
23
|
+
]
|
24
|
+
}];
|
25
|
+
const actual = await findVulnerableDependencies(tempDir, advisories);
|
26
|
+
const expected = {
|
27
|
+
dependency_name: "@dependabot-fixtures/npm-parent-dependency",
|
28
|
+
fix_updates: [
|
29
|
+
{
|
30
|
+
dependency_name: "@dependabot-fixtures/npm-parent-dependency",
|
31
|
+
current_version: "2.0.0",
|
32
|
+
top_level_ancestors: [],
|
33
|
+
target_version: "2.0.2"
|
34
|
+
},
|
35
|
+
],
|
36
|
+
top_level_ancestors: [
|
37
|
+
"@dependabot-fixtures/npm-parent-dependency"
|
38
|
+
],
|
39
|
+
current_version: "2.0.0",
|
40
|
+
fix_available: true,
|
41
|
+
target_version: "2.0.2"
|
42
|
+
};
|
43
|
+
expect(actual).toEqual(expected);
|
44
|
+
});
|
45
|
+
|
46
|
+
it("finds vulnerable dependencies when multiple versions of the same package are affected", async () => {
|
47
|
+
helpers.copyDependencies("vulnerability-auditor/update-needed-across-two-versions", tempDir);
|
48
|
+
|
49
|
+
const advisories = [{
|
50
|
+
dependency_name: "@msgpack/msgpack",
|
51
|
+
affected_versions: [
|
52
|
+
">= 2.0.0, < 2.8.0",
|
53
|
+
">= 3.0.0, < 3.1.2"
|
54
|
+
]
|
55
|
+
}];
|
56
|
+
const actual = await findVulnerableDependencies(tempDir, advisories);
|
57
|
+
const expected = {
|
58
|
+
dependency_name: "@msgpack/msgpack",
|
59
|
+
fix_updates: [
|
60
|
+
{
|
61
|
+
dependency_name: "@msgpack/msgpack",
|
62
|
+
current_version: "2.7.2",
|
63
|
+
top_level_ancestors: [],
|
64
|
+
target_version: "2.8.0"
|
65
|
+
},
|
66
|
+
{
|
67
|
+
dependency_name: "@msgpack/msgpack",
|
68
|
+
current_version: "3.0.0",
|
69
|
+
top_level_ancestors: [
|
70
|
+
"wireql-client"
|
71
|
+
],
|
72
|
+
target_version: "3.1.2"
|
73
|
+
}
|
74
|
+
],
|
75
|
+
top_level_ancestors: [
|
76
|
+
"@msgpack/msgpack",
|
77
|
+
"wireql-client"
|
78
|
+
],
|
79
|
+
current_version: "2.7.2",
|
80
|
+
fix_available: true,
|
81
|
+
target_version: "2.8.0"
|
82
|
+
};
|
83
|
+
expect(actual).toEqual(expected);
|
84
|
+
});
|
85
|
+
});
|
@@ -15,6 +15,9 @@ module Dependabot
|
|
15
15
|
sig { params(dependency_file: DependencyFile).void }
|
16
16
|
def initialize(dependency_file)
|
17
17
|
@dependency_file = dependency_file
|
18
|
+
# Set this file to priority 1 to indicate it should override manifests for purposes of a graph
|
19
|
+
dependency_file.priority = 1
|
20
|
+
@direct_dependencies = T.let(fetch_direct_dependencies, T::Array[String])
|
18
21
|
end
|
19
22
|
|
20
23
|
sig { returns(T::Hash[String, T.untyped]) }
|
@@ -48,6 +51,31 @@ module Dependabot
|
|
48
51
|
|
49
52
|
private
|
50
53
|
|
54
|
+
# Only V3 lockfiles contain information on the package itself, so we use `npm ls` to generate
|
55
|
+
# a graph we can pluck the direct dependency list from at parse-time for this lockfile.
|
56
|
+
sig { returns(T::Array[String]) }
|
57
|
+
def fetch_direct_dependencies
|
58
|
+
# TODO(brrygrdn): Implement a 'verbose' flag that runs this extra step?
|
59
|
+
#
|
60
|
+
# For now, don't run this extra native command if we aren't using the submission experiment
|
61
|
+
return [] unless Dependabot::Experiments.enabled?(:enable_dependency_submission_poc)
|
62
|
+
|
63
|
+
SharedHelpers.in_a_temporary_repo_directory do |_|
|
64
|
+
write_temporary_dependency_files
|
65
|
+
|
66
|
+
npm_ls_json = Helpers.run_npm_command("ls --all --package-lock-only --json")
|
67
|
+
|
68
|
+
JSON.parse(npm_ls_json).fetch("dependencies", {}).keys
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
sig { void }
|
73
|
+
def write_temporary_dependency_files
|
74
|
+
path = @dependency_file.name
|
75
|
+
FileUtils.mkdir_p(Pathname.new(path).dirname)
|
76
|
+
File.write(path, @dependency_file.content)
|
77
|
+
end
|
78
|
+
|
51
79
|
sig do
|
52
80
|
params(object_with_dependencies: T::Hash[String, T.untyped])
|
53
81
|
.returns(Dependabot::FileParsers::Base::DependencySet)
|
@@ -64,13 +92,18 @@ module Dependabot
|
|
64
92
|
version = Version.semver_for(details["version"])
|
65
93
|
next unless version
|
66
94
|
|
95
|
+
package_name = name.split("node_modules/").last
|
67
96
|
version = version.to_s
|
68
97
|
|
69
98
|
dependency_args = {
|
70
|
-
name:
|
99
|
+
name: package_name,
|
71
100
|
version: version,
|
72
101
|
package_manager: "npm_and_yarn",
|
73
|
-
requirements: []
|
102
|
+
requirements: [],
|
103
|
+
direct_relationship: @direct_dependencies.include?(package_name),
|
104
|
+
metadata: {
|
105
|
+
depends_on: details&.fetch("dependencies", {})&.keys || []
|
106
|
+
}
|
74
107
|
}
|
75
108
|
|
76
109
|
if details["bundled"]
|
@@ -87,6 +120,7 @@ module Dependabot
|
|
87
120
|
dependency_set += recursively_fetch_dependencies(details)
|
88
121
|
end
|
89
122
|
|
123
|
+
@dependency_file.dependencies = dependency_set.dependencies.to_set
|
90
124
|
dependency_set
|
91
125
|
end
|
92
126
|
|
@@ -267,14 +267,21 @@ module Dependabot
|
|
267
267
|
# NOTE: Needs to be explicitly run through corepack to respect the
|
268
268
|
# `packageManager` setting in `package.json`, because corepack does not
|
269
269
|
# add shims for NPM.
|
270
|
-
sig
|
271
|
-
|
270
|
+
sig do
|
271
|
+
params(
|
272
|
+
command: String,
|
273
|
+
fingerprint: T.nilable(String),
|
274
|
+
env: T.nilable(T::Hash[String, String])
|
275
|
+
).returns(String)
|
276
|
+
end
|
277
|
+
def self.run_npm_command(command, fingerprint: command, env: nil)
|
272
278
|
if Dependabot::Experiments.enabled?(:enable_corepack_for_npm_and_yarn)
|
273
279
|
package_manager_run_command(
|
274
280
|
NpmPackageManager::NAME,
|
275
281
|
command,
|
276
282
|
fingerprint: fingerprint,
|
277
|
-
output_observer: ->(output) { command_observer(output) }
|
283
|
+
output_observer: ->(output) { command_observer(output) },
|
284
|
+
env: env
|
278
285
|
)
|
279
286
|
else
|
280
287
|
Dependabot::SharedHelpers.run_shell_command(
|
@@ -506,14 +513,16 @@ module Dependabot
|
|
506
513
|
name: String,
|
507
514
|
command: String,
|
508
515
|
fingerprint: T.nilable(String),
|
509
|
-
output_observer: CommandHelpers::OutputObserver
|
516
|
+
output_observer: CommandHelpers::OutputObserver,
|
517
|
+
env: T.nilable(T::Hash[String, String])
|
510
518
|
).returns(String)
|
511
519
|
end
|
512
520
|
def self.package_manager_run_command(
|
513
521
|
name,
|
514
522
|
command,
|
515
523
|
fingerprint: nil,
|
516
|
-
output_observer: nil
|
524
|
+
output_observer: nil,
|
525
|
+
env: nil
|
517
526
|
)
|
518
527
|
return run_bun_command(command, fingerprint: fingerprint) if name == BunPackageManager::NAME
|
519
528
|
|
@@ -524,7 +533,8 @@ module Dependabot
|
|
524
533
|
return Dependabot::SharedHelpers.run_shell_command(
|
525
534
|
full_command,
|
526
535
|
fingerprint: fingerprint,
|
527
|
-
output_observer: output_observer
|
536
|
+
output_observer: output_observer,
|
537
|
+
env: env
|
528
538
|
).strip
|
529
539
|
else
|
530
540
|
Dependabot::SharedHelpers.run_shell_command(full_command, fingerprint: fingerprint)
|
@@ -55,7 +55,7 @@ module Dependabot
|
|
55
55
|
def registry
|
56
56
|
return @registry if @registry
|
57
57
|
|
58
|
-
@registry =
|
58
|
+
@registry = configured_registry || locked_registry || first_registry_with_dependency_details
|
59
59
|
T.must(@registry)
|
60
60
|
end
|
61
61
|
|
@@ -828,9 +828,10 @@ module Dependabot
|
|
828
828
|
).returns(T.nilable(T.any(T::Hash[String, T.untyped], String, T::Array[T::Hash[String, T.untyped]])))
|
829
829
|
end
|
830
830
|
def run_npm8_checker(version:)
|
831
|
+
env = corepack_registry_override_env
|
831
832
|
cmd =
|
832
833
|
"install #{version_install_arg(version: version)} --package-lock-only --dry-run=true --ignore-scripts"
|
833
|
-
output = Helpers.run_npm_command(cmd)
|
834
|
+
output = Helpers.run_npm_command(cmd, env: env)
|
834
835
|
if output.match?(NPM8_PEER_DEP_ERROR_REGEX)
|
835
836
|
error_context = { command: cmd, process_exit_value: 1 }
|
836
837
|
raise SharedHelpers::HelperSubprocessFailed.new(message: output, error_context: error_context)
|
@@ -839,6 +840,19 @@ module Dependabot
|
|
839
840
|
raise if e.message.match?(NPM8_PEER_DEP_ERROR_REGEX)
|
840
841
|
end
|
841
842
|
|
843
|
+
sig { returns(T.nilable(T::Hash[String, String])) }
|
844
|
+
def corepack_registry_override_env
|
845
|
+
return nil unless Dependabot::Experiments.enabled?(:enable_corepack_for_npm_and_yarn)
|
846
|
+
|
847
|
+
replaces_base_cred = credentials.find { |cred| cred["type"] == "npm_registry" && cred.replaces_base? }
|
848
|
+
registry_url = replaces_base_cred&.[]("registry")
|
849
|
+
return nil unless registry_url
|
850
|
+
|
851
|
+
registry_url = "https://#{registry_url}" unless registry_url.start_with?("http")
|
852
|
+
|
853
|
+
{ "npm_config_registry" => registry_url }
|
854
|
+
end
|
855
|
+
|
842
856
|
sig do
|
843
857
|
params(
|
844
858
|
version: T.nilable(T.any(String, Gem::Version))
|
@@ -259,6 +259,7 @@ module Dependabot
|
|
259
259
|
end
|
260
260
|
|
261
261
|
# rubocop:disable Metrics/AbcSize
|
262
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
262
263
|
sig { returns(T::Array[Dependabot::Dependency]) }
|
263
264
|
def conflicting_updated_dependencies
|
264
265
|
top_level_dependencies = top_level_dependency_lookup
|
@@ -266,7 +267,11 @@ module Dependabot
|
|
266
267
|
updated_deps = []
|
267
268
|
vulnerability_audit["fix_updates"].each do |update|
|
268
269
|
dependency_name = update["dependency_name"]
|
269
|
-
requirements = top_level_dependencies[dependency_name]&.
|
270
|
+
requirements = if top_level_dependencies[dependency_name]&.version == update["current_version"]
|
271
|
+
top_level_dependencies[dependency_name]&.requirements || []
|
272
|
+
else
|
273
|
+
[]
|
274
|
+
end
|
270
275
|
|
271
276
|
updated_deps << build_updated_dependency(
|
272
277
|
dependency: Dependency.new(
|
@@ -299,6 +304,7 @@ module Dependabot
|
|
299
304
|
updated_deps.select { |dep| dep.name == dependency.name } +
|
300
305
|
updated_deps.reject { |dep| dep.name == dependency.name }
|
301
306
|
end
|
307
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
302
308
|
|
303
309
|
sig { returns(T::Hash[String, Dependabot::Dependency]) }
|
304
310
|
def top_level_dependency_lookup
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dependabot-npm_and_yarn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.328.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dependabot
|
@@ -15,14 +15,14 @@ dependencies:
|
|
15
15
|
requirements:
|
16
16
|
- - '='
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: 0.
|
18
|
+
version: 0.328.0
|
19
19
|
type: :runtime
|
20
20
|
prerelease: false
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
22
22
|
requirements:
|
23
23
|
- - '='
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version: 0.
|
25
|
+
version: 0.328.0
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: debug
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -269,6 +269,12 @@ files:
|
|
269
269
|
- helpers/package.json
|
270
270
|
- helpers/patches/npm++pacote+9.5.12.patch
|
271
271
|
- helpers/run.js
|
272
|
+
- helpers/test/npm/fixtures/vulnerability-auditor/simple/package-lock.json
|
273
|
+
- helpers/test/npm/fixtures/vulnerability-auditor/simple/package.json
|
274
|
+
- helpers/test/npm/fixtures/vulnerability-auditor/update-needed-across-two-versions/package-lock.json
|
275
|
+
- helpers/test/npm/fixtures/vulnerability-auditor/update-needed-across-two-versions/package.json
|
276
|
+
- helpers/test/npm/helpers.js
|
277
|
+
- helpers/test/npm/vulnerability-auditor.test.js
|
272
278
|
- helpers/test/npm6/conflicting-dependency-parser.test.js
|
273
279
|
- helpers/test/npm6/fixtures/conflicting-dependency-parser/deeply-nested/package-lock.json
|
274
280
|
- helpers/test/npm6/fixtures/conflicting-dependency-parser/deeply-nested/package.json
|
@@ -356,7 +362,7 @@ licenses:
|
|
356
362
|
- MIT
|
357
363
|
metadata:
|
358
364
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
359
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
365
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.328.0
|
360
366
|
rdoc_options: []
|
361
367
|
require_paths:
|
362
368
|
- lib
|