feat: blocklist table with registration check endpoint
- is_blocked BOOLEAN (default true), INET type for IP validation - Indexes on email/username/phone/ip for fast registration checks - POST /api/blocklist/check — checks all fields in one request, returns 403 if blocked - Auto-timestamps on block/unblock, email stored lowercase Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -307,6 +307,34 @@ async function migrate() {
|
||||
)
|
||||
`);
|
||||
|
||||
// blocklist
|
||||
await query(`
|
||||
CREATE TABLE IF NOT EXISTS blocklist (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
is_blocked BOOLEAN NOT NULL DEFAULT true,
|
||||
username TEXT,
|
||||
email TEXT,
|
||||
phone TEXT,
|
||||
ip INET,
|
||||
blocked_at TIMESTAMPTZ,
|
||||
unblocked_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
)
|
||||
`);
|
||||
|
||||
await query(`
|
||||
DROP TRIGGER IF EXISTS blocklist_updated_at ON blocklist;
|
||||
CREATE TRIGGER blocklist_updated_at
|
||||
BEFORE UPDATE ON blocklist
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at()
|
||||
`);
|
||||
|
||||
await query(`CREATE INDEX IF NOT EXISTS blocklist_email_idx ON blocklist (lower(email)) WHERE email IS NOT NULL`);
|
||||
await query(`CREATE INDEX IF NOT EXISTS blocklist_username_idx ON blocklist (lower(username)) WHERE username IS NOT NULL`);
|
||||
await query(`CREATE INDEX IF NOT EXISTS blocklist_phone_idx ON blocklist (phone) WHERE phone IS NOT NULL`);
|
||||
await query(`CREATE INDEX IF NOT EXISTS blocklist_ip_idx ON blocklist (ip) WHERE ip IS NOT NULL`);
|
||||
|
||||
console.log('Migration complete');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user