Module: Passkeyed::Model
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/passkeyed/model.rb,
sig/passkeyed/model.rbs
Overview
Mix into the model that owns passkeys (typically your User):
class User < ApplicationRecord
include Passkeyed::Model
end
It wires up the credentials association and assigns the random WebAuthn
user handle (+webauthn_id+) on create. The host table needs a
webauthn_id:string column (the install generator adds it).
Instance Method Summary collapse
- #assign_passkeyed_webauthn_id ⇒ void
- #ensure_webauthn_id_column! ⇒ void
-
#passkey_display_name ⇒ String
The human-friendly display name (WebAuthn's user.displayName) shown by account pickers, distinct from
passkey_name(the account identifier). -
#passkey_name ⇒ String
The name passed to the authenticator at registration time.
-
#passkeyed_webauthn_id! ⇒ String
Return this record's WebAuthn user handle, assigning one when absent.
-
#rename_passkey(credential_id, nickname) ⇒ Object
Rename one of this owner's passkeys (e.g. from a credential-management UI).
-
#revoke_passkey(credential_id) ⇒ Object
Revoke (delete) one of this owner's passkeys.
Instance Method Details
#assign_passkeyed_webauthn_id ⇒ void
This method returns an undefined value.
85 86 87 88 |
# File 'lib/passkeyed/model.rb', line 85 def assign_passkeyed_webauthn_id ensure_webauthn_id_column! self.webauthn_id ||= WebAuthn.generate_user_id end |
#ensure_webauthn_id_column! ⇒ void
This method returns an undefined value.
90 91 92 93 94 95 96 |
# File 'lib/passkeyed/model.rb', line 90 def ensure_webauthn_id_column! return if self.class.column_names.include?("webauthn_id") raise Passkeyed::ConfigurationError, "#{self.class.name} has no webauthn_id column; run the passkeyed install migration " \ "(bin/rails generate passkeyed:install && bin/rails db:migrate)" end |
#passkey_display_name ⇒ String
The human-friendly display name (WebAuthn's user.displayName) shown by
account pickers, distinct from passkey_name (the account identifier).
Defaults to passkey_name; override to show e.g. a full name next to an
email.
41 42 43 |
# File 'lib/passkeyed/model.rb', line 41 def passkey_display_name passkey_name end |
#passkey_name ⇒ String
The name passed to the authenticator at registration time. Prefers an
email, then a name, falling back to the opaque handle. Override in
your model if you want something else shown.
30 31 32 33 34 35 |
# File 'lib/passkeyed/model.rb', line 30 def passkey_name return email if respond_to?(:email) && email.present? return name if respond_to?(:name) && name.present? passkeyed_webauthn_id! end |
#passkeyed_webauthn_id! ⇒ String
Return this record's WebAuthn user handle, assigning one when absent.
before_create only covers rows created after the gem is installed, so a
pre-existing user (or one whose backfill was missed) would otherwise reach
the ceremony with a nil handle, which webauthn-ruby drops from the options
JSON and the browser then rejects. Persists the handle when the record is
already saved; assigns it in memory otherwise (the before_create keeps
it for an unsaved record). Raises if the webauthn_id column is missing.
73 74 75 76 77 78 79 80 81 |
# File 'lib/passkeyed/model.rb', line 73 def passkeyed_webauthn_id! ensure_webauthn_id_column! return webauthn_id if webauthn_id.present? handle = WebAuthn.generate_user_id self.webauthn_id = handle update_column(:webauthn_id, handle) if persisted? handle end |
#rename_passkey(credential_id, nickname) ⇒ Object
Rename one of this owner's passkeys (e.g. from a credential-management UI). Looked up through the association, so an id belonging to another owner raises ActiveRecord::RecordNotFound rather than letting one user relabel another's credential. A blank nickname clears the label. Returns the credential.
50 51 52 53 54 |
# File 'lib/passkeyed/model.rb', line 50 def rename_passkey(credential_id, nickname) credential = passkeyed_credentials.find(credential_id) credential.update!(nickname: nickname.presence) credential end |
#revoke_passkey(credential_id) ⇒ Object
Revoke (delete) one of this owner's passkeys. Scoped through the
association like rename_passkey. Returns the destroyed credential; raises
ActiveRecord::RecordNotFound if the id isn't this owner's.
This does not stop a user removing their last passkey — guard against that in your app if it would lock the account out.
62 63 64 |
# File 'lib/passkeyed/model.rb', line 62 def revoke_passkey(credential_id) passkeyed_credentials.find(credential_id).destroy! end |