diff --git a/app/models/devise_token_auth/concerns/user.rb b/app/models/devise_token_auth/concerns/user.rb index d58e97042..3a1e884cf 100644 --- a/app/models/devise_token_auth/concerns/user.rb +++ b/app/models/devise_token_auth/concerns/user.rb @@ -98,6 +98,8 @@ def create_token(client_id: nil, token: nil, expiry: nil, **token_extras) expiry: expiry }.merge!(token_extras) + clean_old_tokens + [client_id, token, expiry] end @@ -196,17 +198,12 @@ def build_auth_header(token, client_id='default') def update_auth_header(token, client_id='default') headers = build_auth_header(token, client_id) - while tokens.length > 0 && DeviseTokenAuth.max_number_of_devices < tokens.length - oldest_client_id, _tk = tokens.min_by { |_cid, v| v[:expiry] || v["expiry"] } - tokens.delete(oldest_client_id) - end - + clean_old_tokens save! headers end - def build_auth_url(base_url, args) args[:uid] = uid args[:expiry] = tokens[args[:client_id]]['expiry'] @@ -214,7 +211,6 @@ def build_auth_url(base_url, args) DeviseTokenAuth::Url.generate(base_url, args) end - def extend_batch_buffer(token, client_id) self.tokens[client_id]['updated_at'] = Time.now update_auth_header(token, client_id) @@ -257,4 +253,10 @@ def remove_tokens_after_password_reset end end + def clean_old_tokens + while tokens.length > 0 && DeviseTokenAuth.max_number_of_devices < tokens.length + oldest_client_id, _tk = tokens.min_by { |_cid, v| v[:expiry] || v["expiry"] } + tokens.delete(oldest_client_id) + end + end end diff --git a/test/controllers/devise_token_auth/sessions_controller_test.rb b/test/controllers/devise_token_auth/sessions_controller_test.rb index 694bbc88a..397209d11 100644 --- a/test/controllers/devise_token_auth/sessions_controller_test.rb +++ b/test/controllers/devise_token_auth/sessions_controller_test.rb @@ -72,6 +72,33 @@ class DeviseTokenAuth::SessionsControllerTest < ActionController::TestCase assert_equal '0.0.0.0', @new_last_sign_in_ip end end + + describe "with multiple clients and headers don't change in each request" do + before do + DeviseTokenAuth.max_number_of_devices = 1 + DeviseTokenAuth.change_headers_on_each_request = false + @tokens = [] + (1..3).each do |n| + post :create, + params: { + email: @existing_user.email, + password: 'secret123' + } + @tokens << @existing_user.reload.tokens + end + end + + test 'should delete old tokens' do + current_tokens = @existing_user.reload.tokens + assert_equal 1, current_tokens.count + assert_equal @tokens.pop.keys.first, current_tokens.keys.first + end + + after do + DeviseTokenAuth.max_number_of_devices = 10 + DeviseTokenAuth.change_headers_on_each_request = true + end + end end describe 'get sign_in is not supported' do