59 lines
2.1 KiB
PL/PgSQL
59 lines
2.1 KiB
PL/PgSQL
-- Phase 1: auth foundation
|
|
-- Requires Postgres. citext for case-insensitive email; pgcrypto for gen_random_uuid.
|
|
CREATE EXTENSION IF NOT EXISTS citext;
|
|
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
|
|
|
CREATE TABLE users (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
email CITEXT NOT NULL UNIQUE,
|
|
password_hash TEXT NOT NULL,
|
|
display_name TEXT,
|
|
email_verified BOOLEAN NOT NULL DEFAULT FALSE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
-- One row per user; created on registration.
|
|
CREATE TABLE user_settings (
|
|
user_id UUID PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
|
locale TEXT NOT NULL DEFAULT 'de', -- 'de' | 'en'
|
|
currency TEXT NOT NULL DEFAULT 'EUR',
|
|
theme TEXT NOT NULL DEFAULT 'breakcore',
|
|
notify_email BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
-- Email verification + password reset tokens.
|
|
-- Only the SHA-256 hash of the token is stored; raw token lives in the emailed link.
|
|
CREATE TYPE token_purpose AS ENUM ('verify_email', 'password_reset');
|
|
|
|
CREATE TABLE auth_tokens (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
token_hash BYTEA NOT NULL UNIQUE,
|
|
purpose token_purpose NOT NULL,
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
consumed_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX idx_auth_tokens_user ON auth_tokens(user_id);
|
|
CREATE INDEX idx_auth_tokens_expires ON auth_tokens(expires_at);
|
|
|
|
-- Touch updated_at on row changes.
|
|
CREATE OR REPLACE FUNCTION set_updated_at() RETURNS trigger AS $$
|
|
BEGIN
|
|
NEW.updated_at = now();
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
CREATE TRIGGER trg_users_updated
|
|
BEFORE UPDATE ON users
|
|
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
|
|
|
CREATE TRIGGER trg_user_settings_updated
|
|
BEFORE UPDATE ON user_settings
|
|
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|