mirror of
https://github.com/lukevella/rallly.git
synced 2025-05-01 19:26:30 +02:00
🔒️ Block temporary inboxes (#1602)
This commit is contained in:
parent
cf9ab1b265
commit
35c3d0bb4f
4 changed files with 86 additions and 1 deletions
|
@ -30,6 +30,7 @@
|
||||||
"editVotes": "Edit votes",
|
"editVotes": "Edit votes",
|
||||||
"email": "Email",
|
"email": "Email",
|
||||||
"emailNotAllowed": "This email is not allowed.",
|
"emailNotAllowed": "This email is not allowed.",
|
||||||
|
"temporaryEmailNotAllowed": "Temporary or disposable email addresses are not allowed.",
|
||||||
"emailPlaceholder": "jessie.smith@example.com",
|
"emailPlaceholder": "jessie.smith@example.com",
|
||||||
"exportToCsv": "Export to CSV",
|
"exportToCsv": "Export to CSV",
|
||||||
"guest": "Guest",
|
"guest": "Guest",
|
||||||
|
|
|
@ -51,6 +51,14 @@ export function RegisterNameForm() {
|
||||||
message: t("emailNotAllowed"),
|
message: t("emailNotAllowed"),
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case "temporaryEmailNotAllowed":
|
||||||
|
form.setError("email", {
|
||||||
|
message: t("temporaryEmailNotAllowed", {
|
||||||
|
defaultValue:
|
||||||
|
"Temporary or disposable email addresses are not allowed.",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
break;
|
||||||
case "userAlreadyExists":
|
case "userAlreadyExists":
|
||||||
form.setError("email", {
|
form.setError("email", {
|
||||||
message: t("userAlreadyExists"),
|
message: t("userAlreadyExists"),
|
||||||
|
|
65
apps/web/src/auth/helpers/temp-email-domains.ts
Normal file
65
apps/web/src/auth/helpers/temp-email-domains.ts
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
// List of common temporary/disposable email domains
|
||||||
|
export const temporaryEmailDomains = [
|
||||||
|
"10minutemail.com",
|
||||||
|
"temp-mail.org",
|
||||||
|
"fakeinbox.com",
|
||||||
|
"tempinbox.com",
|
||||||
|
"mailinator.com",
|
||||||
|
"guerrillamail.com",
|
||||||
|
"guerrillamail.net",
|
||||||
|
"guerrillamail.org",
|
||||||
|
"sharklasers.com",
|
||||||
|
"grr.la",
|
||||||
|
"yopmail.com",
|
||||||
|
"yopmail.fr",
|
||||||
|
"yopmail.net",
|
||||||
|
"cool.fr.nf",
|
||||||
|
"jetable.org",
|
||||||
|
"nospam.ze.tc",
|
||||||
|
"nomail.xl.cx",
|
||||||
|
"mega.zik.dj",
|
||||||
|
"speed.1s.fr",
|
||||||
|
"courriel.fr.nf",
|
||||||
|
"moncourrier.fr.nf",
|
||||||
|
"monemail.fr.nf",
|
||||||
|
"monmail.fr.nf",
|
||||||
|
"tempr.email",
|
||||||
|
"discard.email",
|
||||||
|
"discardmail.com",
|
||||||
|
"throwawaymail.com",
|
||||||
|
"trashmail.com",
|
||||||
|
"mailnesia.com",
|
||||||
|
"mailnull.com",
|
||||||
|
"maildrop.cc",
|
||||||
|
"getairmail.com",
|
||||||
|
"getnada.com",
|
||||||
|
"emailondeck.com",
|
||||||
|
"emailfake.com",
|
||||||
|
"mohmal.com",
|
||||||
|
"tempmail.ninja",
|
||||||
|
"temp-mail.io",
|
||||||
|
"disposable-email.com",
|
||||||
|
"tempmailaddress.com",
|
||||||
|
"tempail.com",
|
||||||
|
"tempemail.co",
|
||||||
|
"tempmail.plus",
|
||||||
|
"burnermail.io",
|
||||||
|
"spamgourmet.com",
|
||||||
|
"mytemp.email",
|
||||||
|
"incognitomail.com",
|
||||||
|
"mintemail.com",
|
||||||
|
"tempmailo.com",
|
||||||
|
"temporary-mail.net",
|
||||||
|
"mailto.plus",
|
||||||
|
"ethereal.mail",
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if an email domain is a known temporary/disposable email service
|
||||||
|
*/
|
||||||
|
export const isTemporaryEmail = (email: string): boolean => {
|
||||||
|
const domain = email.split("@")[1]?.toLowerCase();
|
||||||
|
if (!domain) return false;
|
||||||
|
|
||||||
|
return temporaryEmailDomains.includes(domain);
|
||||||
|
};
|
|
@ -6,6 +6,7 @@ import { z } from "zod";
|
||||||
|
|
||||||
import { isEmailBlocked } from "@/auth/helpers/is-email-blocked";
|
import { isEmailBlocked } from "@/auth/helpers/is-email-blocked";
|
||||||
import { mergeGuestsIntoUser } from "@/auth/helpers/merge-user";
|
import { mergeGuestsIntoUser } from "@/auth/helpers/merge-user";
|
||||||
|
import { isTemporaryEmail } from "@/auth/helpers/temp-email-domains";
|
||||||
import { getEmailClient } from "@/utils/emails";
|
import { getEmailClient } from "@/utils/emails";
|
||||||
import { createToken, decryptToken } from "@/utils/session";
|
import { createToken, decryptToken } from "@/utils/session";
|
||||||
|
|
||||||
|
@ -42,12 +43,22 @@ export const auth = router({
|
||||||
ctx,
|
ctx,
|
||||||
}): Promise<
|
}): Promise<
|
||||||
| { ok: true; token: string }
|
| { ok: true; token: string }
|
||||||
| { ok: false; reason: "userAlreadyExists" | "emailNotAllowed" }
|
| {
|
||||||
|
ok: false;
|
||||||
|
reason:
|
||||||
|
| "userAlreadyExists"
|
||||||
|
| "emailNotAllowed"
|
||||||
|
| "temporaryEmailNotAllowed";
|
||||||
|
}
|
||||||
> => {
|
> => {
|
||||||
if (isEmailBlocked?.(input.email)) {
|
if (isEmailBlocked?.(input.email)) {
|
||||||
return { ok: false, reason: "emailNotAllowed" };
|
return { ok: false, reason: "emailNotAllowed" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isTemporaryEmail(input.email)) {
|
||||||
|
return { ok: false, reason: "temporaryEmailNotAllowed" };
|
||||||
|
}
|
||||||
|
|
||||||
const user = await prisma.user.findUnique({
|
const user = await prisma.user.findUnique({
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
|
|
Loading…
Add table
Reference in a new issue