diff --git a/lib/api/concerns/packages/npm_endpoints.rb b/lib/api/concerns/packages/npm_endpoints.rb index f26b3a1d8c2fc894dc1060dcc573e4d9f639b5bf..d0594269a19fbdc54f0c8cfbfe92072378dbec17 100644 --- a/lib/api/concerns/packages/npm_endpoints.rb +++ b/lib/api/concerns/packages/npm_endpoints.rb @@ -163,8 +163,7 @@ def redirect_or_present_audit_report route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true get '*package_name', format: false, requirements: ::API::Helpers::Packages::Npm::NPM_ENDPOINT_REQUIREMENTS do package_name = params[:package_name] - packages = ::Packages::Npm::PackageFinder.new(package_name, project: project_or_nil) - .execute + packages = find_by_endpoint_scope(package_name) redirect_request = project_or_nil.blank? || packages.empty? diff --git a/lib/api/helpers/packages/npm.rb b/lib/api/helpers/packages/npm.rb index 352d77f472c86fc2b9b0c83793a5794ed48a205e..7dd5cb7e49cf2e4c18b29203d45d8953b9034154 100644 --- a/lib/api/helpers/packages/npm.rb +++ b/lib/api/helpers/packages/npm.rb @@ -33,6 +33,19 @@ def project end end + def find_by_endpoint_scope(package_name) + case endpoint_scope + when :project + ::Packages::Npm::PackageFinder.new(package_name, project: project_or_nil).execute + when :instance + namespace = package_namespace(package_name) + return unless namespace + + ::Packages::Npm::PackageFinder.new(package_name, namespace: namespace, last_of_each_version: false) + .execute + end + end + def project_or_nil # mainly used by the metadata endpoint where we need to get a project # and return nil if not found (no errors should be raised) @@ -50,11 +63,7 @@ def project_id_or_nil params[:id] when :instance package_name = params[:package_name] - namespace_path = ::Packages::Npm.scope_of(package_name) - next unless namespace_path - - namespace = Namespace.top_most - .by_path(namespace_path) + namespace = package_namespace(package_name) next unless namespace finder = ::Packages::Npm::PackageFinder.new( @@ -67,6 +76,13 @@ def project_id_or_nil end end end + + def package_namespace(package_name) + namespace_path = ::Packages::Npm.scope_of(package_name) + return unless namespace_path + + Namespace.top_most.by_path(namespace_path) + end end end end diff --git a/spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb b/spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb index 1e50505162d9ab1a11a94489131e3c31f29b3fff..80711ae57bd067420bd7a3c884c5e9ff9036a0cb 100644 --- a/spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb +++ b/spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb @@ -20,6 +20,11 @@ let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, property: 'i_package_npm_user' } } before do + create(:packages_dependency_link, package: package1, dependency_type: :dependencies) + create(:packages_dependency_link, package: package1, dependency_type: :devDependencies) + create(:packages_dependency_link, package: package1, dependency_type: :bundleDependencies) + create(:packages_dependency_link, package: package1, dependency_type: :peerDependencies) + # create a duplicated package without triggering model validation errors package1.update_column(:version, '1.2.3') end