68 lines
2.2 KiB
SQL
68 lines
2.2 KiB
SQL
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
|
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
username TEXT UNIQUE NOT NULL,
|
|
client_salt TEXT NOT NULL,
|
|
encrypted_master_key TEXT NOT NULL,
|
|
hashed_auth_key TEXT NOT NULL,
|
|
public_identity_key TEXT NOT NULL,
|
|
public_signing_key TEXT NOT NULL,
|
|
encrypted_private_keys TEXT NOT NULL,
|
|
is_admin BOOLEAN DEFAULT FALSE,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS channels (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
name TEXT UNIQUE NOT NULL,
|
|
type TEXT DEFAULT 'text' CHECK (type IN ('text', 'voice')),
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS roles (
|
|
id SERIAL PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
color TEXT DEFAULT '#99aab5',
|
|
position INTEGER DEFAULT 0,
|
|
permissions JSONB DEFAULT '{}',
|
|
is_hoist BOOLEAN DEFAULT FALSE,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS user_roles (
|
|
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
|
role_id INTEGER REFERENCES roles(id) ON DELETE CASCADE,
|
|
PRIMARY KEY (user_id, role_id)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS channel_keys (
|
|
channel_id UUID NOT NULL,
|
|
user_id UUID NOT NULL,
|
|
encrypted_key_bundle TEXT NOT NULL,
|
|
key_version INTEGER DEFAULT 1,
|
|
PRIMARY KEY (channel_id, user_id)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS messages (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
channel_id UUID NOT NULL,
|
|
sender_id UUID NOT NULL,
|
|
ciphertext TEXT NOT NULL,
|
|
nonce TEXT NOT NULL,
|
|
signature TEXT NOT NULL,
|
|
key_version INTEGER NOT NULL,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS invites (
|
|
code TEXT PRIMARY KEY, -- e.g. "8f1a4c..." (The ID of the invite)
|
|
encrypted_payload TEXT NOT NULL, -- The AES-Encrypted Key Bundle (Server can't read this)
|
|
created_by UUID REFERENCES users(id) ON DELETE CASCADE,
|
|
max_uses INTEGER DEFAULT NULL, -- NULL = Infinite
|
|
uses INTEGER DEFAULT 0,
|
|
expires_at TIMESTAMPTZ DEFAULT NULL, -- NULL = Never
|
|
key_version INTEGER NOT NULL, -- Which key version is inside? (So we can invalidate leaks)
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|