feat: Add additional checks for website, NS records and personal emails

This commit is contained in:
Dries Augustyns
2026-01-12 20:02:08 +01:00
parent 26800a8553
commit 0a67a8278f
8 changed files with 163 additions and 46 deletions
@@ -2,15 +2,16 @@ import {
AlertCircle,
AlertTriangle,
CheckCircle,
Forward,
Info,
Mail,
Server,
Shield,
Trash2,
User,
XCircle,
Forward,
} from 'lucide-react';
import type {EmailVerificationResult as VerificationResult} from '../../lib/emailVerification';
import type {EmailVerificationResult as VerificationResult} from '@plunk/types';
interface EmailVerificationResultProps {
result: VerificationResult;
@@ -52,7 +53,7 @@ export function EmailVerificationResult({result}: EmailVerificationResultProps)
<Server className="h-5 w-5 text-neutral-600" />
<div>
<p className="font-medium text-neutral-900">Domain Exists</p>
<p className="text-sm text-neutral-600">DNS A/AAAA records found</p>
<p className="text-sm text-neutral-600">Domain has nameservers (NS records)</p>
</div>
</div>
{result.domainExists ? (
@@ -78,6 +79,22 @@ export function EmailVerificationResult({result}: EmailVerificationResultProps)
)}
</div>
{/* Website/A Records */}
<div className="flex items-center justify-between px-6 py-4">
<div className="flex items-center gap-3">
<Server className="h-5 w-5 text-neutral-600" />
<div>
<p className="font-medium text-neutral-900">Has Website</p>
<p className="text-sm text-neutral-600">DNS A/AAAA records found</p>
</div>
</div>
{result.hasWebsite ? (
<CheckCircle className="h-5 w-5 text-green-600" />
) : (
<Info className="h-5 w-5 text-neutral-400" />
)}
</div>
{/* Disposable Email */}
<div className="flex items-center justify-between px-6 py-4">
<div className="flex items-center gap-3">
@@ -94,6 +111,22 @@ export function EmailVerificationResult({result}: EmailVerificationResultProps)
)}
</div>
{/* Personal Email */}
<div className="flex items-center justify-between px-6 py-4">
<div className="flex items-center gap-3">
<User className="h-5 w-5 text-neutral-600" />
<div>
<p className="font-medium text-neutral-900">Personal Email</p>
<p className="text-sm text-neutral-600">Free email provider (Gmail, Hotmail, etc.)</p>
</div>
</div>
{result.isPersonalEmail ? (
<Info className="h-5 w-5 text-blue-600" />
) : (
<span className="text-sm text-neutral-500">No</span>
)}
</div>
{/* Alias/Forwarding Email */}
<div className="flex items-center justify-between px-6 py-4">
<div className="flex items-center gap-3">
+1 -12
View File
@@ -1,15 +1,4 @@
export interface EmailVerificationResult {
email: string;
valid: boolean;
isDisposable: boolean;
isAlias: boolean;
isTypo: boolean;
isPlusAddressed: boolean;
domainExists: boolean;
hasMxRecords: boolean;
suggestedEmail?: string;
reasons: string[];
}
import type {EmailVerificationResult} from '@plunk/types';
export async function verifyEmail(email: string): Promise<EmailVerificationResult> {
const response = await fetch('/api/verify-email', {
+6 -1
View File
@@ -1,4 +1,4 @@
import {CheckCircle, Mail, Search, Shield} from 'lucide-react';
import {CheckCircle, Mail, Search, Shield, User} from 'lucide-react';
/**
* Educational content for the email verification tool
@@ -29,6 +29,11 @@ export const EMAIL_VERIFICATION_FEATURES = [
description: 'Identify temporary email addresses that are often used for spam or fake signups.',
icon: Mail,
},
{
title: 'Personal Email Detection',
description: 'Detect personal/free email providers like Gmail, Hotmail, Yahoo for B2B validation.',
icon: User,
},
{
title: 'Plus Addressing',
description: 'Detect plus-addressed emails ([email protected]) which can be useful for tracking.',
+5 -13
View File
@@ -1,24 +1,16 @@
import type {NextApiRequest, NextApiResponse} from 'next';
import type {EmailVerificationResult} from '@plunk/types';
import {UtilitySchemas} from '@plunk/shared';
import {API_URI} from '../../lib/constants';
interface VerifyEmailResponse {
email: string;
valid: boolean;
isDisposable: boolean;
isTypo: boolean;
isPlusAddressed: boolean;
domainExists: boolean;
hasMxRecords: boolean;
suggestedEmail?: string;
reasons: string[];
}
interface ErrorResponse {
error: string;
}
export default async function handler(req: NextApiRequest, res: NextApiResponse<VerifyEmailResponse | ErrorResponse>) {
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<EmailVerificationResult | ErrorResponse>,
) {
// Only allow POST requests
if (req.method !== 'POST') {
return res.status(405).json({error: 'Method not allowed'});
@@ -4,7 +4,8 @@ import {DASHBOARD_URI} from '../../lib/constants';
import React, {useState} from 'react';
import {NextSeo} from 'next-seo';
import {ArrowRight, CheckCircle, Loader2, Search} from 'lucide-react';
import {type EmailVerificationResult as VerificationResult, verifyEmail} from '../../lib/emailVerification';
import type {EmailVerificationResult as VerificationResult} from '@plunk/types';
import {verifyEmail} from '../../lib/emailVerification';
import {EmailVerificationResult} from '../../components/tools/EmailVerificationResult';
import {Button, Input} from '@plunk/ui';
import {EMAIL_VERIFICATION_FEATURES} from '../../lib/toolsContent';