From d3e512a1c752dd078450827efd2a5eaece8309ce Mon Sep 17 00:00:00 2001 From: Renzo Minelli Date: Sun, 1 Feb 2026 17:13:54 -0300 Subject: [PATCH 1/5] use resource_name instead of resource object --- lib/devise/webauthn/helpers/credentials_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/devise/webauthn/helpers/credentials_helper.rb b/lib/devise/webauthn/helpers/credentials_helper.rb index 2173263a..a858ed0d 100644 --- a/lib/devise/webauthn/helpers/credentials_helper.rb +++ b/lib/devise/webauthn/helpers/credentials_helper.rb @@ -23,7 +23,7 @@ def login_with_passkey_button(text = nil, session_path:, button_classes: nil, fo 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_name) }) do concat f.hidden_field(:public_key_credential, data: { webauthn_target: "response" }) concat f.button(text, type: "submit", class: button_classes, &block) From 8573aa94345e3d178535e41263f018a4629ca2b7 Mon Sep 17 00:00:00 2001 From: Renzo Minelli Date: Thu, 5 Feb 2026 11:05:11 -0300 Subject: [PATCH 2/5] send resource name always --- README.md | 4 ++-- app/views/devise/passkeys/new.html.erb | 2 +- .../new.html.erb | 2 +- app/views/devise/sessions/new.html.erb | 2 +- .../two_factor_authentications/new.html.erb | 2 +- .../webauthn/helpers/credentials_helper.rb | 21 ++++++++++--------- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index bd16c107..5a6cbb1f 100644 --- a/README.md +++ b/README.md @@ -149,12 +149,12 @@ Devise::Webauthn provides helpers that can be used in your views. For example, f 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", session_path: user_session_path) %> ``` 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..ff52ff06 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", session_path: session_path(resource_name)) %> <%= 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 a858ed0d..45e438c2 100644 --- a/lib/devise/webauthn/helpers/credentials_helper.rb +++ b/lib/devise/webauthn/helpers/credentials_helper.rb @@ -4,20 +4,21 @@ module Devise module Webauthn module CredentialsHelper - def passkey_creation_form_for(resource, form_classes: nil, &block) + def passkey_creation_form_for(resource_name, form_classes: nil, &block) form_with( - url: passkeys_path(resource), + url: passkeys_path(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_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_name, text = nil, session_path:, button_classes: nil, + form_classes: nil, &block) form_with( url: session_path, method: :post, @@ -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_name, form_classes: nil, &block) form_with( - url: second_factor_webauthn_credentials_path(resource), + url: second_factor_webauthn_credentials_path(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_name) } ) do concat f.hidden_field(:public_key_credential, data: { webauthn_target: "response" }) concat capture(f, &block) @@ -46,13 +47,13 @@ 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_name, text = nil, button_classes: nil, form_classes: nil, &block) form_with( - url: two_factor_authentication_path(resource), + url: two_factor_authentication_path(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_name) }) do concat f.hidden_field(:public_key_credential, data: { webauthn_target: "response" }) concat f.button(text, type: "submit", class: button_classes, &block) end From 79d3e9c29eb34c871c15079da52dc405ac12420b Mon Sep 17 00:00:00 2001 From: Renzo Minelli Date: Fri, 6 Feb 2026 10:56:34 -0300 Subject: [PATCH 3/5] rename param --- README.md | 4 ++- .../webauthn/helpers/credentials_helper.rb | 25 +++++++++++-------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 5a6cbb1f..79e59437 100644 --- a/README.md +++ b/README.md @@ -145,7 +145,9 @@ $ 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 diff --git a/lib/devise/webauthn/helpers/credentials_helper.rb b/lib/devise/webauthn/helpers/credentials_helper.rb index 45e438c2..0ba9b659 100644 --- a/lib/devise/webauthn/helpers/credentials_helper.rb +++ b/lib/devise/webauthn/helpers/credentials_helper.rb @@ -4,27 +4,27 @@ module Devise module Webauthn module CredentialsHelper - def passkey_creation_form_for(resource_name, form_classes: nil, &block) + def passkey_creation_form_for(resource_or_resource_name, form_classes: nil, &block) form_with( - url: passkeys_path(resource_name), + 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_name) }) 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_for(resource_name, text = nil, session_path:, button_classes: nil, + def login_with_passkey_button_for(resource_or_resource_name, text = nil, session_path:, button_classes: nil, form_classes: nil, &block) form_with( url: session_path, method: :post, class: form_classes ) do |f| - tag.webauthn_get(data: { options_url: passkey_authentication_options_path(resource_name) }) 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) @@ -32,14 +32,14 @@ def login_with_passkey_button_for(resource_name, text = nil, session_path:, butt end end - def security_key_creation_form_for(resource_name, 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_name), + 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_name) } + 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) @@ -47,13 +47,16 @@ def security_key_creation_form_for(resource_name, form_classes: nil, &block) end end - def login_with_security_key_button_for(resource_name, text = nil, 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_name), + 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_name) }) 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 From 8de5faf7c1ef6706b10daac68c28b6f99d6b00ae Mon Sep 17 00:00:00 2001 From: Renzo Minelli Date: Fri, 6 Feb 2026 10:59:20 -0300 Subject: [PATCH 4/5] update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) 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 From 31ba5804153239db58eee7d0f9962eaa9823186d Mon Sep 17 00:00:00 2001 From: Renzo Minelli Date: Fri, 6 Feb 2026 17:28:40 -0300 Subject: [PATCH 5/5] calculate session path from resource --- README.md | 2 +- app/views/devise/sessions/new.html.erb | 2 +- lib/devise/webauthn/helpers/credentials_helper.rb | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 79e59437..cc2c5ae1 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,7 @@ 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_for(:user, "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: diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb index ff52ff06..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_for(resource_name, "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/lib/devise/webauthn/helpers/credentials_helper.rb b/lib/devise/webauthn/helpers/credentials_helper.rb index 0ba9b659..a1acf3e5 100644 --- a/lib/devise/webauthn/helpers/credentials_helper.rb +++ b/lib/devise/webauthn/helpers/credentials_helper.rb @@ -17,10 +17,10 @@ def passkey_creation_form_for(resource_or_resource_name, form_classes: nil, &blo end end - def login_with_passkey_button_for(resource_or_resource_name, text = nil, session_path:, button_classes: nil, + 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|