Skip to content

Commit

Permalink
after some research found out that some subdomains do have mx records…
Browse files Browse the repository at this point in the history
…, this will fall back to root domain if subdomain fails
  • Loading branch information
denish-fearless committed Jan 15, 2025
1 parent 4b5cef8 commit f25bd69
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 28 deletions.
28 changes: 10 additions & 18 deletions backend/src/middleware/emailValidator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ jest.mock('dns');

const mockedDns = dns as jest.Mocked<typeof dns>;

describe('isValidEmail Function', () => {
describe('isValidEmail Function (Full and Root Domain Validation)', () => {

afterEach(() => {
jest.resetAllMocks();
Expand All @@ -16,7 +16,7 @@ describe('isValidEmail Function', () => {
expect(result).toBe(false);
});

test('should return true for a valid email with MX records (full domain)', async () => {
test('should return true for a valid email with MX records on the full domain', async () => {
mockedDns.resolveMx.mockImplementation((domain, callback) => {
if (domain === 'gmail.com') {
callback(null, [{ exchange: 'mail.google.com', priority: 10 }]);
Expand All @@ -29,22 +29,20 @@ describe('isValidEmail Function', () => {
expect(result).toBe(true);
});

test('should return true for a valid email with MX records (root domain fallback)', async () => {
test('should return true for a valid email where MX records exist on the root domain', async () => {
mockedDns.resolveMx.mockImplementation((domain, callback) => {
if (domain === 'subdomain.example.com') {
callback(null, []);
} else if (domain === 'example.com') {
callback(null, [{ exchange: 'mail.example.com', priority: 20 }]);
} else {
callback(null, []);
}
});

const result = await isValidEmail('[email protected]');
expect(result).toBe(true);
});

test('should return false for a valid email but no MX records in either domain', async () => {
test('should return false when neither the full nor root domain has MX records', async () => {
mockedDns.resolveMx.mockImplementation((domain, callback) => {
callback(null, []);
});
Expand All @@ -53,31 +51,25 @@ describe('isValidEmail Function', () => {
expect(result).toBe(false);
});

test('should return false for a domain with an error during MX lookup (full domain)', async () => {
test('should return false when an error occurs during full domain lookup and no MX records exist on root', async () => {
mockedDns.resolveMx.mockImplementation((domain, callback) => {
if (domain === 'fakeexample.com') {
if (domain === 'subdomain.fakeexample.com') {
callback(new Error('Domain not found'), []);
} else {
callback(null, []);
}
});

const result = await isValidEmail('[email protected]');
const result = await isValidEmail('test@subdomain.fakeexample.com');
expect(result).toBe(false);
});

test('should return false for a domain with an error during MX lookup (root domain fallback)', async () => {
test('should return false when an error occurs during both full and root domain lookups', async () => {
mockedDns.resolveMx.mockImplementation((domain, callback) => {
if (domain === 'subdomain.fakeexample.com') {
callback(new Error('Domain not found'), []);
} else if (domain === 'fakeexample.com') {
callback(new Error('Domain not found'), []);
} else {
callback(null, []);
}
callback(new Error('Domain not found'), []);
});

const result = await isValidEmail('test@subdomain.fakeexample.com');
const result = await isValidEmail('test@error.com');
expect(result).toBe(false);
});
});
29 changes: 19 additions & 10 deletions backend/src/middleware/emailValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,30 @@ export const isValidEmail = async (email: string): Promise<boolean> => {
};

const validateDomainMX = (email: string): Promise<boolean> => {
let domain = email.split('@')[1];
const domainParts = domain.split('.')
if(domainParts.length > 2) {
domain = domainParts.slice(-2).join('.')
}
const domain = email.split('@')[1];
const domainParts = domain.split('.');
const rootDomain = domainParts.length > 2 ? domainParts.slice(-2).join('.') : domain; // If subdomain exists

return new Promise((resolve) => {
// Trying full domain first
dns.resolveMx(domain, (err, addresses) => {
if (err || addresses.length === 0) {
console.log(`Invalid domain or no MX records for: ${domain}`);
resolve(false);
} else {
if (!err && addresses.length > 0) {
console.log(`Valid MX records found for ${domain}:`, addresses);
resolve(true);
return resolve(true);
}

// Fallback to root domain if the full domain fails
dns.resolveMx(rootDomain, (rootErr, rootAddresses) => {
if (!rootErr && rootAddresses.length > 0) {
console.log(`Valid MX records found for ${rootDomain}:`, rootAddresses);
resolve(true);
} else {
console.log(`Invalid domain or no MX records for: ${domain}`);
resolve(false);
}
});
});
});
};


0 comments on commit f25bd69

Please sign in to comment.