Class: Unmagic::Passkeys::Credential
- Inherits:
-
Object
- Object
- Unmagic::Passkeys::Credential
- Defined in:
- app/models/unmagic/passkeys/credential.rb
Overview
Unmagic::Passkeys::Credential provides WebAuthn passkey registration and authentication backed by Active Record.
Passkeys are scoped to a polymorphic holder (typically a User or Identity) and store the credential ID, public key, sign count, and transport hints needed for the WebAuthn ceremonies.
Registration
Generate options for the browser’s navigator.credentials.create() call, then register the response:
= Unmagic::Passkeys::Credential.(holder: current_user)
# Pass options to the browser
passkey = Unmagic::Passkeys::Credential.register(params[:passkey], holder: current_user)
Authentication
Generate options for the browser’s navigator.credentials.get() call, then authenticate the response:
= Unmagic::Passkeys::Credential.
# Pass options to the browser
passkey = Unmagic::Passkeys::Credential.authenticate(params[:passkey])
Holder integration
Call has_passkeys in your model to set up the association and configure ceremony options per-holder. See Unmagic::Passkeys::Holder for details.
Class Method Summary collapse
-
.authenticate(passkey) ⇒ Object
Looks up a passkey by credential ID and verifies the assertion response from the browser.
-
.authentication_options(holder: nil, **options) ⇒ Object
Returns a RequestOptions object suitable for passing to the browser’s navigator.credentials.get() call.
-
.register(passkey, **attributes) ⇒ Object
Verifies the attestation response from the browser and persists a new passkey record.
-
.registration_options(holder:, **options) ⇒ Object
Returns a CreationOptions object for the given
holder, suitable for passing to the browser’s navigator.credentials.create() call.
Instance Method Summary collapse
-
#authenticate(passkey) ⇒ Object
Verifies the assertion response against this passkey’s stored credential and updates the
sign_countandbacked_upattributes. -
#to_public_key_credential ⇒ Object
Returns an Unmagic::Passkeys::WebAuthn::PublicKeyCredential initialized from this record’s stored credential data.
Class Method Details
.authenticate(passkey) ⇒ Object
Looks up a passkey by credential ID and verifies the assertion response from the browser. Returns the authenticated Passkey record, or nil if the credential is not found or verification fails.
76 77 78 |
# File 'app/models/unmagic/passkeys/credential.rb', line 76 def authenticate(passkey) find_by(credential_id: passkey[:id])&.authenticate(passkey) end |
.authentication_options(holder: nil, **options) ⇒ Object
Returns a RequestOptions object suitable for passing to the browser’s navigator.credentials.get() call. When a holder is provided, their existing credentials are included so the browser can offer them for selection. Merges global defaults, holder options, and any additional options overrides.
65 66 67 68 69 70 71 |
# File 'app/models/unmagic/passkeys/credential.rb', line 65 def (holder: nil, **) Unmagic::Passkeys::WebAuthn::PublicKeyCredential.( **Rails.configuration.unmagic_passkeys.web_authn..to_h, **holder&..to_h, ** ) end |
.register(passkey, **attributes) ⇒ Object
Verifies the attestation response from the browser and persists a new passkey record. The passkey hash should contain client_data_json, attestation_object, and transports as submitted by the registration form. The challenge is extracted from the authenticator’s clientDataJSON response and verified server-side. Any additional attributes (e.g. holder) are passed through to create!.
Raises Unmagic::Passkeys::WebAuthn::InvalidResponseError if the attestation is invalid.
55 56 57 58 59 |
# File 'app/models/unmagic/passkeys/credential.rb', line 55 def register(passkey, **attributes) credential = Unmagic::Passkeys::WebAuthn::PublicKeyCredential.register(passkey) create!(**credential.to_h, **attributes) end |
.registration_options(holder:, **options) ⇒ Object
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 configuration, holder-specific options from holder.passkey_registration_options, and any additional options overrides.
40 41 42 43 44 45 46 |
# File 'app/models/unmagic/passkeys/credential.rb', line 40 def (holder:, **) Unmagic::Passkeys::WebAuthn::PublicKeyCredential.( **Rails.configuration.unmagic_passkeys.web_authn..to_h, **holder..to_h, ** ) end |
Instance Method Details
#authenticate(passkey) ⇒ Object
Verifies the assertion response against this passkey’s stored credential and updates the sign_count and backed_up attributes. Returns self on success, or nil if the response is invalid.
84 85 86 87 88 89 90 91 |
# File 'app/models/unmagic/passkeys/credential.rb', line 84 def authenticate(passkey) credential = to_public_key_credential credential.authenticate(passkey) update!(sign_count: credential.sign_count, backed_up: credential.backed_up) self rescue Unmagic::Passkeys::WebAuthn::InvalidResponseError nil end |
#to_public_key_credential ⇒ Object
Returns an Unmagic::Passkeys::WebAuthn::PublicKeyCredential initialized from this record’s stored credential data.
95 96 97 98 99 100 101 102 |
# File 'app/models/unmagic/passkeys/credential.rb', line 95 def to_public_key_credential Unmagic::Passkeys::WebAuthn::PublicKeyCredential.new( id: credential_id, public_key: public_key, sign_count: sign_count, transports: transports ) end |