diff --git a/CHANGELOG.md b/CHANGELOG.md index 022b07b..0112d01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ ## [Unreleased] +- [Bump to warden-webauthn 0.2.1](https://github.com/ruby-passkeys/devise-passkeys/pull/29/commits/d825ffded91aa98801bdd5530442761aa60538f9) +- [Use `Warden::WebAuthn::RackHelper.set_relying_party_in_request_env` to streamline setup](https://github.com/ruby-passkeys/devise-passkeys/pull/29/commits/7b7d50129ebe83b0a224d0ace0e4cff8ea407f4a) +- [Refactor PasskeysControllerConcern to have clearer credential verify with `verify_credential_integrity`](https://github.com/ruby-passkeys/devise-passkeys/pull/29/commits/f1400cb4b217c20b9e74fda3f55f74284e373d25) +- Refactor Controller concerns to not use `Warden::WebAuthn::StrategyHelpers` + - https://github.com/ruby-passkeys/devise-passkeys/pull/29 - Rename `Devise::Passkeys::Controllers::Concerns::PasskeyReauthentication` => `Devise::Passkeys::Controllers::Concerns::Reauthentication` - https://github.com/ruby-passkeys/devise-passkeys/pull/7/ - Bump `Devise` requirement to `>= 4.7.1` diff --git a/Gemfile.lock b/Gemfile.lock index 1ff91f6..a6738be 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,7 +3,7 @@ PATH specs: devise-passkeys (0.1.0) devise (>= 4.7.1) - warden-webauthn (>= 0.2.0) + warden-webauthn (>= 0.2.1) GEM remote: https://rubygems.org/ @@ -157,7 +157,7 @@ GEM unicode-display_width (2.4.2) warden (1.2.9) rack (>= 2.0.9) - warden-webauthn (0.2.0) + warden-webauthn (0.2.1) warden webauthn (>= 3) webauthn (3.0.0) diff --git a/README.md b/README.md index 113b1a5..174e9b1 100644 --- a/README.md +++ b/README.md @@ -96,10 +96,6 @@ class Users::SessionsController < Devise::SessionsController def relying_party WebAuthn::RelyingParty.new(...) end - - def set_relying_party_in_request_env - request.env[relying_party_key] = relying_party - end end # frozen_string_literal: true @@ -111,10 +107,6 @@ class Users::ReauthenticationController < DeviseController def relying_party WebAuthn::RelyingParty.new(...) end - - def set_relying_party_in_request_env - request.env[relying_party_key] = relying_party - end end # frozen_string_literal: true @@ -126,10 +118,6 @@ class Users::PasskeysController < DeviseController def relying_party WebAuthn::RelyingParty.new(...) end - - def set_relying_party_in_request_env - request.env[relying_party_key] = relying_party - end end ``` diff --git a/devise-passkeys.gemspec b/devise-passkeys.gemspec index edf5d36..3a9b2bc 100644 --- a/devise-passkeys.gemspec +++ b/devise-passkeys.gemspec @@ -33,7 +33,7 @@ Gem::Specification.new do |spec| # Uncomment to register a new dependency of your gem spec.add_dependency "devise", ">= 4.7.1" - spec.add_dependency "warden-webauthn", ">= 0.2.0" + spec.add_dependency "warden-webauthn", ">= 0.2.1" # For more information and examples about making a new gem, check out our # guide at: https://bundler.io/guides/creating_gem.html diff --git a/lib/devise/passkeys/controllers/passkeys_controller_concern.rb b/lib/devise/passkeys/controllers/passkeys_controller_concern.rb index ae1e59e..5a38dca 100644 --- a/lib/devise/passkeys/controllers/passkeys_controller_concern.rb +++ b/lib/devise/passkeys/controllers/passkeys_controller_concern.rb @@ -11,12 +11,12 @@ module PasskeysControllerConcern include Devise::Passkeys::Controllers::Concerns::ReauthenticationChallenge include Warden::WebAuthn::AuthenticationInitiationHelpers include Warden::WebAuthn::RegistrationHelpers - include Warden::WebAuthn::StrategyHelpers prepend_before_action :authenticate_scope! before_action :ensure_at_least_one_passkey, only: %i[new_destroy_challenge destroy] before_action :find_passkey, only: %i[new_destroy_challenge destroy] + before_action :verify_credential_integrity, only: [:create] before_action :verify_passkey_challenge, only: [:create] before_action :verify_reauthentication_token, only: %i[create destroy] @@ -93,18 +93,17 @@ def user_details_for_registration { id: resource.webauthn_id, name: resource.email } end + def verify_credential_integrity + return render_credential_missing_or_could_not_be_parsed_error if parsed_credential.nil? + rescue JSON::JSONError, TypeError + return render_credential_missing_or_could_not_be_parsed_error + end + def verify_passkey_challenge - if parsed_credential.nil? - render json: { message: find_message(:credential_missing_or_could_not_be_parsed) }, status: :bad_request - delete_registration_challenge - return false - end - begin - @webauthn_credential = verify_registration(relying_party: relying_party) - rescue ::WebAuthn::Error => e - error_key = Warden::WebAuthn::ErrorKeyFinder.webauthn_error_key(exception: e) - render json: { message: find_message(error_key) }, status: :bad_request - end + @webauthn_credential = verify_registration(relying_party: relying_party) + rescue ::WebAuthn::Error => e + error_key = Warden::WebAuthn::ErrorKeyFinder.webauthn_error_key(exception: e) + render json: { message: find_message(error_key) }, status: :bad_request end def passkey_params @@ -134,6 +133,12 @@ def verify_reauthentication_token def reauthentication_params params.require(:passkey).permit(:reauthentication_token) end + + def render_credential_missing_or_could_not_be_parsed_error + render json: { message: find_message(:credential_missing_or_could_not_be_parsed) }, status: :bad_request + delete_registration_challenge + return false + end end end end diff --git a/lib/devise/passkeys/controllers/reauthentication_controller_concern.rb b/lib/devise/passkeys/controllers/reauthentication_controller_concern.rb index 8d1aed7..c67a28d 100644 --- a/lib/devise/passkeys/controllers/reauthentication_controller_concern.rb +++ b/lib/devise/passkeys/controllers/reauthentication_controller_concern.rb @@ -10,7 +10,7 @@ module ReauthenticationControllerConcern include Devise::Passkeys::Controllers::Concerns::Reauthentication include Devise::Passkeys::Controllers::Concerns::ReauthenticationChallenge include Warden::WebAuthn::AuthenticationInitiationHelpers - include Warden::WebAuthn::StrategyHelpers + include Warden::WebAuthn::RackHelpers prepend_before_action :authenticate_scope! @@ -69,7 +69,7 @@ def delete_reauthentication_challenge session.delete(passkey_reauthentication_challenge_session_key) end - def set_relying_party_in_request_env + def relying_party raise "need to define relying_party for this SessionsController" end end diff --git a/lib/devise/passkeys/controllers/sessions_controller_concern.rb b/lib/devise/passkeys/controllers/sessions_controller_concern.rb index 9f4e5ed..7e62c05 100644 --- a/lib/devise/passkeys/controllers/sessions_controller_concern.rb +++ b/lib/devise/passkeys/controllers/sessions_controller_concern.rb @@ -8,7 +8,7 @@ module SessionsControllerConcern included do include Warden::WebAuthn::AuthenticationInitiationHelpers - include Warden::WebAuthn::StrategyHelpers + include Warden::WebAuthn::RackHelpers # Prepending is crucial to ensure that the relying party is set in the # request.env before the strategy is executed @@ -29,7 +29,7 @@ def new_challenge protected - def set_relying_party_in_request_env + def relying_party raise "need to define relying_party for this SessionsController" end end diff --git a/test/devise/passkeys/controllers/test_passkeys_controller_concern.rb b/test/devise/passkeys/controllers/test_passkeys_controller_concern.rb index 206c5ad..6278f6d 100644 --- a/test/devise/passkeys/controllers/test_passkeys_controller_concern.rb +++ b/test/devise/passkeys/controllers/test_passkeys_controller_concern.rb @@ -18,10 +18,6 @@ def relying_party WebAuthn::RelyingParty.new(origin: "https://www.example.com") end - def set_relying_party_in_request_env - request.env[relying_party_key] = relying_party - end - def resource_name :user end diff --git a/test/devise/passkeys/controllers/test_reauthentication_controller_concern.rb b/test/devise/passkeys/controllers/test_reauthentication_controller_concern.rb index 5f4f98f..5961914 100644 --- a/test/devise/passkeys/controllers/test_reauthentication_controller_concern.rb +++ b/test/devise/passkeys/controllers/test_reauthentication_controller_concern.rb @@ -18,10 +18,6 @@ def relying_party WebAuthn::RelyingParty.new(origin: "https://www.example.com") end - def set_relying_party_in_request_env - request.env[relying_party_key] = relying_party - end - def resource_name :user end diff --git a/test/devise/passkeys/controllers/test_registrations_controller_concern.rb b/test/devise/passkeys/controllers/test_registrations_controller_concern.rb index 8e61ce9..2800a41 100644 --- a/test/devise/passkeys/controllers/test_registrations_controller_concern.rb +++ b/test/devise/passkeys/controllers/test_registrations_controller_concern.rb @@ -16,10 +16,6 @@ def relying_party WebAuthn::RelyingParty.new(origin: "https://www.example.com") end - def set_relying_party_in_request_env - request.env[relying_party_key] = relying_party - end - # Dummy action to setup reauthentication token def reauthenticate store_reauthentication_token_in_session diff --git a/test/devise/passkeys/controllers/test_sessions_controller_concern.rb b/test/devise/passkeys/controllers/test_sessions_controller_concern.rb index c353261..b77e86f 100644 --- a/test/devise/passkeys/controllers/test_sessions_controller_concern.rb +++ b/test/devise/passkeys/controllers/test_sessions_controller_concern.rb @@ -13,10 +13,6 @@ def relying_party WebAuthn::RelyingParty.new(origin: "test.host") end - def set_relying_party_in_request_env - request.env[relying_party_key] = relying_party - end - def resource_name :user end @@ -55,10 +51,6 @@ def relying_party WebAuthn::RelyingParty.new(origin: "test.host") end - def set_relying_party_in_request_env - request.env[relying_party_key] = relying_party - end - def resource_name "user" end