Skip to content

Commit 26e8f54

Browse files
refactor: adopt Devise core's 2FA interface
- Register WebauthnTwoFactorAuthenticatable module with `two_factor: true` - Include Devise's TwoFactorAuthenticatable concern in the 2FA model - Inherit 2FA strategy from Devise's new TwoFactor base strategy - Remove DatabaseAuthenticatable override (Devise now handles 2FA routing) - Rename controller to match Devise's expected naming convention - Update routes and helpers for new endpoints - Use Devise-provided 2FA session keys
1 parent d226794 commit 26e8f54

9 files changed

Lines changed: 14 additions & 121 deletions

app/controllers/devise/security_key_authentication_options_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def index
2020
private
2121

2222
def set_resource
23-
@resource = resource_class.find(session[:current_authentication_resource_id])
23+
@resource = resource_class.find(session[:devise_two_factor_resource_id])
2424
end
2525
end
2626
end

app/controllers/devise/two_factor_authentications_controller.rb

Lines changed: 0 additions & 38 deletions
This file was deleted.
File renamed without changes.

lib/devise/models/webauthn_two_factor_authenticatable.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ module Models
99
module WebauthnTwoFactorAuthenticatable
1010
extend ActiveSupport::Concern
1111
include WebauthnCredentialAuthenticatable
12+
include Devise::Models::TwoFactorAuthenticatable
1213

1314
included do
1415
has_many :second_factor_webauthn_credentials, -> { second_factor }, class_name: "WebauthnCredential"
1516
end
1617

17-
def second_factor_enabled?
18+
def webauthn_two_factor_enabled?
1819
webauthn_credentials.any?
1920
end
2021
end

lib/devise/strategies/database_authenticatable.rb

Lines changed: 0 additions & 53 deletions
This file was deleted.

lib/devise/strategies/webauthn_two_factor_authenticatable.rb

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,15 @@
22

33
module Devise
44
module Strategies
5-
class WebauthnTwoFactorAuthenticatable < Devise::Strategies::Base
5+
class WebauthnTwoFactorAuthenticatable < Devise::Strategies::TwoFactor
66
def valid?
77
credential_param.present? &&
8-
session[:current_authentication_resource_id].present? &&
8+
session[:devise_two_factor_resource_id].present? &&
99
session[:two_factor_authentication_challenge].present?
1010
end
1111

12-
# rubocop:disable Metrics/AbcSize
13-
def authenticate!
12+
def verify_two_factor!(resource)
1413
credential_from_params = WebAuthn::Credential.from_get(JSON.parse(credential_param))
15-
resource = resource_class.find_by(id: session[:current_authentication_resource_id])
1614
stored_credential = resource&.webauthn_credentials&.find_by(external_id: credential_from_params.id)
1715

1816
return fail!(:webauthn_credential_not_found) if stored_credential.blank?
@@ -21,18 +19,11 @@ def authenticate!
2119
end
2220

2321
verify_credential(credential_from_params, stored_credential)
24-
25-
resource.remember_me = session[:current_authentication_remember_me] if resource.respond_to?(:remember_me=)
26-
success!(resource)
27-
28-
session.delete(:current_authentication_resource_id)
29-
session.delete(:current_authentication_remember_me)
3022
rescue WebAuthn::Error
3123
fail!(:webauthn_credential_verification_failed)
3224
ensure
3325
session.delete(:two_factor_authentication_challenge)
3426
end
35-
# rubocop:enable Metrics/AbcSize
3627

3728
private
3829

@@ -54,10 +45,6 @@ def user_handle_mismatch?(credential_from_params, resource)
5445
credential_from_params.user_handle.present? &&
5546
credential_from_params.user_handle != resource.webauthn_id
5647
end
57-
58-
def resource_class
59-
mapping.to
60-
end
6148
end
6249
end
6350
end

lib/devise/webauthn/engine.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ class Engine < ::Rails::Engine
1515
}
1616
)
1717

18-
Devise.add_module(
19-
:webauthn_two_factor_authenticatable,
18+
Devise.register_two_factor_method(
19+
:webauthn,
2020
{
2121
model: "devise/models/webauthn_two_factor_authenticatable",
22-
strategy: true,
23-
route: { two_factor_authentication: [] }
22+
strategy: :webauthn_two_factor_authenticatable,
23+
route: { webauthn: [] }
2424
}
2525
)
2626
end

lib/devise/webauthn/helpers/credentials_helper.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def security_key_creation_form_for(resource_or_resource_name, **options, &block)
4040

4141
def login_with_security_key_form_for(resource_or_resource_name, **options, &block)
4242
form_with(
43-
**options, url: two_factor_authentication_path(resource_or_resource_name), method: :post
43+
**options, url: two_factor_path(resource_or_resource_name), method: :post
4444
) do |f|
4545
tag.webauthn_get(data: {
4646
options_url: security_key_authentication_options_path(resource_or_resource_name)

lib/devise/webauthn/routes.rb

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,15 @@ def devise_passkey_authentication(_mapping, controllers)
1313
resources :passkey_registration_options, only: :index, controller: controllers[:passkey_registration_options]
1414
end
1515

16-
def devise_two_factor_authentication(_mapping, controllers)
17-
resource :two_factor_authentication,
18-
only: %i[new create],
19-
controller: controllers[:two_factor_authentications]
20-
16+
def devise_webauthn(_mapping, controllers)
2117
resources :second_factor_webauthn_credentials,
2218
only: %i[new create update destroy],
2319
controller: controllers[:second_factor_webauthn_credentials]
2420

2521
resources :security_key_authentication_options, only: %i[index],
26-
controller: controllers[:security_key_authentication_options]
22+
controller: controllers[:security_key_authentication_options]
2723
resources :security_key_registration_options, only: %i[index],
28-
controller: controllers[:security_key_registration_options]
24+
controller: controllers[:security_key_registration_options]
2925
end
3026
end
3127
end

0 commit comments

Comments
 (0)