init
This commit is contained in:
91
lib/email.ts
Normal file
91
lib/email.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
const DISPOSABLE_EMAIL_DOMAINS = [
|
||||
'tempmail.com',
|
||||
'throwawaymail.com',
|
||||
'tempmail100.com'
|
||||
];
|
||||
|
||||
export type EmailValidationError =
|
||||
| 'invalid_email_format'
|
||||
| 'email_part_too_long'
|
||||
| 'disposable_email_not_allowed'
|
||||
| 'invalid_characters';
|
||||
|
||||
const EMAIL_REGEX = /^(?=[a-zA-Z0-9@._%+-]{6,254}$)[a-zA-Z0-9._%+-]{1,64}@(?:[a-zA-Z0-9-]{1,63}\.){1,8}[a-zA-Z]{2,63}$/;
|
||||
|
||||
export function validateEmail(email: string): {
|
||||
isValid: boolean;
|
||||
error?: string;
|
||||
} {
|
||||
// validate email format
|
||||
if (!EMAIL_REGEX.test(email)) {
|
||||
return {
|
||||
isValid: false,
|
||||
error: 'invalid_email_format'
|
||||
};
|
||||
}
|
||||
|
||||
// check domain length
|
||||
const [localPart, domain] = email.split('@');
|
||||
if (domain.length > 255 || localPart.length > 64) {
|
||||
return {
|
||||
isValid: false,
|
||||
error: 'email_part_too_long'
|
||||
};
|
||||
}
|
||||
|
||||
// check if it's a disposable email
|
||||
if (DISPOSABLE_EMAIL_DOMAINS.includes(domain.toLowerCase())) {
|
||||
return {
|
||||
isValid: false,
|
||||
error: 'disposable_email_not_allowed'
|
||||
};
|
||||
}
|
||||
|
||||
// check for special characters
|
||||
if (/[<>()[\]\\.,;:\s@"]+/.test(localPart)) {
|
||||
return {
|
||||
isValid: false,
|
||||
error: 'invalid_characters'
|
||||
};
|
||||
}
|
||||
|
||||
return { isValid: true };
|
||||
}
|
||||
|
||||
// email validation (including alias detection)
|
||||
export function normalizeEmail(email: string): string {
|
||||
if (!email) return '';
|
||||
|
||||
// convert to lowercase
|
||||
let normalizedEmail = email.toLowerCase();
|
||||
|
||||
// separate email local part and domain part
|
||||
const [localPart, domain] = normalizedEmail.split('@');
|
||||
|
||||
// handle different email service provider alias rules
|
||||
switch (domain) {
|
||||
case 'gmail.com':
|
||||
// remove dot and + suffix
|
||||
const gmailBase = localPart
|
||||
.replace(/\./g, '')
|
||||
.split('+')[0];
|
||||
return `${gmailBase}@${domain}`;
|
||||
|
||||
case 'outlook.com':
|
||||
case 'hotmail.com':
|
||||
case 'live.com':
|
||||
// remove + suffix
|
||||
const microsoftBase = localPart.split('+')[0];
|
||||
return `${microsoftBase}@${domain}`;
|
||||
|
||||
case 'yahoo.com':
|
||||
// remove - suffix
|
||||
const yahooBase = localPart.split('-')[0];
|
||||
return `${yahooBase}@${domain}`;
|
||||
|
||||
default:
|
||||
// for other emails, only remove + suffix
|
||||
const baseLocalPart = localPart.split('+')[0];
|
||||
return `${baseLocalPart}@${domain}`;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user