feat(admin): accept domain entries in the email blocklist (#3129)

This commit is contained in:
Hampus authored and GitHub committed 2026-10-02 18:00:38 +02:00
1 parent b54016653b
commit 1abde06824
8 files changed
+106 -15

No files matched your search

+23 -5
View File
@@ -46,6 +46,20 @@ const IS_EMAIL_BANNED_QUERY = BannedEmails.select({
where: BannedEmails.where.eq('email_lower'),
});
const LOAD_ALL_BANNED_EMAILS_QUERY = BannedEmails.select();
function getEmailBlocklistKeys(email: string): Array<string> {
const emailLower = email.trim().toLowerCase();
const atIndex = emailLower.lastIndexOf('@');
if (atIndex <= 0) {
return [emailLower];
}
const labels = emailLower.slice(atIndex + 1).split('.');
const keys = [emailLower];
for (let index = 0; index < labels.length - 1; index++) {
keys.push(`@${labels.slice(index).join('.')}`);
}
return keys;
}
const IS_PHRASE_BANNED_QUERY = BannedPhrases.select({
where: BannedPhrases.where.eq('phrase'),
});
@@ -224,11 +238,15 @@ export class AdminRepository implements IAdminRepository {
}
async isEmailBanned(email: string): Promise<boolean> {
const emailLower = email.toLowerCase();
const result = await fetchOne<{
email_lower: string;
}>(IS_EMAIL_BANNED_QUERY.bind({email_lower: emailLower}));
return !!result;
for (const key of getEmailBlocklistKeys(email)) {
const result = await fetchOne<{
email_lower: string;
}>(IS_EMAIL_BANNED_QUERY.bind({email_lower: key}));
if (result) {
return true;
}
}
return false;
}
async banEmail(email: string): Promise<void> {
@@ -67,7 +67,8 @@ const BLOCKLIST_CATALOG = [
},
{
list_type: 'email' as const,
description: 'Email addresses that cannot be used to register or be set on an account.',
description:
'Email addresses that cannot be used to register or be set on an account. An entry written as @example.com covers every address at that domain and its subdomains.',
value_field: 'email',
fields: [],
scoped: false,