-- Password reset tokens + JWT credential invalidation (see auth_api, auth_credential_middleware). -- Apply: docker exec -i initiative-postgres psql -U initiative -d initiatives < be0/migrations/012_password_reset.sql ALTER TABLE users ADD COLUMN IF NOT EXISTS credential_version INTEGER NOT NULL DEFAULT 0; COMMENT ON COLUMN users.credential_version IS 'Incremented on password change/reset. JWT ''cv'' claim must match or token is rejected.'; CREATE TABLE IF NOT EXISTS password_reset_tokens ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, token_hash TEXT NOT NULL UNIQUE, expires_at TIMESTAMPTZ NOT NULL, used_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_password_reset_tokens_user_id ON password_reset_tokens(user_id); CREATE INDEX IF NOT EXISTS idx_password_reset_tokens_expires_at ON password_reset_tokens(expires_at);