diff --git a/lib/auth/default_current_user_provider.rb b/lib/auth/default_current_user_provider.rb index 761ac3a5e87..e91cd59630a 100644 --- a/lib/auth/default_current_user_provider.rb +++ b/lib/auth/default_current_user_provider.rb @@ -259,7 +259,15 @@ class Auth::DefaultCurrentUserProvider end api_key.update_columns(last_used_at: Time.zone.now) + if client_id.present? && client_id != api_key.client_id + + # invalidate old dupe api key for client if needed + UserApiKey + .where(client_id: client_id, user_id: api_key.user_id) + .where('id <> ?', api_key.id) + .destroy_all + api_key.update_columns(client_id: client_id) end diff --git a/spec/components/auth/default_current_user_provider_spec.rb b/spec/components/auth/default_current_user_provider_spec.rb index b3a3d7a54eb..20cf716d964 100644 --- a/spec/components/auth/default_current_user_provider_spec.rb +++ b/spec/components/auth/default_current_user_provider_spec.rb @@ -368,6 +368,26 @@ describe Auth::DefaultCurrentUserProvider do ) end + it "can clear old duplicate keys correctly" do + dupe = UserApiKey.create!( + application_name: 'my app', + client_id: '12345', + scopes: ['read'], + key: SecureRandom.hex, + user_id: user.id + ) + + params = { + "REQUEST_METHOD" => "GET", + "HTTP_USER_API_KEY" => api_key.key, + "HTTP_USER_API_CLIENT_ID" => dupe.client_id, + } + + good_provider = provider("/", params) + expect(good_provider.current_user.id).to eq(user.id) + expect(UserApiKey.find_by(id: dupe.id)).to eq(nil) + end + it "allows user API access correctly" do params = { "REQUEST_METHOD" => "GET",