Class: PasskeySessionsController

Inherits:
ApplicationController
  • Object
show all
Defined in:
lib/generators/ruby_cms/templates/controllers/passkey_sessions_controller.rb

Instance Method Summary collapse

Instance Method Details

#createObject

POST /passkey_sessions — verify the assertion and start a session.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/generators/ruby_cms/templates/controllers/passkey_sessions_controller.rb', line 16

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

  webauthn_credential = WebAuthn::Credential.from_get(raw)
  stored = PasskeyCredential.find_by!(external_id: webauthn_credential.id)
  challenge = session.delete(:passkey_authentication_challenge)

  verify_assertion(webauthn_credential, stored, challenge)
  apply_sign_count(webauthn_credential, stored)
  stored.update!(last_used_at: Time.current)

  start_new_session_for(stored.user)
  render json: { ok: true, redirect: after_authentication_url }
rescue ActiveRecord::RecordNotFound, ActiveRecord::RecordInvalid, WebAuthn::Error, ArgumentError, TypeError => e
  Rails.logger.warn("[passkey] authentication failed: #{e.class}: #{e.message}")
  render json: { error: "Authentication failed" }, status: :unprocessable_entity
end

#newObject

POST /passkey_sessions/new — issue usernameless (discoverable) request options.



9
10
11
12
13
# File 'lib/generators/ruby_cms/templates/controllers/passkey_sessions_controller.rb', line 9

def new
  get_options = WebAuthn::Credential.options_for_get(user_verification: "preferred")
  session[:passkey_authentication_challenge] = get_options.challenge
  render json: get_options
end