-- 20260126000007_auth_security.up.sql -- 1. Ensure has_completed_onboarding exists (idempotent) ALTER TABLE public.profiles ADD COLUMN IF NOT EXISTS has_completed_onboarding BOOLEAN NOT NULL DEFAULT FALSE; -- 2. Create verification_tokens table CREATE TABLE IF NOT EXISTS public.verification_tokens ( token_hash VARCHAR(64) PRIMARY KEY, user_id UUID NOT NULL REFERENCES public.users(id) ON DELETE CASCADE, expires_at TIMESTAMPTZ NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- 3. Create user_mfa_secrets (TOTP) CREATE TABLE IF NOT EXISTS public.user_mfa_secrets ( user_id UUID PRIMARY KEY REFERENCES public.users(id) ON DELETE CASCADE, secret_key TEXT NOT NULL, recovery_codes TEXT[] NOT NULL DEFAULT '{}', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- 4. Create webauthn_credentials (Passkeys) CREATE TABLE IF NOT EXISTS public.webauthn_credentials ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES public.users(id) ON DELETE CASCADE, credential_id TEXT NOT NULL, -- The base64 URL encoded ID public_key TEXT NOT NULL, -- The public key attestation_type TEXT, aaguid UUID, sign_count INT DEFAULT 0, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), last_used_at TIMESTAMPTZ, CONSTRAINT unique_credential_id UNIQUE (credential_id) );