diff --git a/CHANGELOG.md b/CHANGELOG.md index f4116822..f4f03e88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - Options for getting or creating passkeys and security keys are now served by dedicated Rails controllers and retrieved via JavaScript fetch requests. [#73](https://github.com/cedarcode/devise-webauthn/pull/73) [@nicolastemciuc] +### Fixed + +- Fix form helpers (`passkey_creation_form_for`, `login_with_passkey_button`, `security_key_creation_form_for`, `login_with_security_key_button`) to accept a `resource_name` instead of requiring the `resource` object from the view context. [#114](https://github.com/cedarcode/devise-webauthn/pull/114) [@RenzoMinelli] + ## [v0.3.0](https://github.com/cedarcode/devise-webauthn/compare/v0.2.2...v0.3.0/) - 2026-01-16 ### Added diff --git a/README.md b/README.md index bd16c107..cc2c5ae1 100644 --- a/README.md +++ b/README.md @@ -145,16 +145,18 @@ $ bin/rails generate devise:webauthn:views -v passkeys ``` ### Helper methods -Devise::Webauthn provides helpers that can be used in your views. For example, for a resource named `user`, you can use the following helpers: +Devise::Webauthn provides helpers that can be used in your views. These helpers accept either a resource name (e.g., `:user`) or a resource object (e.g., `@user`) as the first argument. + +For example, for a resource named `user`, you can use the following helpers: To add a button for logging in with passkeys: ```erb -<%= login_with_passkey_button("Log in with passkeys", session_path: user_session_path) %> +<%= login_with_passkey_button_for(:user, "Log in with passkeys") %> ``` To add a passkeys creation form: ```erb -<%= passkey_creation_form_for(current_user) do |form| %> +<%= passkey_creation_form_for(:user) do |form| %> <%= form.label :name, 'Passkey name' %> <%= form.text_field :name, required: true %> <%= form.submit 'Create Passkey' %> diff --git a/app/views/devise/passkeys/new.html.erb b/app/views/devise/passkeys/new.html.erb index 029017cc..df7c877b 100644 --- a/app/views/devise/passkeys/new.html.erb +++ b/app/views/devise/passkeys/new.html.erb @@ -1,4 +1,4 @@ -<%= passkey_creation_form_for(resource) do |form| %> +<%= passkey_creation_form_for(resource_name) do |form| %> <%= form.label :name, 'Passkey name' %> <%= form.text_field :name, required: true %> <%= form.submit 'Create Passkey' %> diff --git a/app/views/devise/second_factor_webauthn_credentials/new.html.erb b/app/views/devise/second_factor_webauthn_credentials/new.html.erb index 2b91472f..f41a93c5 100644 --- a/app/views/devise/second_factor_webauthn_credentials/new.html.erb +++ b/app/views/devise/second_factor_webauthn_credentials/new.html.erb @@ -1,4 +1,4 @@ -<%= security_key_creation_form_for(resource) do |form| %> +<%= security_key_creation_form_for(resource_name) do |form| %> <%= form.label :name, 'Security Key name' %> <%= form.text_field :name, required: true %> <%= form.submit 'Create Security Key' %> diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb index e0ab91cc..f0178eed 100644 --- a/app/views/devise/sessions/new.html.erb +++ b/app/views/devise/sessions/new.html.erb @@ -23,6 +23,6 @@ <% end %> -<%= login_with_passkey_button("Log in with passkeys", session_path: session_path(resource_name)) %> +<%= login_with_passkey_button_for(resource_name, "Log in with passkeys") %> <%= render "devise/shared/links" %> diff --git a/app/views/devise/two_factor_authentications/new.html.erb b/app/views/devise/two_factor_authentications/new.html.erb index 5fc58a5f..af02ad81 100644 --- a/app/views/devise/two_factor_authentications/new.html.erb +++ b/app/views/devise/two_factor_authentications/new.html.erb @@ -1 +1 @@ -<%= login_with_security_key_button('Use security key', resource: @resource) %> +<%= login_with_security_key_button_for(resource_name, 'Use security key') %> diff --git a/lib/devise/webauthn/helpers/credentials_helper.rb b/lib/devise/webauthn/helpers/credentials_helper.rb index 2173263a..a1acf3e5 100644 --- a/lib/devise/webauthn/helpers/credentials_helper.rb +++ b/lib/devise/webauthn/helpers/credentials_helper.rb @@ -4,26 +4,27 @@ module Devise module Webauthn module CredentialsHelper - def passkey_creation_form_for(resource, form_classes: nil, &block) + def passkey_creation_form_for(resource_or_resource_name, form_classes: nil, &block) form_with( - url: passkeys_path(resource), + url: passkeys_path(resource_or_resource_name), method: :post, class: form_classes ) do |f| - tag.webauthn_create(data: { options_url: passkey_registration_options_path(resource) }) do + tag.webauthn_create(data: { options_url: passkey_registration_options_path(resource_or_resource_name) }) do concat f.hidden_field(:public_key_credential, data: { webauthn_target: "response" }) concat capture(f, &block) end end end - def login_with_passkey_button(text = nil, session_path:, button_classes: nil, form_classes: nil, &block) + def login_with_passkey_button_for(resource_or_resource_name, text = nil, button_classes: nil, + form_classes: nil, &block) form_with( - url: session_path, + url: session_path(resource_or_resource_name), method: :post, class: form_classes ) do |f| - tag.webauthn_get(data: { options_url: passkey_authentication_options_path(resource) }) do + tag.webauthn_get(data: { options_url: passkey_authentication_options_path(resource_or_resource_name) }) do concat f.hidden_field(:public_key_credential, data: { webauthn_target: "response" }) concat f.button(text, type: "submit", class: button_classes, &block) @@ -31,14 +32,14 @@ def login_with_passkey_button(text = nil, session_path:, button_classes: nil, fo end end - def security_key_creation_form_for(resource, form_classes: nil, &block) + def security_key_creation_form_for(resource_or_resource_name, form_classes: nil, &block) form_with( - url: second_factor_webauthn_credentials_path(resource), + url: second_factor_webauthn_credentials_path(resource_or_resource_name), method: :post, class: form_classes ) do |f| tag.webauthn_create( - data: { options_url: security_key_registration_options_path(resource) } + data: { options_url: security_key_registration_options_path(resource_or_resource_name) } ) do concat f.hidden_field(:public_key_credential, data: { webauthn_target: "response" }) concat capture(f, &block) @@ -46,13 +47,16 @@ def security_key_creation_form_for(resource, form_classes: nil, &block) end end - def login_with_security_key_button(text = nil, resource:, button_classes: nil, form_classes: nil, &block) + def login_with_security_key_button_for(resource_or_resource_name, text = nil, button_classes: nil, + form_classes: nil, &block) form_with( - url: two_factor_authentication_path(resource), + url: two_factor_authentication_path(resource_or_resource_name), method: :post, class: form_classes ) do |f| - tag.webauthn_get(data: { options_url: security_key_authentication_options_path(resource) }) do + tag.webauthn_get(data: { + options_url: security_key_authentication_options_path(resource_or_resource_name) + }) do concat f.hidden_field(:public_key_credential, data: { webauthn_target: "response" }) concat f.button(text, type: "submit", class: button_classes, &block) end