···11+CREATE TABLE user_totp (
22+ did TEXT PRIMARY KEY REFERENCES users(did) ON DELETE CASCADE,
33+ secret_encrypted BYTEA NOT NULL,
44+ encryption_version INTEGER NOT NULL DEFAULT 1,
55+ verified BOOLEAN NOT NULL DEFAULT FALSE,
66+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
77+ last_used TIMESTAMPTZ
88+);
99+1010+CREATE TABLE backup_codes (
1111+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
1212+ did TEXT NOT NULL REFERENCES users(did) ON DELETE CASCADE,
1313+ code_hash TEXT NOT NULL,
1414+ used_at TIMESTAMPTZ,
1515+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
1616+);
1717+CREATE INDEX idx_backup_codes_did ON backup_codes(did);
1818+1919+CREATE TABLE passkeys (
2020+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
2121+ did TEXT NOT NULL REFERENCES users(did) ON DELETE CASCADE,
2222+ credential_id BYTEA NOT NULL UNIQUE,
2323+ public_key BYTEA NOT NULL,
2424+ sign_count INTEGER NOT NULL DEFAULT 0,
2525+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
2626+ last_used TIMESTAMPTZ,
2727+ friendly_name TEXT,
2828+ aaguid BYTEA,
2929+ transports TEXT[]
3030+);
3131+CREATE INDEX idx_passkeys_did ON passkeys(did);
3232+3333+CREATE TABLE webauthn_challenges (
3434+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
3535+ did TEXT NOT NULL,
3636+ challenge BYTEA NOT NULL,
3737+ challenge_type TEXT NOT NULL,
3838+ state_json TEXT NOT NULL,
3939+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
4040+ expires_at TIMESTAMPTZ NOT NULL
4141+);
4242+CREATE INDEX idx_webauthn_challenges_did ON webauthn_challenges(did);
···33pub mod email;
44pub mod invite;
55pub mod meta;
66+pub mod passkeys;
67pub mod password;
78pub mod service_auth;
89pub mod session;
910pub mod signing_key;
1111+pub mod totp;
10121113pub use account_status::{
1214 activate_account, check_account_status, deactivate_account, delete_account,
···1618pub use email::{confirm_email, request_email_update, update_email};
1719pub use invite::{create_invite_code, create_invite_codes, get_account_invite_codes};
1820pub use meta::{describe_server, health, robots_txt};
2121+pub use passkeys::{
2222+ delete_passkey, finish_passkey_registration, has_passkeys_for_user, list_passkeys,
2323+ start_passkey_registration, update_passkey,
2424+};
1925pub use password::{change_password, request_password_reset, reset_password};
2026pub use service_auth::get_service_auth;
2127pub use session::{
···2329 resend_verification, revoke_session,
2430};
2531pub use signing_key::reserve_signing_key;
3232+pub use totp::{
3333+ create_totp_secret, disable_totp, enable_totp, get_totp_status, has_totp_enabled,
3434+ regenerate_backup_codes, verify_totp_or_backup_for_user,
3535+};
···1111pub mod scope_check;
1212pub mod service;
1313pub mod token;
1414+pub mod totp;
1415pub mod verify;
1616+pub mod webauthn;
15171618pub use extractor::{
1719 AuthError, BearerAuth, BearerAuthAdmin, BearerAuthAllowDeactivated, ExtractedToken,