Class: Admin::PasskeyRegistrationsController

Inherits:
ApplicationController show all
Includes:
SudoMode
Defined in:
lib/generators/ruby_cms/templates/controllers/admin/passkey_registrations_controller.rb

Constant Summary

Constants included from SudoMode

SudoMode::SUDO_WINDOW

Instance Method Summary collapse

Methods inherited from ApplicationController

#admin_notifications, cms_page, #current_user_cms

Instance Method Details

#createObject

POST /admin/passkey_registration — verify attestation, store credential.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/generators/ruby_cms/templates/controllers/admin/passkey_registrations_controller.rb', line 27

def create
  raw = params[:credential]
  return render(json: { error: "Missing credential" }, status: :bad_request) if raw.blank?

  webauthn_credential = WebAuthn::Credential.from_create(raw.to_unsafe_h)
  challenge = session.delete(:passkey_registration_challenge)
  webauthn_credential.verify(challenge)

  Current.user.passkey_credentials.create!(
    external_id: webauthn_credential.id,
    public_key: webauthn_credential.public_key,
    sign_count: webauthn_credential.sign_count,
    nickname: params[:nickname].presence || "Passkey",
    transports: Array(params[:transports]).join(","),
    last_used_at: nil
  )
  render json: { ok: true, redirect: admin_user_path(Current.user, tab: "passkeys") }
rescue WebAuthn::Error => e
  render json: { error: e.message }, status: :unprocessable_entity
rescue ArgumentError, JSON::ParserError => e
  render json: { error: "Invalid credential format" }, status: :bad_request
end

#newObject

GET — the "name your passkey + register" page.



11
12
# File 'lib/generators/ruby_cms/templates/controllers/admin/passkey_registrations_controller.rb', line 11

def new
end

#optionsObject

POST /admin/passkey_registration/options — issue WebAuthn creation options.



15
16
17
18
19
20
21
22
23
24
# File 'lib/generators/ruby_cms/templates/controllers/admin/passkey_registrations_controller.rb', line 15

def options
  user = Current.user
  create_options = WebAuthn::Credential.options_for_create(
    user: { id: user.webauthn_id, name: user.email_address, display_name: user.email_address },
    exclude: user.passkey_credentials.pluck(:external_id),
    authenticator_selection: { resident_key: "preferred", user_verification: "preferred" }
  )
  session[:passkey_registration_challenge] = create_options.challenge
  render json: create_options
end