Module: Unmagic::Passkeys::FormHelper

Defined in:
lib/unmagic/passkeys/form_helper.rb

Overview

View helpers for rendering passkey registration and sign-in buttons.

Constant Summary collapse

REGISTRATION_ERROR_MESSAGE =
"Something went wrong while registering your passkey."
REGISTRATION_CANCELLED_MESSAGE =
"Passkey registration was cancelled. Try again when you are ready."
REGISTRATION_DUPLICATE_MESSAGE =
"You already have a passkey registered on this device. Remove the existing one first and try again."
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."

Instance Method Summary collapse

Instance Method Details

#passkey_registration_button(name = nil, url = nil, **options, &block) ⇒ Object

Renders a button for registering a new passkey. Accepts a label string or a block for button content.

Options:

  • options: WebAuthn creation options (JSON-serializable hash)

  • challenge_url: endpoint to refresh the challenge nonce

  • wrapper: HTML attributes for the outer web component element

  • form: additional HTML attributes for the <form> tag. Supports a :param key to set the form parameter namespace (default: :passkey)

  • error: HTML attributes for the error message <div>. Supports a :message key to override the default error text

  • cancellation: HTML attributes for the cancellation message <div>. Supports a :message key to override the default cancellation text

  • All other options are passed to the <button> tag



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/unmagic/passkeys/form_helper.rb', line 23

def passkey_registration_button(name = nil, url = nil, **options, &block)
  url, name = name, block ? capture(&block) : nil if block_given?
  component_options, form_options, button_options, error_options = partition_passkey_options(url, options)
  error_options[:error][:message] ||= REGISTRATION_ERROR_MESSAGE
  error_options[:cancellation][:message] ||= REGISTRATION_CANCELLED_MESSAGE
  error_options[:duplicate][:message] ||= REGISTRATION_DUPLICATE_MESSAGE
  param = form_options.delete(:param)

  ("unmagic-passkey-registration-button", **component_options.transform_keys { |key| key.to_s.dasherize }) do
    tag.form(**form_options) do
      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}[attestation_object]", nil, id: nil, data: { passkey_field: "attestation_object" }) +
        hidden_field_tag("#{param}[transports][]", nil, id: nil, data: { passkey_field: "transports" }) +
        tag.button(name, type: :button, data: { passkey: "register" }, **button_options)
    end + passkey_error_messages(**error_options)
  end
end

#passkey_sign_in_button(name = nil, url = nil, **options, &block) ⇒ Object

Renders a button for signing in with a passkey. Accepts a label string or a block for button content.

Options:

  • options: WebAuthn request options (JSON-serializable hash)

  • challenge_url: endpoint to refresh the challenge nonce

  • mediation: WebAuthn mediation hint (e.g. “conditional” for autofill-assisted sign in)

  • wrapper: HTML attributes for the outer web component element

  • form: additional HTML attributes for the <form> tag. Supports a :param key to set the form parameter namespace (default: :passkey)

  • error: HTML attributes for the error message <div>. Supports a :message key to override the default error text

  • cancellation: HTML attributes for the cancellation message <div>. Supports a :message key to override the default cancellation text

  • All other options are passed to the <button> tag



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/unmagic/passkeys/form_helper.rb', line 57

def (name = nil, url = nil, **options, &block)
  url, name = name, block ? capture(&block) : nil if block_given?
  component_options, form_options, button_options, error_options = partition_passkey_options(url, options)
  error_options[:error][:message] ||= SIGN_IN_ERROR_MESSAGE
  error_options[:cancellation][:message] ||= SIGN_IN_CANCELLED_MESSAGE
  param = form_options.delete(:param)

  ("unmagic-passkey-sign-in-button", **component_options.transform_keys { |key| key.to_s.dasherize }) do
    tag.form(**form_options) do
      hidden_field_tag(:authenticity_token, form_authenticity_token) +
        hidden_field_tag("#{param}[id]", nil, id: nil, data: { passkey_field: "id" }) +
        hidden_field_tag("#{param}[client_data_json]", nil, id: nil, data: { passkey_field: "client_data_json" }) +
        hidden_field_tag("#{param}[authenticator_data]", nil, id: nil, data: { passkey_field: "authenticator_data" }) +
        hidden_field_tag("#{param}[signature]", nil, id: nil, data: { passkey_field: "signature" }) +
        tag.button(name, type: :button, data: { passkey: "sign_in" }, **button_options)
    end + passkey_error_messages(**error_options)
  end
end