62 lines
2.4 KiB
TypeScript

import SQL from 'sql-template-strings';
import type { Database } from './db.ts';
import type { AuthenticatorRow, UserRow } from './express/user.ts';
import { config as socialLoginConfig } from './social.ts';
const upsertBanArchive = async (db: Database, type: string, value: string): Promise<void> => {
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<void> => {
await db.get(SQL`DELETE FROM bans WHERE type = ${type} AND value = ${value};`);
};
const normaliseEmail = (email: string): string => {
const [username, domain] = email.split('@');
return `${username.replace(/\.+/g, '').replace(/\+.*/, '')}@${domain}`.toLowerCase();
};
export const archiveBan = async (db: Database, user: Pick<UserRow, 'id'>) => {
for (const auth of await db.all<AuthenticatorRow>(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<UserRow, 'id'>): Promise<void> => {
for (const auth of await db.all<AuthenticatorRow>(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<boolean> => {
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;
};