diff --git a/app/controllers/oidc_controller.rb b/app/controllers/oidc_controller.rb index 54744f2..0b46ae0 100644 --- a/app/controllers/oidc_controller.rb +++ b/app/controllers/oidc_controller.rb @@ -482,14 +482,11 @@ class OidcController < ApplicationController return end - # Find the refresh token record - # Note: This is inefficient with BCrypt hashing, but necessary for security - # In production, consider adding a token prefix for faster lookup - refresh_token_record = OidcRefreshToken.where(application: application).find do |rt| - rt.token_matches?(refresh_token) - end + # Find the refresh token record using indexed token prefix lookup + refresh_token_record = OidcRefreshToken.find_by_token(refresh_token) - unless refresh_token_record + # Verify the token belongs to the correct application + unless refresh_token_record && refresh_token_record.application == application render json: { error: "invalid_grant", error_description: "Invalid refresh token" }, status: :bad_request return end @@ -668,9 +665,7 @@ class OidcController < ApplicationController if token_type_hint == "refresh_token" || token_type_hint.nil? # Try to find as refresh token - refresh_token_record = OidcRefreshToken.where(application: application).find do |rt| - rt.token_matches?(token) - end + refresh_token_record = OidcRefreshToken.find_by_token(token) if refresh_token_record refresh_token_record.revoke! @@ -681,9 +676,7 @@ class OidcController < ApplicationController if !revoked && (token_type_hint == "access_token" || token_type_hint.nil?) # Try to find as access token - access_token_record = OidcAccessToken.where(application: application).find do |at| - at.token_matches?(token) - end + access_token_record = OidcAccessToken.find_by_token(token) if access_token_record access_token_record.revoke! diff --git a/app/models/oidc_refresh_token.rb b/app/models/oidc_refresh_token.rb index d60a453..aede896 100644 --- a/app/models/oidc_refresh_token.rb +++ b/app/models/oidc_refresh_token.rb @@ -10,6 +10,7 @@ class OidcRefreshToken < ApplicationRecord before_validation :set_token_family_id, on: :create validates :token_digest, presence: true, uniqueness: true + validates :token_prefix, presence: true scope :valid, -> { where("expires_at > ?", Time.current).where(revoked_at: nil) } scope :expired, -> { where("expires_at <= ?", Time.current) } diff --git a/config/environments/production.rb b/config/environments/production.rb index 41493f4..ca66c3b 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -57,8 +57,8 @@ Rails.application.configure do # Replace the default in-process memory cache store with a durable alternative. config.cache_store = :solid_cache_store - # Use async processor for background jobs (modify as needed for production) - config.active_job.queue_adapter = :async + # Use Solid Queue for background jobs + config.active_job.queue_adapter = :solid_queue # Ignore bad email addresses and do not raise email delivery errors. # Set this to true and configure the email server for immediate delivery to raise delivery errors.