Rename create_options to registration_options
This commit is contained in:
@@ -5,11 +5,11 @@ class My::PasskeysController < ApplicationController
|
|||||||
|
|
||||||
def index
|
def index
|
||||||
@passkeys = Current.identity.passkeys.order(name: :asc, created_at: :desc)
|
@passkeys = Current.identity.passkeys.order(name: :asc, created_at: :desc)
|
||||||
@creation_options = passkey_creation_options(holder: Current.identity)
|
@registration_options = passkey_registration_options(holder: Current.identity)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
passkey = Current.identity.passkeys.register(passkey_creation_params)
|
passkey = Current.identity.passkeys.register(passkey_registration_params)
|
||||||
|
|
||||||
redirect_to edit_my_passkey_path(passkey, created: true)
|
redirect_to edit_my_passkey_path(passkey, created: true)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Web components for the ActionPack::Passkey Ruby helpers.
|
// Web components for the ActionPack::Passkey Ruby helpers.
|
||||||
//
|
//
|
||||||
// <rails-passkey-creation-button> — wraps a registration ceremony form
|
// <rails-passkey-registration-button> — wraps a registration ceremony form
|
||||||
// <rails-passkey-sign-in-button> — wraps an authentication ceremony form
|
// <rails-passkey-sign-in-button> — wraps an authentication ceremony form
|
||||||
//
|
//
|
||||||
// The Ruby form helpers render the component markup including the inner form,
|
// The Ruby form helpers render the component markup including the inner form,
|
||||||
@@ -92,13 +92,13 @@ class PasskeyButton extends HTMLElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PasskeyCreationButton extends PasskeyButton {
|
class PasskeyRegistrationButton extends PasskeyButton {
|
||||||
async perform(options) {
|
async perform(options) {
|
||||||
return await register(options)
|
return await register(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
fillForm(passkey) {
|
fillForm(passkey) {
|
||||||
fillCreateForm(this.form, passkey)
|
fillRegistrationForm(this.form, passkey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ class PasskeySignInButton extends PasskeyButton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("rails-passkey-creation-button", PasskeyCreationButton)
|
customElements.define("rails-passkey-registration-button", PasskeyRegistrationButton)
|
||||||
customElements.define("rails-passkey-sign-in-button", PasskeySignInButton)
|
customElements.define("rails-passkey-sign-in-button", PasskeySignInButton)
|
||||||
|
|
||||||
// -- Shared helpers ----------------------------------------------------------
|
// -- Shared helpers ----------------------------------------------------------
|
||||||
@@ -176,7 +176,7 @@ async function refreshChallenge(options, challengeUrl) {
|
|||||||
options.challenge = challenge
|
options.challenge = challenge
|
||||||
}
|
}
|
||||||
|
|
||||||
function fillCreateForm(form, passkey) {
|
function fillRegistrationForm(form, passkey) {
|
||||||
form.querySelector('[data-passkey-field="client_data_json"]').value = passkey.client_data_json
|
form.querySelector('[data-passkey-field="client_data_json"]').value = passkey.client_data_json
|
||||||
form.querySelector('[data-passkey-field="attestation_object"]').value = passkey.attestation_object
|
form.querySelector('[data-passkey-field="attestation_object"]').value = passkey.attestation_object
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<%= passkey_creation_button my_passkeys_path, options: @creation_options, error: { class: "txt-negative" }, cancellation: { class: "txt-subtle" }, class: "btn btn--link center txt-medium" do %>
|
<%= passkey_registration_button my_passkeys_path, options: @registration_options, error: { class: "txt-negative" }, cancellation: { class: "txt-subtle" }, class: "btn btn--link center txt-medium" do %>
|
||||||
<%= icon_tag "add" %>
|
<%= icon_tag "add" %>
|
||||||
<span>Register a passkey</span>
|
<span>Register a passkey</span>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
# Generate options for the browser's +navigator.credentials.create()+ call, then register the
|
# Generate options for the browser's +navigator.credentials.create()+ call, then register the
|
||||||
# response:
|
# response:
|
||||||
#
|
#
|
||||||
# options = ActionPack::Passkey.creation_options(holder: current_user)
|
# options = ActionPack::Passkey.registration_options(holder: current_user)
|
||||||
# # Pass options to the browser
|
# # Pass options to the browser
|
||||||
#
|
#
|
||||||
# passkey = ActionPack::Passkey.register(params[:passkey], holder: current_user)
|
# passkey = ActionPack::Passkey.register(params[:passkey], holder: current_user)
|
||||||
@@ -35,12 +35,12 @@ class ActionPack::Passkey < Rails.configuration.action_pack.passkey.parent_class
|
|||||||
class << self
|
class << self
|
||||||
# Returns a CreationOptions object for the given +holder+, suitable for passing to the
|
# Returns a CreationOptions object for the given +holder+, suitable for passing to the
|
||||||
# browser's +navigator.credentials.create()+ call. Merges global defaults from the Rails
|
# browser's +navigator.credentials.create()+ call. Merges global defaults from the Rails
|
||||||
# configuration, holder-specific options from +holder.passkey_creation_options+, and any
|
# configuration, holder-specific options from +holder.passkey_registration_options+, and any
|
||||||
# additional +options+ overrides.
|
# additional +options+ overrides.
|
||||||
def creation_options(holder:, **options)
|
def registration_options(holder:, **options)
|
||||||
ActionPack::WebAuthn::PublicKeyCredential.creation_options(
|
ActionPack::WebAuthn::PublicKeyCredential.creation_options(
|
||||||
**Rails.configuration.action_pack.web_authn.default_creation_options.to_h,
|
**Rails.configuration.action_pack.web_authn.default_creation_options.to_h,
|
||||||
**holder.passkey_creation_options.to_h,
|
**holder.passkey_registration_options.to_h,
|
||||||
**options
|
**options
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,17 +2,17 @@
|
|||||||
#
|
#
|
||||||
# Include this module in your helper or ApplicationHelper to get access to:
|
# Include this module in your helper or ApplicationHelper to get access to:
|
||||||
#
|
#
|
||||||
# - +passkey_creation_button+ — render a <rails-passkey-creation-button> web component with
|
# - +passkey_registration_button+ — render a <rails-passkey-registration-button> web component with
|
||||||
# a form, hidden fields, and error messages for the registration ceremony.
|
# a form, hidden fields, and error messages for the registration ceremony.
|
||||||
# - +passkey_sign_in_button+ — render a <rails-passkey-sign-in-button> web component with
|
# - +passkey_sign_in_button+ — render a <rails-passkey-sign-in-button> web component with
|
||||||
# a form, hidden fields, and error messages for the authentication ceremony.
|
# a form, hidden fields, and error messages for the authentication ceremony.
|
||||||
module ActionPack::Passkey::FormHelper
|
module ActionPack::Passkey::FormHelper
|
||||||
CREATION_ERROR_MESSAGE = "Something went wrong while registering your passkey."
|
REGISTRATION_ERROR_MESSAGE = "Something went wrong while registering your passkey."
|
||||||
CREATION_CANCELLED_MESSAGE = "Passkey registration was cancelled. Try again when you are ready."
|
REGISTRATION_CANCELLED_MESSAGE = "Passkey registration was cancelled. Try again when you are ready."
|
||||||
SIGN_IN_ERROR_MESSAGE = "Something went wrong while signing in with your passkey."
|
SIGN_IN_ERROR_MESSAGE = "Something went wrong while signing in with your passkey."
|
||||||
SIGN_IN_CANCELLED_MESSAGE = "Passkey sign in was cancelled. Try again when you are ready."
|
SIGN_IN_CANCELLED_MESSAGE = "Passkey sign in was cancelled. Try again when you are ready."
|
||||||
|
|
||||||
# Renders a +<rails-passkey-creation-button>+ web component containing a form with hidden
|
# Renders a +<rails-passkey-registration-button>+ web component containing a form with hidden
|
||||||
# fields for the passkey registration ceremony and error messages. The form POSTs to +url+ and
|
# fields for the passkey registration ceremony and error messages. The form POSTs to +url+ and
|
||||||
# includes hidden fields for +client_data_json+, +attestation_object+, and +transports+ —
|
# includes hidden fields for +client_data_json+, +attestation_object+, and +transports+ —
|
||||||
# populated by the web component after the browser credential API resolves.
|
# populated by the web component after the browser credential API resolves.
|
||||||
@@ -28,20 +28,20 @@ module ActionPack::Passkey::FormHelper
|
|||||||
# - +cancellation+: HTML attributes for the cancellation message +<div>+. Supports a
|
# - +cancellation+: HTML attributes for the cancellation message +<div>+. Supports a
|
||||||
# +:message+ key to override the default cancellation text
|
# +:message+ key to override the default cancellation text
|
||||||
# - All other options are passed to the +<button>+ tag
|
# - All other options are passed to the +<button>+ tag
|
||||||
def passkey_creation_button(name = nil, url = nil, **options, &block)
|
def passkey_registration_button(name = nil, url = nil, **options, &block)
|
||||||
url, name = name, block ? capture(&block) : nil if block_given?
|
url, name = name, block ? capture(&block) : nil if block_given?
|
||||||
component_options, form_options, button_options, error_options = extract_passkey_component_options(url, options)
|
component_options, form_options, button_options, error_options = extract_passkey_component_options(url, options)
|
||||||
error_options[:error][:message] ||= CREATION_ERROR_MESSAGE
|
error_options[:error][:message] ||= REGISTRATION_ERROR_MESSAGE
|
||||||
error_options[:cancellation][:message] ||= CREATION_CANCELLED_MESSAGE
|
error_options[:cancellation][:message] ||= REGISTRATION_CANCELLED_MESSAGE
|
||||||
param = form_options.delete(:param)
|
param = form_options.delete(:param)
|
||||||
|
|
||||||
content_tag("rails-passkey-creation-button", **component_options.transform_keys { |key| key.to_s.dasherize }) do
|
content_tag("rails-passkey-registration-button", **component_options.transform_keys { |key| key.to_s.dasherize }) do
|
||||||
tag.form(**form_options) do
|
tag.form(**form_options) do
|
||||||
hidden_field_tag(:authenticity_token, form_authenticity_token) +
|
hidden_field_tag(:authenticity_token, form_authenticity_token) +
|
||||||
hidden_field_tag("#{param}[client_data_json]", nil, id: nil, data: { passkey_field: "client_data_json" }) +
|
hidden_field_tag("#{param}[client_data_json]", nil, id: nil, data: { passkey_field: "client_data_json" }) +
|
||||||
hidden_field_tag("#{param}[attestation_object]", nil, id: nil, data: { passkey_field: "attestation_object" }) +
|
hidden_field_tag("#{param}[attestation_object]", nil, id: nil, data: { passkey_field: "attestation_object" }) +
|
||||||
hidden_field_tag("#{param}[transports][]", nil, id: nil, data: { passkey_field: "transports" }) +
|
hidden_field_tag("#{param}[transports][]", nil, id: nil, data: { passkey_field: "transports" }) +
|
||||||
tag.button(name, type: :button, data: { passkey: "create" }, **button_options)
|
tag.button(name, type: :button, data: { passkey: "register" }, **button_options)
|
||||||
end + passkey_error_messages(**error_options)
|
end + passkey_error_messages(**error_options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
# This sets up a polymorphic +has_many :passkeys+ association and defines two methods on the
|
# This sets up a polymorphic +has_many :passkeys+ association and defines two methods on the
|
||||||
# model that supply holder-specific options for the WebAuthn ceremonies:
|
# model that supply holder-specific options for the WebAuthn ceremonies:
|
||||||
#
|
#
|
||||||
# - +passkey_creation_options+ — merged into ActionPack::Passkey.creation_options
|
# - +passkey_registration_options+ — merged into ActionPack::Passkey.registration_options
|
||||||
# - +passkey_request_options+ — merged into ActionPack::Passkey.request_options
|
# - +passkey_request_options+ — merged into ActionPack::Passkey.request_options
|
||||||
#
|
#
|
||||||
# == Options
|
# == Options
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
# For more complex configuration, pass a block that receives a ActionPack::Passkey::Holder::Config:
|
# For more complex configuration, pass a block that receives a ActionPack::Passkey::Holder::Config:
|
||||||
#
|
#
|
||||||
# has_passkeys do |config|
|
# has_passkeys do |config|
|
||||||
# config.creation_options { { name: email, display_name: name } }
|
# config.registration_options { { name: email, display_name: name } }
|
||||||
# config.request_options { { user_verification: "required" } }
|
# config.request_options { { user_verification: "required" } }
|
||||||
# end
|
# end
|
||||||
module ActionPack::Passkey::Holder
|
module ActionPack::Passkey::Holder
|
||||||
@@ -39,7 +39,7 @@ module ActionPack::Passkey::Holder
|
|||||||
|
|
||||||
class_methods do
|
class_methods do
|
||||||
# Declares that this model can hold passkeys. Sets up a polymorphic +has_many+ association
|
# Declares that this model can hold passkeys. Sets up a polymorphic +has_many+ association
|
||||||
# and defines +passkey_creation_options+ and +passkey_request_options+ instance methods used
|
# and defines +passkey_registration_options+ and +passkey_request_options+ instance methods used
|
||||||
# by ActionPack::Passkey to build ceremony options.
|
# by ActionPack::Passkey to build ceremony options.
|
||||||
#
|
#
|
||||||
# Keyword arguments matching CreationOptions or RequestOptions fields are extracted and
|
# Keyword arguments matching CreationOptions or RequestOptions fields are extracted and
|
||||||
@@ -54,11 +54,11 @@ module ActionPack::Passkey::Holder
|
|||||||
dependent: config.dependent,
|
dependent: config.dependent,
|
||||||
class_name: "ActionPack::Passkey"
|
class_name: "ActionPack::Passkey"
|
||||||
|
|
||||||
define_method(:passkey_creation_options) do
|
define_method(:passkey_registration_options) do
|
||||||
{
|
{
|
||||||
id: id,
|
id: id,
|
||||||
exclude_credentials: public_send(config.association_name)
|
exclude_credentials: public_send(config.association_name)
|
||||||
}.merge(config.evaluate_creation_options(self))
|
}.merge(config.evaluate_registration_options(self))
|
||||||
end
|
end
|
||||||
|
|
||||||
define_method(:passkey_request_options) do
|
define_method(:passkey_request_options) do
|
||||||
@@ -77,7 +77,7 @@ module ActionPack::Passkey::Holder
|
|||||||
@dependent = options.delete(:dependent) || :destroy
|
@dependent = options.delete(:dependent) || :destroy
|
||||||
|
|
||||||
if creation_opts = extract_options_for(ActionPack::WebAuthn::PublicKeyCredential::CreationOptions, options)
|
if creation_opts = extract_options_for(ActionPack::WebAuthn::PublicKeyCredential::CreationOptions, options)
|
||||||
@creation_options = options_to_proc(creation_opts)
|
@registration_options = options_to_proc(creation_opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
if request_opts = extract_options_for(ActionPack::WebAuthn::PublicKeyCredential::RequestOptions, options)
|
if request_opts = extract_options_for(ActionPack::WebAuthn::PublicKeyCredential::RequestOptions, options)
|
||||||
@@ -94,9 +94,9 @@ module ActionPack::Passkey::Holder
|
|||||||
|
|
||||||
# Sets a block to evaluate in the holder's context to produce additional creation options.
|
# Sets a block to evaluate in the holder's context to produce additional creation options.
|
||||||
#
|
#
|
||||||
# config.creation_options { { name: email, display_name: name } }
|
# config.registration_options { { name: email, display_name: name } }
|
||||||
def creation_options(&block)
|
def registration_options(&block)
|
||||||
@creation_options = block
|
@registration_options = block
|
||||||
end
|
end
|
||||||
|
|
||||||
# Evaluates the request options block (if any) in the context of the given +record+. Called
|
# Evaluates the request options block (if any) in the context of the given +record+. Called
|
||||||
@@ -110,10 +110,10 @@ module ActionPack::Passkey::Holder
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Evaluates the creation options block (if any) in the context of the given +record+. Called
|
# Evaluates the creation options block (if any) in the context of the given +record+. Called
|
||||||
# internally by the +passkey_creation_options+ method defined on the holder.
|
# internally by the +passkey_registration_options+ method defined on the holder.
|
||||||
def evaluate_creation_options(record)
|
def evaluate_registration_options(record)
|
||||||
if @creation_options
|
if @registration_options
|
||||||
record.instance_exec(&@creation_options)
|
record.instance_exec(&@registration_options)
|
||||||
else
|
else
|
||||||
{}
|
{}
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -10,12 +10,12 @@
|
|||||||
# include ActionPack::Passkey::Request
|
# include ActionPack::Passkey::Request
|
||||||
#
|
#
|
||||||
# def new
|
# def new
|
||||||
# @creation_options = passkey_creation_options(holder: Current.user)
|
# @registration_options = passkey_registration_options(holder: Current.user)
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# def create
|
# def create
|
||||||
# @passkey = ActionPack::Passkey.register(
|
# @passkey = ActionPack::Passkey.register(
|
||||||
# passkey_creation_params, holder: Current.user
|
# passkey_registration_params, holder: Current.user
|
||||||
# )
|
# )
|
||||||
# redirect_to settings_path
|
# redirect_to settings_path
|
||||||
# end
|
# end
|
||||||
@@ -56,7 +56,7 @@ module ActionPack::Passkey::Request
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Returns strong parameters for the passkey registration ceremony.
|
# Returns strong parameters for the passkey registration ceremony.
|
||||||
def passkey_creation_params(param: :passkey)
|
def passkey_registration_params(param: :passkey)
|
||||||
params.expect(param => [ :client_data_json, :attestation_object, transports: [] ])
|
params.expect(param => [ :client_data_json, :attestation_object, transports: [] ])
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -70,8 +70,8 @@ module ActionPack::Passkey::Request
|
|||||||
ActionPack::Passkey.request_options(**options)
|
ActionPack::Passkey.request_options(**options)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns CreationOptions for the registration ceremony.
|
# Returns RegistrationOptions for the registration ceremony.
|
||||||
def passkey_creation_options(**options)
|
def passkey_registration_options(**options)
|
||||||
ActionPack::Passkey.creation_options(**options)
|
ActionPack::Passkey.registration_options(**options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user