import SQL from 'sql-template-strings'; import { config as socialLoginConfig } from './social.ts'; import type { Database } from './db.ts'; import type { AuthenticatorRow, UserRow } from './routes/user.ts'; const upsertBanArchive = async (db: Database, type: string, value: string): Promise => { await db.get(SQL`INSERT INTO bans (type, value) VALUES (${type}, ${value}) ON CONFLICT DO NOTHING`); }; const removeBanArchive = async (db: Database, type: string, value: string): Promise => { await db.get(SQL`DELETE FROM bans WHERE type = ${type} AND value = ${value};`); }; const normaliseEmail = (email: string): string => { let [username, domain] = email.split('@'); username = username.replace(/\.+/g, ''); username = username.replace(/\+.*/, ''); return `${username}@${domain}`.toLowerCase(); }; export const archiveBan = async (db: Database, user: Pick) => { for (const auth of await db.all(SQL`SELECT * FROM authenticators WHERE userId = ${user.id}`)) { const p = JSON.parse(auth.payload); if (auth.type === 'email') { await upsertBanArchive(db, 'email', normaliseEmail(p.email)); } else if (socialLoginConfig[auth.type] !== undefined) { await upsertBanArchive(db, auth.type, p.id); if (p.email) { await upsertBanArchive(db, 'email', normaliseEmail(p.email)); } } } }; export const liftBan = async (db: Database, user: Pick): Promise => { for (const auth of await db.all(SQL`SELECT * FROM authenticators WHERE userId = ${user.id}`)) { const p = JSON.parse(auth.payload); if (auth.type === 'email') { await removeBanArchive(db, 'email', normaliseEmail(p.email)); } else if (socialLoginConfig[auth.type] !== undefined) { await removeBanArchive(db, auth.type, p.id); if (p.email) { await removeBanArchive(db, 'email', normaliseEmail(p.email)); } } } }; export const lookupBanArchive = async ( db: Database, type: string, value: { email?: string, id?: string }, ): Promise => { let resultValue; if (type === 'email') { resultValue = normaliseEmail(value.email!); } else { resultValue = value.id; } return (await db.all(SQL`SELECT * FROM bans WHERE type=${type} and value = ${resultValue}`)).length > 0; };