@synotech/utils
Version:
a collection of utilities for internal use
145 lines (129 loc) • 3.29 kB
text/typescript
import tlds from './assets/tlds';
import { Resolver } from 'node:dns';
const resolver = new Resolver();
resolver.setServers(['8.8.8.8']);
const dnsResolver = (domain: string): Promise<boolean> => {
return new Promise((resolve) => {
resolver.resolveMx(domain, (err, addresses) => {
try {
if (err || !addresses || addresses.length === 0) {
console.trace(err);
resolve(false);
} else {
addresses.sort((a, b) => a.priority - b.priority);
const priorityRecord = addresses[0];
if (!priorityRecord.exchange) resolve(false);
resolver.resolve(priorityRecord.exchange, (err) => {
if (err) {
console.trace(err);
resolve(false);
} else {
resolve(true);
}
});
}
} catch (error) {
console.trace(error);
resolve(false);
}
});
});
};
/**
* This method validates email address
* @param {Object} contact
* @param {String} contact.email the email to be validated
* @return {boolean} {Promise<boolean>} a boolean value indicating if the email is valid or not
* @memberof Verymail
* @example
* const isValid = await validateEmail({
* email: 'user@example.com',
* })
*/
export async function validateEmail({
email,
}: {
email: string;
}): Promise<boolean> {
if (!email) {
return false;
}
email = email.toLowerCase();
email = email.replace(/\s/g, '');
const emailPattern =
/^[-!#$%&'*+\/0-9=?A-Z^_a-z`{|}~](\.?[-!#$%&'*+\/0-9=?A-Z^_a-z`{|}~])*@[a-zA-Z0-9](-*\.?[a-zA-Z0-9])*\.[a-zA-Z](-?[a-zA-Z0-9])+$/;
if (!emailPattern.test(email)) {
return false;
}
/**
* Check if the email contains more than 3 numeric characters. If it does, throw an error.
*/
if (email && (email.match(/\./g)?.length ?? 0) > 3) {
return false;
}
/**
* Validate TLD
*/
const tld = (email: any) => email.split('@')[1].split('.').pop();
if (!tlds.includes(tld(email))) {
return false;
}
/**
* remove email modifier
*/
const atIndex = email.indexOf('@');
const plusIndex = email.indexOf('+');
if (
plusIndex !== -1 &&
plusIndex < atIndex &&
process.env.NODE_ENV === 'production'
) {
email = email.slice(0, plusIndex) + email.slice(atIndex);
}
const [username, domain] = email.split('@');
if (username.length < 3) {
return false;
}
if (/^\d+$/.test(username)) {
return false;
}
return dnsResolver(domain);
}
/**
* This method validates all supplied email addresses.
* @param {Array} mailingList array of email objects to be verified
* @returns {Array} object consisting of valid and invalid email addresses { valid: [], invalid: [] }
* @memberof Verymail
* @example
* const { data } = await validateEmailBulk(
* {
* email: 'user1@example.com',
* },
* {
* email: 'user2@example.com',
* },
* ])
*
*/
export async function validateEmailBulk(mailingList: any[]) {
try {
let i;
let ValidEmailList: any[] = [];
let InValidEmailList: any[] = [];
for (i in mailingList) {
if (mailingList.hasOwnProperty(i)) {
if (await validateEmail({ email: mailingList[i].email })) {
ValidEmailList.push(mailingList[i]);
} else {
InValidEmailList.push(mailingList[i]);
}
}
}
return {
valid: ValidEmailList,
invalid: InValidEmailList,
};
} catch (error) {
return { data: [] };
}
}