diff --git a/npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater/npmrc_builder.rb b/npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater/npmrc_builder.rb index 3a877afa140..4e5c924ffc3 100644 --- a/npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater/npmrc_builder.rb +++ b/npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater/npmrc_builder.rb @@ -42,7 +42,9 @@ def build_npmrc_content_from_lockfile return unless yarn_lock || package_lock return unless global_registry - "registry = https://#{global_registry['registry']}\n" \ + registry = global_registry["registry"] + registry = "https://#{registry}" unless registry.start_with?("http") + "registry = #{registry}\n" \ "#{global_registry_auth_line}" \ "always-auth = true" end @@ -113,8 +115,10 @@ def complete_npmrc_from_credentials return initial_content unless yarn_lock || package_lock return initial_content unless global_registry + registry = global_registry["registry"] + registry = "https://#{registry}" unless registry.start_with?("http") initial_content + - "registry = https://#{global_registry['registry']}\n" \ + "registry = #{registry}\n" \ "#{global_registry_auth_line}" \ "always-auth = true\n" end diff --git a/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/registry_finder.rb b/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/registry_finder.rb index 4d4dfcc9c60..29c6ca56060 100644 --- a/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/registry_finder.rb +++ b/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/registry_finder.rb @@ -65,8 +65,10 @@ def registry_from_rc(dependency_name) def first_registry_with_dependency_details @first_registry_with_dependency_details ||= known_registries.find do |details| + url = "#{details['registry'].gsub(%r{/+$}, '')}/#{escaped_dependency_name}" + url = "https://#{url}" unless url.start_with?("http") response = Dependabot::RegistryClient.get( - url: "https://#{details['registry'].gsub(%r{/+$}, '')}/#{escaped_dependency_name}", + url: url, headers: auth_header_for(details["token"]) ) response.status < 400 && JSON.parse(response.body) @@ -80,6 +82,8 @@ def first_registry_with_dependency_details end def registry_url + return registry if registry.start_with?("http") + protocol = if registry_source_url registry_source_url.split("://").first @@ -202,23 +206,36 @@ def unique_registries(registries) end end + # rubocop:disable Metrics/PerceivedComplexity def global_registry + return @global_registry if defined? @global_registry + npmrc_file&.content.to_s.scan(NPM_GLOBAL_REGISTRY_REGEX) do next if Regexp.last_match[:registry].include?("${") - return Regexp.last_match[:registry].strip + return @global_registry = Regexp.last_match[:registry].strip end yarnrc_file&.content.to_s.scan(YARN_GLOBAL_REGISTRY_REGEX) do next if Regexp.last_match[:registry].include?("${") - return Regexp.last_match[:registry].strip + return @global_registry = Regexp.last_match[:registry].strip end - return parsed_yarnrc_yml["npmRegistryServer"] if parsed_yarnrc_yml&.key?("npmRegistryServer") + if parsed_yarnrc_yml&.key?("npmRegistryServer") + return @global_registry = parsed_yarnrc_yml["npmRegistryServer"] + end + + replaces_base = credentials.find { |cred| cred["type"] == "npm_registry" && cred["replaces-base"] == true } + if replaces_base + registry = replaces_base["registry"] + registry = "https://#{registry}" unless registry.start_with?("http") + return @global_registry = registry + end "https://registry.npmjs.org" end + # rubocop:enable Metrics/PerceivedComplexity def scoped_registry(scope) npmrc_file&.content.to_s.scan(NPM_SCOPED_REGISTRY_REGEX) do diff --git a/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/registry_finder_spec.rb b/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/registry_finder_spec.rb index f9b0d35fcdc..6a492593d2c 100644 --- a/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/registry_finder_spec.rb +++ b/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/registry_finder_spec.rb @@ -46,6 +46,18 @@ it { is_expected.to eq("https://registry.npmjs.org") } + context "with no rc and with credentials" do + let(:credentials) do + [{ + "type" => "npm_registry", + "registry" => "http://example.com", + "replaces-base" => true + }] + end + + it { is_expected.to eq("http://example.com") } + end + context "with a global npm registry" do let(:npmrc_file) { Dependabot::DependencyFile.new(name: ".npmrc", content: "registry=http://example.com") } @@ -122,7 +134,7 @@ "password" => "token" }, { "type" => "npm_registry", - "registry" => "npm.fury.io/dependabot", + "registry" => "https://npm.fury.io/dependabot", "token" => "secret_token" }] end @@ -145,7 +157,7 @@ to_return(status: 200, body: body) end - it { is_expected.to eq("npm.fury.io/dependabot") } + it { is_expected.to eq("https://npm.fury.io/dependabot") } context "but returns HTML" do before do