Implement Passkey registration

- Create Identity credentials
- Add management UI and registration flow
This commit is contained in:
Stanko K.R.
2026-02-13 16:58:06 +01:00
parent 4bb0a2929c
commit 6c58fd9bdd
16 changed files with 330 additions and 19 deletions
@@ -0,0 +1,71 @@
class Users::CredentialsController < ApplicationController
before_action :set_user
before_action :set_webauthn_host
def index
@credentials = identity.credentials.order(created_at: :desc)
end
def new
@creation_options = creation_options
session[:webauthn_challenge] = @creation_options.challenge
end
def create
public_key_credential = ActionPack::WebAuthn::PublicKeyCredential.create(
client_data_json: decode64(credential_response[:client_data_json]),
attestation_object: decode64(credential_response[:attestation_object]),
challenge: session.delete(:webauthn_challenge),
origin: request.base_url,
transports: Array(credential_response[:transports])
)
identity.credentials.create!(
name: params.dig(:credential, :name),
credential_id: public_key_credential.id,
public_key: public_key_credential.public_key.to_der,
sign_count: public_key_credential.sign_count,
transports: public_key_credential.transports
)
redirect_to user_credentials_path(@user)
end
def destroy
identity.credentials.find(params[:id]).destroy!
redirect_to user_credentials_path(@user)
end
private
def set_user
@user = Current.identity.users.find(params[:user_id])
end
def set_webauthn_host
ActionPack::WebAuthn::Current.host = request.host
end
def identity
@user.identity
end
def creation_options
ActionPack::WebAuthn::PublicKeyCredential::CreationOptions.new(
id: identity.id,
name: identity.email_address,
display_name: @user.name,
resident_key: :required,
exclude_credentials: identity.credentials.map { |c| ExcludeCredential.new(c.credential_id, c.transports) }
)
end
def credential_response
params.expect(credential: { response: [ :client_data_json, :attestation_object, transports: [] ] })[:response]
end
def decode64(value)
Base64.urlsafe_decode64(value)
end
ExcludeCredential = Struct.new(:id, :transports)
end