Skip to content

Commit 1aab1e7

Browse files
committed
Add new check for emails
1 parent f8f2b10 commit 1aab1e7

File tree

1 file changed

+145
-4
lines changed

1 file changed

+145
-4
lines changed

views/admin-console.ejs

Lines changed: 145 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@
152152
}
153153
154154
.pending-user-email {
155-
font-size: 1.1rem;
155+
font-size: 1.2rem;
156156
color: #f7fafc;
157157
}
158158
@@ -176,13 +176,13 @@
176176
177177
.info-label {
178178
color: #a0aec0;
179-
font-size: 0.9rem;
179+
font-size: 1rem;
180180
font-weight: 500;
181181
}
182182
183183
.info-value {
184184
color: #f7fafc;
185-
font-size: 0.9rem;
185+
font-size: 1rem;
186186
}
187187
188188
.pending-user-divider {
@@ -191,8 +191,50 @@
191191
margin: 1.5rem 0;
192192
}
193193
194+
/* Email validation warning styles */
195+
.email-warning {
196+
padding: 0.75rem;
197+
margin: 0.5rem 0;
198+
border-radius: 8px;
199+
display: flex;
200+
align-items: center;
201+
font-size: 0.95rem;
202+
font-weight: 500;
203+
}
204+
205+
.email-warning.invalid-warning {
206+
background: linear-gradient(135deg, rgba(229, 62, 62, 0.1) 0%, rgba(229, 62, 62, 0.05) 100%);
207+
border: 1px solid rgba(229, 62, 62, 0.3);
208+
color: #fed7d7;
209+
}
210+
211+
.email-warning.invalid-warning i {
212+
color: #e53e3e;
213+
margin-right: 0.5rem;
214+
font-size: 1rem;
215+
}
216+
217+
.email-warning.suspicious-warning {
218+
background: linear-gradient(135deg, rgba(214, 158, 46, 0.1) 0%, rgba(214, 158, 46, 0.05) 100%);
219+
border: 1px solid rgba(214, 158, 46, 0.3);
220+
color: #faf089;
221+
}
222+
223+
.email-warning.suspicious-warning i {
224+
color: #d69e2e;
225+
margin-right: 0.5rem;
226+
font-size: 1rem;
227+
}
228+
194229
.recent-search-item {
195230
margin-bottom: 0.75rem;
231+
font-size: 0.95rem;
232+
}
233+
234+
.recent-searches h6 {
235+
font-size: 1rem;
236+
color: #e2e8f0;
237+
font-weight: 600;
196238
}
197239
198240
.no-users-found {
@@ -297,7 +339,7 @@
297339
.recent-searches-title {
298340
color: #e2e8f0;
299341
font-weight: 600;
300-
font-size: 0.875rem;
342+
font-size: 1rem;
301343
margin: 0;
302344
display: flex;
303345
align-items: center;
@@ -2338,17 +2380,115 @@
23382380
displayPendingUserResultsPage(pendingUsers, pagination.currentPage, pagination.totalRecords, pagination.totalPages);
23392381
}
23402382
2383+
// Email validation functions
2384+
function isValidEmail(email) {
2385+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
2386+
return emailRegex.test(email);
2387+
}
2388+
2389+
function getEmailValidationLevel(email) {
2390+
if (!email || typeof email !== 'string') return 'invalid';
2391+
2392+
// Basic email structure check
2393+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
2394+
if (!emailRegex.test(email)) return 'invalid';
2395+
2396+
// Check for common typos in domain extensions
2397+
const domain = email.split('@')[1];
2398+
const validExtensions = [
2399+
'com', 'org', 'net', 'edu', 'gov', 'mil', 'int',
2400+
'co.uk', 'co.jp', 'co.in', 'com.au', 'com.br', 'com.mx',
2401+
'de', 'fr', 'it', 'es', 'ca', 'au', 'jp', 'in', 'br', 'mx'
2402+
];
2403+
2404+
// Check if domain ends with a valid extension
2405+
const hasValidExtension = validExtensions.some(ext => domain.endsWith('.' + ext) || domain === ext);
2406+
2407+
// Check for suspicious patterns
2408+
const suspiciousPatterns = [
2409+
/[^a-zA-Z0-9@._-]/, // Contains invalid characters
2410+
/\.{2,}/, // Multiple consecutive dots
2411+
/^\.|\.$/, // Starts or ends with dot
2412+
/@.*@/, // Multiple @ symbols
2413+
/\.{2,}@/, // Dots before @
2414+
/@\.{2,}/, // Dots after @
2415+
];
2416+
2417+
for (const pattern of suspiciousPatterns) {
2418+
if (pattern.test(email)) return 'invalid';
2419+
}
2420+
2421+
// Check for common typos in popular domains
2422+
const commonDomains = ['gmail.com', 'yahoo.com', 'hotmail.com', 'outlook.com', 'aol.com'];
2423+
const emailDomain = domain.toLowerCase();
2424+
2425+
for (const commonDomain of commonDomains) {
2426+
if (emailDomain.includes(commonDomain) && emailDomain !== commonDomain) {
2427+
// Check if it's just a typo (similar but not exact)
2428+
if (emailDomain.length <= commonDomain.length + 3) {
2429+
return 'suspicious';
2430+
}
2431+
}
2432+
}
2433+
2434+
// Check for domains that end with extra characters (like .comq)
2435+
if (domain.includes('.') && !hasValidExtension) {
2436+
const parts = domain.split('.');
2437+
const lastPart = parts[parts.length - 1];
2438+
if (lastPart.length > 4 || !/^[a-zA-Z]+$/.test(lastPart)) {
2439+
return 'suspicious';
2440+
}
2441+
}
2442+
2443+
return hasValidExtension ? 'valid' : 'suspicious';
2444+
}
2445+
2446+
function getEmailWarningIcon(validationLevel) {
2447+
switch (validationLevel) {
2448+
case 'invalid':
2449+
return '<i class="fas fa-exclamation-triangle" style="color: #e53e3e; margin-left: 8px;" title="Invalid email address"></i>';
2450+
case 'suspicious':
2451+
return '<i class="fas fa-exclamation-circle" style="color: #d69e2e; margin-left: 8px;" title="Potentially invalid email address"></i>';
2452+
default:
2453+
return '<i class="fas fa-check-circle" style="color: #38a169; margin-left: 8px;" title="Valid email address"></i>';
2454+
}
2455+
}
2456+
2457+
function getEmailWarningMessage(validationLevel, email) {
2458+
switch (validationLevel) {
2459+
case 'invalid':
2460+
return `<div class="email-warning invalid-warning">
2461+
<i class="fas fa-exclamation-triangle"></i>
2462+
<span>Invalid email format - user may have entered incorrect email</span>
2463+
</div>`;
2464+
case 'suspicious':
2465+
const domain = email.split('@')[1];
2466+
return `<div class="email-warning suspicious-warning">
2467+
<i class="fas fa-exclamation-circle"></i>
2468+
<span>Potentially invalid email (${domain}) - verify with user</span>
2469+
</div>`;
2470+
default:
2471+
return '';
2472+
}
2473+
}
2474+
23412475
function displayPendingUserResultsPage(pendingUsers, currentPage, totalRecords, totalPages) {
23422476
let html = '';
23432477
23442478
pendingUsers.forEach((pendingUser, index) => {
2479+
// Validate email
2480+
const emailValidation = getEmailValidationLevel(pendingUser.email);
2481+
const warningIcon = getEmailWarningIcon(emailValidation);
2482+
const warningMessage = getEmailWarningMessage(emailValidation, pendingUser.email);
2483+
23452484
const createdAt = new Date(pendingUser.createdAt).toLocaleString();
23462485
html += `
23472486
<div class="pending-user-card">
23482487
<div class="pending-user-header">
23492488
<div class="pending-user-email">
23502489
<i class="fas fa-envelope" style="margin-right: 8px; color: #667eea;"></i>
23512490
<strong>${pendingUser.email}</strong>
2491+
${warningIcon}
23522492
</div>
23532493
<div class="pending-user-actions">
23542494
<button class="btn btn-sm copy-btn"
@@ -2358,6 +2498,7 @@
23582498
</button>
23592499
</div>
23602500
</div>
2501+
${warningMessage}
23612502
<div class="pending-user-details">
23622503
<div class="pending-user-info">
23632504
<div class="info-item">

0 commit comments

Comments
 (0)