91 lines
3.0 KiB
SQL
91 lines
3.0 KiB
SQL
CREATE TABLE IF NOT EXISTS sessions (
|
|
id TEXT PRIMARY KEY,
|
|
user_id TEXT NOT NULL,
|
|
token_hash TEXT NOT NULL UNIQUE,
|
|
created_at TEXT NOT NULL,
|
|
expires_at TEXT NOT NULL,
|
|
last_seen_at TEXT,
|
|
revoked_at TEXT,
|
|
ip_address TEXT,
|
|
user_agent TEXT,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_sessions_token_hash ON sessions(token_hash);
|
|
CREATE INDEX IF NOT EXISTS idx_sessions_user ON sessions(user_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS webauthn_credentials (
|
|
id TEXT PRIMARY KEY,
|
|
user_id TEXT NOT NULL,
|
|
credential_id BLOB NOT NULL UNIQUE,
|
|
credential_json TEXT NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
last_used_at TEXT,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_webauthn_credentials_user ON webauthn_credentials(user_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS auth_challenges (
|
|
id TEXT PRIMARY KEY,
|
|
user_id TEXT NOT NULL,
|
|
type TEXT NOT NULL CHECK(type IN ('webauthn_registration', 'webauthn_login')),
|
|
session_json TEXT NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
expires_at TEXT NOT NULL,
|
|
used_at TEXT,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_auth_challenges_user_type ON auth_challenges(user_id, type);
|
|
|
|
CREATE TABLE IF NOT EXISTS device_codes (
|
|
id TEXT PRIMARY KEY,
|
|
user_id TEXT,
|
|
device_code_hash TEXT NOT NULL UNIQUE,
|
|
user_code_hash TEXT NOT NULL UNIQUE,
|
|
user_code_display TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
scopes TEXT NOT NULL,
|
|
status TEXT NOT NULL CHECK(status IN ('pending', 'approved', 'denied', 'expired')),
|
|
created_at TEXT NOT NULL,
|
|
expires_at TEXT NOT NULL,
|
|
approved_at TEXT,
|
|
last_polled_at TEXT,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE SET NULL
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_device_codes_user_code_hash ON device_codes(user_code_hash);
|
|
CREATE INDEX IF NOT EXISTS idx_device_codes_device_code_hash ON device_codes(device_code_hash);
|
|
|
|
CREATE TABLE IF NOT EXISTS permissions (
|
|
id TEXT PRIMARY KEY,
|
|
user_id TEXT NOT NULL,
|
|
resource_type TEXT NOT NULL CHECK(resource_type IN ('global', 'collection', 'document')),
|
|
resource_id TEXT,
|
|
permission TEXT NOT NULL CHECK(permission IN ('read', 'write', 'admin')),
|
|
granted_by TEXT,
|
|
created_at TEXT NOT NULL,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(granted_by) REFERENCES users(id) ON DELETE SET NULL
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_permissions_user ON permissions(user_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS audit_log (
|
|
id TEXT PRIMARY KEY,
|
|
actor_user_id TEXT,
|
|
event_type TEXT NOT NULL,
|
|
resource_type TEXT,
|
|
resource_id TEXT,
|
|
ip_address TEXT,
|
|
user_agent TEXT,
|
|
created_at TEXT NOT NULL,
|
|
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
FOREIGN KEY(actor_user_id) REFERENCES users(id) ON DELETE SET NULL
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_audit_log_created_at ON audit_log(created_at);
|
|
|
|
ALTER TABLE api_keys ADD COLUMN revoked_at TEXT;
|