Raw
 1ALTER TABLE audit_log ADD COLUMN address TEXT
 2    CHECK (
 3        address IS NULL
 4        OR (length(address) BETWEEN 2 AND 45 AND address NOT GLOB '*[^0-9a-f.:]*')
 5    );
 6
 7CREATE INDEX audit_log_address_idx ON audit_log(address, occurred_at DESC, id DESC);
 8
 9CREATE TABLE reset_links (
10    user_id TEXT PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
11    token_hash BLOB NOT NULL UNIQUE CHECK (length(token_hash) = 32),
12    created_by TEXT REFERENCES users(id) ON DELETE SET NULL,
13    created_at INTEGER NOT NULL,
14    expires_at INTEGER NOT NULL,
15    CHECK (expires_at > created_at)
16) STRICT;
17
18ALTER TABLE invitations ADD COLUMN label TEXT NOT NULL DEFAULT ''
19    CHECK (length(CAST(label AS BLOB)) <= 128);
20ALTER TABLE invitations ADD COLUMN batch_id TEXT
21    CHECK (batch_id IS NULL OR length(batch_id) = 36);
22
23CREATE INDEX invitations_batch_id_idx ON invitations(batch_id) WHERE batch_id IS NOT NULL;
24
25CREATE TABLE invitation_groups (
26    invitation_id TEXT NOT NULL REFERENCES invitations(id) ON DELETE CASCADE,
27    group_id TEXT REFERENCES groups(id) ON DELETE SET NULL,
28    group_name TEXT NOT NULL
29        CHECK (
30            length(group_name) BETWEEN 1 AND 32
31            AND group_name = lower(group_name)
32            AND substr(group_name, 1, 1) GLOB '[a-z0-9]'
33            AND group_name NOT GLOB '*[^a-z0-9_-]*'
34        ),
35    PRIMARY KEY (invitation_id, group_name)
36) STRICT;
37
38CREATE INDEX invitation_groups_group_id_idx ON invitation_groups(group_id);
39
40CREATE TABLE pending_confirmations (
41    user_id TEXT PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
42    code_hash BLOB NOT NULL CHECK (length(code_hash) = 32),
43    issued_at INTEGER NOT NULL,
44    expires_at INTEGER NOT NULL,
45    wrong_codes INTEGER NOT NULL DEFAULT 0 CHECK (wrong_codes >= 0),
46    CHECK (expires_at > issued_at)
47) STRICT;
48
49CREATE TRIGGER pending_confirmations_need_disabled
50BEFORE INSERT ON pending_confirmations
51WHEN (SELECT disabled FROM users WHERE id = NEW.user_id) IS NOT 1
52BEGIN
53    SELECT RAISE(ABORT, 'a pending account must be disabled');
54END;
55
56CREATE TRIGGER users_pending_stays_disabled
57BEFORE UPDATE OF disabled ON users
58WHEN NEW.disabled = 0 AND EXISTS (SELECT 1 FROM pending_confirmations WHERE user_id = NEW.id)
59BEGIN
60    SELECT RAISE(ABORT, 'a pending account is activated only by its confirmation');
61END;