-- v0.13.3: F022 WebAuthn Credentials + F025 GeoIP on login_history + F016 Password expiration -- Up migration -- F022: WebAuthn credentials — stores FIDO2 passkeys per user CREATE TABLE IF NOT EXISTS webauthn_credentials ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, credential_id BYTEA NOT NULL UNIQUE, public_key BYTEA NOT NULL, attestation_type VARCHAR(50) NOT NULL DEFAULT 'none', aaguid BYTEA, sign_count BIGINT NOT NULL DEFAULT 0, name VARCHAR(100) NOT NULL DEFAULT 'My Passkey', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), last_used_at TIMESTAMPTZ ); CREATE INDEX IF NOT EXISTS idx_webauthn_user_id ON webauthn_credentials(user_id); CREATE INDEX IF NOT EXISTS idx_webauthn_credential_id ON webauthn_credentials(credential_id); -- F025: Add geolocation columns to login_history ALTER TABLE login_history ADD COLUMN IF NOT EXISTS country VARCHAR(2) DEFAULT ''; ALTER TABLE login_history ADD COLUMN IF NOT EXISTS city VARCHAR(100) DEFAULT ''; -- F016: Add password_changed_at to users for expiration tracking ALTER TABLE users ADD COLUMN IF NOT EXISTS password_changed_at TIMESTAMPTZ; -- Backfill: set password_changed_at = updated_at for existing users with passwords UPDATE users SET password_changed_at = updated_at WHERE password_hash != '' AND password_changed_at IS NULL;