dependabot-npm_and_yarn 0.212.0 → 0.213.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/.eslintrc +1 -1
  3. data/helpers/README.md +2 -2
  4. data/helpers/lib/npm/vulnerability-auditor.js +7 -7
  5. data/helpers/package-lock.json +2585 -2386
  6. data/helpers/package.json +4 -4
  7. data/lib/dependabot/npm_and_yarn/file_fetcher.rb +30 -5
  8. data/lib/dependabot/npm_and_yarn/file_parser/lockfile_parser.rb +19 -4
  9. data/lib/dependabot/npm_and_yarn/file_parser.rb +17 -5
  10. data/lib/dependabot/npm_and_yarn/file_updater/npm_lockfile_updater.rb +35 -21
  11. data/lib/dependabot/npm_and_yarn/file_updater/npmrc_builder.rb +7 -3
  12. data/lib/dependabot/npm_and_yarn/file_updater/package_json_updater.rb +2 -2
  13. data/lib/dependabot/npm_and_yarn/file_updater/yarn_lockfile_updater.rb +83 -24
  14. data/lib/dependabot/npm_and_yarn/file_updater.rb +54 -0
  15. data/lib/dependabot/npm_and_yarn/helpers.rb +48 -0
  16. data/lib/dependabot/npm_and_yarn/package_name.rb +2 -2
  17. data/lib/dependabot/npm_and_yarn/requirement.rb +3 -3
  18. data/lib/dependabot/npm_and_yarn/update_checker/latest_version_finder.rb +6 -1
  19. data/lib/dependabot/npm_and_yarn/update_checker/library_detector.rb +16 -3
  20. data/lib/dependabot/npm_and_yarn/update_checker/registry_finder.rb +67 -19
  21. data/lib/dependabot/npm_and_yarn/update_checker/requirements_updater.rb +3 -4
  22. data/lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb +23 -1
  23. data/lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb +3 -3
  24. data/lib/dependabot/npm_and_yarn/update_checker/vulnerability_auditor.rb +33 -8
  25. data/lib/dependabot/npm_and_yarn/update_checker.rb +72 -19
  26. data/lib/dependabot/npm_and_yarn/version.rb +1 -1
  27. metadata +13 -55
@@ -4,6 +4,7 @@ require "dependabot/git_commit_checker"
4
4
  require "dependabot/update_checkers"
5
5
  require "dependabot/update_checkers/base"
6
6
  require "dependabot/shared_helpers"
7
+ require "set"
7
8
 
8
9
  module Dependabot
9
10
  module NpmAndYarn
@@ -16,6 +17,20 @@ module Dependabot
16
17
  require_relative "update_checker/conflicting_dependency_resolver"
17
18
  require_relative "update_checker/vulnerability_auditor"
18
19
 
20
+ def up_to_date?
21
+ return false if security_update? &&
22
+ dependency.version &&
23
+ version_class.correct?(dependency.version) &&
24
+ vulnerable_versions.any? &&
25
+ !vulnerable_versions.include?(version_class.new(dependency.version))
26
+
27
+ super
28
+ end
29
+
30
+ def vulnerable?
31
+ super || vulnerable_versions.any?
32
+ end
33
+
19
34
  def latest_version
20
35
  @latest_version ||=
21
36
  if git_dependency?
@@ -46,8 +61,8 @@ module Dependabot
46
61
  raise "Dependency not vulnerable!" unless vulnerable?
47
62
  # NOTE: we currently don't resolve transitive/sub-dependencies as
48
63
  # npm/yarn don't provide any control over updating to a specific
49
- # sub-dependency
50
- return latest_resolvable_version unless dependency.top_level?
64
+ # sub-dependency version
65
+ return latest_resolvable_transitive_security_fix_version_with_no_unlock unless dependency.top_level?
51
66
 
52
67
  # TODO: Might want to check resolvability here?
53
68
  lowest_security_fix_version
@@ -96,13 +111,19 @@ module Dependabot
96
111
  end
97
112
 
98
113
  def conflicting_dependencies
99
- ConflictingDependencyResolver.new(
114
+ conflicts = ConflictingDependencyResolver.new(
100
115
  dependency_files: dependency_files,
101
116
  credentials: credentials
102
117
  ).conflicting_dependencies(
103
118
  dependency: dependency,
104
119
  target_version: lowest_security_fix_version
105
120
  )
121
+
122
+ vulnerable = [vulnerability_audit].select do |hash|
123
+ !hash["fix_available"] && hash["explanation"]
124
+ end
125
+
126
+ conflicts + vulnerable
106
127
  end
107
128
 
108
129
  private
@@ -119,24 +140,30 @@ module Dependabot
119
140
  )
120
141
  end
121
142
 
143
+ def vulnerable_versions
144
+ @vulnerable_versions ||=
145
+ begin
146
+ all_versions = dependency.all_versions.
147
+ filter_map { |v| version_class.new(v) if version_class.correct?(v) }
148
+
149
+ all_versions.select do |v|
150
+ security_advisories.any? { |advisory| advisory.vulnerable?(v) }
151
+ end
152
+ end
153
+ end
154
+
122
155
  def latest_version_resolvable_with_full_unlock?
123
156
  return false unless latest_version
124
157
 
125
158
  return version_resolver.latest_version_resolvable_with_full_unlock? if dependency.top_level?
126
159
 
127
- return false unless transitive_security_updates_enabled? && security_advisories.any?
160
+ return false unless security_advisories.any?
128
161
 
129
162
  vulnerability_audit["fix_available"]
130
163
  end
131
164
 
132
- def transitive_security_updates_enabled?
133
- options.key?(:npm_transitive_security_updates)
134
- end
135
-
136
165
  def updated_dependencies_after_full_unlock
137
- if !dependency.top_level? && transitive_security_updates_enabled? && security_advisories.any?
138
- return conflicting_updated_dependencies
139
- end
166
+ return conflicting_updated_dependencies if !dependency.top_level? && security_advisories.any?
140
167
 
141
168
  version_resolver.dependency_updates_from_full_unlock.
142
169
  map { |update_details| build_updated_dependency(update_details) }
@@ -163,16 +190,18 @@ module Dependabot
163
190
  end
164
191
  # rubocop:enable Metrics/AbcSize
165
192
 
166
- # We don't need to update this but need to include it so it's described
167
- # in the PR and we'll pass validation that this dependency is at a
168
- # non-vulnerable version.
193
+ # We don't need to directly update the target dependency if it will
194
+ # be updated as a side effect of updating the parent. However, we need
195
+ # to include it so it's described in the PR and we'll pass validation
196
+ # that this dependency is at a non-vulnerable version.
169
197
  if updated_deps.none? { |dep| dep.name == dependency.name }
170
198
  target_version = vulnerability_audit["target_version"]
171
199
  updated_deps << build_updated_dependency(
172
200
  dependency: dependency,
173
201
  version: target_version,
174
202
  previous_version: dependency.version,
175
- removed: target_version.nil?
203
+ removed: target_version.nil?,
204
+ metadata: { information_only: true } # Instruct updater to not directly update this dependency
176
205
  )
177
206
  end
178
207
 
@@ -196,23 +225,35 @@ module Dependabot
196
225
  removed = update_details.fetch(:removed, false)
197
226
  version = update_details.fetch(:version).to_s unless removed
198
227
  previous_version = update_details.fetch(:previous_version)&.to_s
228
+ metadata = update_details.fetch(:metadata, {})
199
229
 
200
230
  Dependency.new(
201
231
  name: original_dep.name,
202
232
  version: version,
203
233
  requirements: RequirementsUpdater.new(
204
234
  requirements: original_dep.requirements,
205
- updated_source: original_dep == dependency ? updated_source : nil,
235
+ updated_source: original_dep == dependency ? updated_source : original_source(original_dep),
206
236
  latest_resolvable_version: version,
207
237
  update_strategy: requirements_update_strategy
208
238
  ).updated_requirements,
209
239
  previous_version: previous_version,
210
240
  previous_requirements: original_dep.requirements,
211
241
  package_manager: original_dep.package_manager,
212
- removed: removed
242
+ removed: removed,
243
+ metadata: metadata
213
244
  )
214
245
  end
215
246
 
247
+ def latest_resolvable_transitive_security_fix_version_with_no_unlock
248
+ fix_possible = Dependabot::UpdateCheckers::VersionFilters.filter_vulnerable_versions(
249
+ [latest_resolvable_version].compact,
250
+ security_advisories
251
+ ).any?
252
+ return nil unless fix_possible
253
+
254
+ latest_resolvable_version
255
+ end
256
+
216
257
  def latest_resolvable_version_with_no_unlock_for_git_dependency
217
258
  reqs = dependency.requirements.filter_map do |r|
218
259
  next if r.fetch(:requirement).nil?
@@ -365,12 +406,24 @@ module Dependabot
365
406
  return true if dependency_files.any? { |f| f.name == "lerna.json" }
366
407
 
367
408
  @library =
368
- LibraryDetector.new(package_json_file: package_json).library?
409
+ LibraryDetector.new(
410
+ package_json_file: package_json,
411
+ credentials: credentials,
412
+ dependency_files: dependency_files
413
+ ).library?
414
+ end
415
+
416
+ def security_update?
417
+ security_advisories.any?
369
418
  end
370
419
 
371
420
  def dependency_source_details
421
+ original_source(dependency)
422
+ end
423
+
424
+ def original_source(updated_dependency)
372
425
  sources =
373
- dependency.requirements.map { |r| r.fetch(:source) }.uniq.compact.
426
+ updated_dependency.requirements.map { |r| r.fetch(:source) }.uniq.compact.
374
427
  sort_by { |source| RegistryFinder.central_registry?(source[:url]) ? 1 : 0 }
375
428
 
376
429
  sources.first
@@ -15,7 +15,7 @@ module Dependabot
15
15
  attr_reader :build_info
16
16
 
17
17
  VERSION_PATTERN = Gem::Version::VERSION_PATTERN + '(\+[0-9a-zA-Z\-.]+)?'
18
- ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/.freeze
18
+ ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/
19
19
 
20
20
  def self.correct?(version)
21
21
  version = version.gsub(/^v/, "") if version.is_a?(String)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-npm_and_yarn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.212.0
4
+ version: 0.213.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-06 00:00:00.000000000 Z
11
+ date: 2022-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dependabot-common
@@ -16,42 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.212.0
19
+ version: 0.213.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.212.0
27
- - !ruby/object:Gem::Dependency
28
- name: debase
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '='
32
- - !ruby/object:Gem::Version
33
- version: 0.2.3
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '='
39
- - !ruby/object:Gem::Version
40
- version: 0.2.3
41
- - !ruby/object:Gem::Dependency
42
- name: debase-ruby_core_source
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - '='
46
- - !ruby/object:Gem::Version
47
- version: 0.10.16
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - '='
53
- - !ruby/object:Gem::Version
54
- version: 0.10.16
26
+ version: 0.213.0
55
27
  - !ruby/object:Gem::Dependency
56
28
  name: debug
57
29
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +58,14 @@ dependencies:
86
58
  requirements:
87
59
  - - "~>"
88
60
  - !ruby/object:Gem::Version
89
- version: 3.12.0
61
+ version: 3.13.0
90
62
  type: :development
91
63
  prerelease: false
92
64
  version_requirements: !ruby/object:Gem::Requirement
93
65
  requirements:
94
66
  - - "~>"
95
67
  - !ruby/object:Gem::Version
96
- version: 3.12.0
68
+ version: 3.13.0
97
69
  - !ruby/object:Gem::Dependency
98
70
  name: rake
99
71
  requirement: !ruby/object:Gem::Requirement
@@ -142,42 +114,28 @@ dependencies:
142
114
  requirements:
143
115
  - - "~>"
144
116
  - !ruby/object:Gem::Version
145
- version: 1.36.0
117
+ version: 1.37.1
146
118
  type: :development
147
119
  prerelease: false
148
120
  version_requirements: !ruby/object:Gem::Requirement
149
121
  requirements:
150
122
  - - "~>"
151
123
  - !ruby/object:Gem::Version
152
- version: 1.36.0
124
+ version: 1.37.1
153
125
  - !ruby/object:Gem::Dependency
154
126
  name: rubocop-performance
155
127
  requirement: !ruby/object:Gem::Requirement
156
128
  requirements:
157
129
  - - "~>"
158
130
  - !ruby/object:Gem::Version
159
- version: 1.14.2
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - "~>"
165
- - !ruby/object:Gem::Version
166
- version: 1.14.2
167
- - !ruby/object:Gem::Dependency
168
- name: ruby-debug-ide
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - "~>"
172
- - !ruby/object:Gem::Version
173
- version: 0.7.3
131
+ version: 1.15.0
174
132
  type: :development
175
133
  prerelease: false
176
134
  version_requirements: !ruby/object:Gem::Requirement
177
135
  requirements:
178
136
  - - "~>"
179
137
  - !ruby/object:Gem::Version
180
- version: 0.7.3
138
+ version: 1.15.0
181
139
  - !ruby/object:Gem::Dependency
182
140
  name: simplecov
183
141
  requirement: !ruby/object:Gem::Requirement
@@ -350,14 +308,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
350
308
  requirements:
351
309
  - - ">="
352
310
  - !ruby/object:Gem::Version
353
- version: 2.7.0
311
+ version: 3.1.0
354
312
  required_rubygems_version: !ruby/object:Gem::Requirement
355
313
  requirements:
356
314
  - - ">="
357
315
  - !ruby/object:Gem::Version
358
- version: 2.7.0
316
+ version: 3.1.0
359
317
  requirements: []
360
- rubygems_version: 3.1.6
318
+ rubygems_version: 3.3.7
361
319
  signing_key:
362
320
  specification_version: 4
363
321
  summary: JS support for dependabot