@mikkelscheike/email-provider-links 2.7.1 β 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -146
- package/dist/api.d.ts +1 -1
- package/dist/api.js +3 -3
- package/dist/concurrent-dns.d.ts +1 -1
- package/dist/hash-verifier.js +2 -2
- package/dist/loader.d.ts +1 -1
- package/dist/loader.js +6 -2
- package/dist/schema.d.ts +3 -3
- package/dist/schema.js +4 -7
- package/package.json +6 -6
- package/providers/emailproviders.json +674 -282
package/README.md
CHANGED
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
π **Modern email provider detection library with enhanced TypeScript support and enterprise security**
|
|
4
4
|
|
|
5
|
-
A robust TypeScript library providing direct links to **93 email providers** (
|
|
5
|
+
A robust TypeScript library providing direct links to **93 email providers** (180 domains) with **concurrent DNS resolution**, **optimized performance**, **comprehensive email validation**, and advanced security features for login and password reset flows.
|
|
6
|
+
|
|
7
|
+
## π Try it out
|
|
8
|
+
|
|
9
|
+
**[Live Demo](https://demo.mikkelscheike.com)** - Test the library with any email address and see it in action!
|
|
6
10
|
|
|
7
11
|
## β¨ New in Version 2.7.0
|
|
8
12
|
|
|
@@ -13,12 +17,13 @@ A robust TypeScript library providing direct links to **93 email providers** (17
|
|
|
13
17
|
- π‘οΈ **Improved Security**: Enhanced cryptographic integrity verification
|
|
14
18
|
- β‘ **Better Performance**: Optimized concurrent DNS with smart caching
|
|
15
19
|
- π― **Developer Experience**: Enhanced error messages and debugging information
|
|
20
|
+
- π **Development Mode**: Memory usage tracking when NODE_ENV=development
|
|
16
21
|
|
|
17
22
|
## β¨ Core Features
|
|
18
23
|
|
|
19
|
-
- π **Fast & Lightweight**: Zero dependencies, ultra-low memory (~0.
|
|
24
|
+
- π **Fast & Lightweight**: Zero dependencies, ultra-low memory (~0.08MB initial, ~0.03MB per 1000 ops)
|
|
20
25
|
- π§ **93 Email Providers**: Gmail, Outlook, Yahoo, ProtonMail, iCloud, and many more
|
|
21
|
-
- π **
|
|
26
|
+
- π **207 Domains Supported**: Comprehensive international coverage
|
|
22
27
|
- π **Full IDN Support**: International domain names with RFC compliance and Punycode
|
|
23
28
|
- β
**Advanced Email Validation**: International email validation with detailed error reporting
|
|
24
29
|
- π’ **Business Domain Detection**: DNS-based detection for custom domains (Google Workspace, Microsoft 365, etc.)
|
|
@@ -31,7 +36,7 @@ A robust TypeScript library providing direct links to **93 email providers** (17
|
|
|
31
36
|
- π **Email Alias Detection**: Normalize Gmail dots, plus addressing, and provider-specific aliases
|
|
32
37
|
- π‘οΈ **Fraud Prevention**: Detect duplicate accounts through email alias manipulation
|
|
33
38
|
- π¦ **Batch Processing**: Efficiently process multiple emails with deduplication
|
|
34
|
-
- π§ͺ **Thoroughly Tested**:
|
|
39
|
+
- π§ͺ **Thoroughly Tested**: 424 tests with 93.16% code coverage
|
|
35
40
|
|
|
36
41
|
## Installation
|
|
37
42
|
|
|
@@ -54,83 +59,9 @@ Fully compatible with the latest Node.js 24.x! The library is tested on:
|
|
|
54
59
|
- Node.js 22.x (Current)
|
|
55
60
|
- **Node.js 24.x (Latest)** - Full support with latest features
|
|
56
61
|
|
|
57
|
-
## Quick Start
|
|
58
|
-
|
|
59
|
-
**One function handles everything** - consumer emails, business domains, and unknown providers:
|
|
60
|
-
|
|
61
|
-
```typescript
|
|
62
|
-
import { getEmailProvider } from '@mikkelscheike/email-provider-links';
|
|
63
|
-
|
|
64
|
-
// Works for ANY email address - the only function you need
|
|
65
|
-
const result = await getEmailProvider('user@gmail.com');
|
|
66
|
-
console.log(result.loginUrl); // "https://mail.google.com/mail/"
|
|
67
|
-
console.log(result.provider?.companyProvider); // "Gmail"
|
|
68
|
-
|
|
69
|
-
// Automatically detects business domains too
|
|
70
|
-
const business = await getEmailProvider('user@mycompany.com');
|
|
71
|
-
console.log(business.provider?.companyProvider); // "Google Workspace" (if detected)
|
|
72
|
-
|
|
73
|
-
// Gracefully handles unknown providers
|
|
74
|
-
const unknown = await getEmailProvider('user@unknown.com');
|
|
75
|
-
console.log(unknown.loginUrl); // null
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## Enhanced Email Validation
|
|
79
|
-
|
|
80
|
-
**New in 2.7.0**: Comprehensive email validation with international support:
|
|
81
|
-
|
|
82
|
-
```typescript
|
|
83
|
-
import { validateEmailAddress, validateInternationalEmail } from '@mikkelscheike/email-provider-links';
|
|
84
|
-
|
|
85
|
-
// Enhanced validation with detailed error reporting
|
|
86
|
-
const result = validateEmailAddress('user@example.com');
|
|
87
|
-
if (result.isValid) {
|
|
88
|
-
console.log('Valid email:', result.normalizedEmail);
|
|
89
|
-
} else {
|
|
90
|
-
console.log('Error:', result.error?.message);
|
|
91
|
-
console.log('Error code:', result.error?.code);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// International domain validation
|
|
95
|
-
const intlResult = validateInternationalEmail('user@mΓΌnchen.de');
|
|
96
|
-
if (!intlResult) {
|
|
97
|
-
console.log('Valid international email');
|
|
98
|
-
} else {
|
|
99
|
-
console.log('Validation error:', intlResult.message);
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
## Batch Processing
|
|
104
|
-
|
|
105
|
-
**New in 2.7.0**: Process multiple emails efficiently with deduplication:
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
import { batchProcessEmails } from '@mikkelscheike/email-provider-links';
|
|
109
|
-
|
|
110
|
-
const emails = [
|
|
111
|
-
'user@gmail.com',
|
|
112
|
-
'u.s.e.r+work@gmail.com', // Alias of the first email
|
|
113
|
-
'test@yahoo.com',
|
|
114
|
-
'invalid-email'
|
|
115
|
-
];
|
|
116
|
-
|
|
117
|
-
const results = batchProcessEmails(emails, {
|
|
118
|
-
includeProviderInfo: true,
|
|
119
|
-
normalizeEmails: true,
|
|
120
|
-
deduplicateAliases: true
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
results.forEach(result => {
|
|
124
|
-
console.log(`${result.email}: ${result.isValid ? 'Valid' : 'Invalid'}`);
|
|
125
|
-
if (result.isDuplicate) {
|
|
126
|
-
console.log(' π Duplicate detected');
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
```
|
|
130
|
-
|
|
131
62
|
## Supported Providers
|
|
132
63
|
|
|
133
|
-
**π Current Coverage: 93 providers supporting
|
|
64
|
+
**π Current Coverage: 93 providers supporting 207 domains**
|
|
134
65
|
|
|
135
66
|
**Consumer Email Providers:**
|
|
136
67
|
- **Gmail** (2 domains): gmail.com, googlemail.com
|
|
@@ -301,73 +232,36 @@ console.log(domain); // 'example.com'
|
|
|
301
232
|
|
|
302
233
|
</details>
|
|
303
234
|
|
|
304
|
-
##
|
|
305
|
-
|
|
306
|
-
Full TypeScript support with comprehensive interfaces:
|
|
307
|
-
|
|
308
|
-
```typescript
|
|
309
|
-
interface EmailProviderResult {
|
|
310
|
-
provider: EmailProvider | null;
|
|
311
|
-
email: string;
|
|
312
|
-
loginUrl: string | null;
|
|
313
|
-
detectionMethod?: 'domain_match' | 'mx_record' | 'txt_record' | 'both' | 'proxy_detected';
|
|
314
|
-
proxyService?: string;
|
|
315
|
-
error?: {
|
|
316
|
-
type: 'INVALID_EMAIL' | 'DNS_TIMEOUT' | 'RATE_LIMITED' | 'UNKNOWN_DOMAIN' |
|
|
317
|
-
'NETWORK_ERROR' | 'IDN_VALIDATION_ERROR';
|
|
318
|
-
message: string;
|
|
319
|
-
retryAfter?: number; // seconds until retry allowed (for rate limiting)
|
|
320
|
-
idnError?: string; // specific IDN validation error message
|
|
321
|
-
};
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
interface ConfigConstants {
|
|
325
|
-
DEFAULT_DNS_TIMEOUT: number; // 5000ms
|
|
326
|
-
MAX_DNS_REQUESTS_PER_MINUTE: number; // 10 requests
|
|
327
|
-
SUPPORTED_PROVIDERS_COUNT: number; // 93 providers
|
|
328
|
-
SUPPORTED_DOMAINS_COUNT: number; // 178 domains
|
|
329
|
-
}
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
## π‘οΈ Security Features
|
|
235
|
+
## Performance and Detection System
|
|
333
236
|
|
|
334
|
-
|
|
237
|
+
For detailed performance metrics and information about the detection system, refer to [Performance and Detection System](docs/PERFORMANCE.md).
|
|
335
238
|
|
|
336
|
-
###
|
|
239
|
+
### Development Mode Features
|
|
337
240
|
|
|
338
|
-
|
|
339
|
-
- **Domain Allowlisting**: Only pre-approved domains are allowed (93+ verified providers)
|
|
340
|
-
- **Malicious Pattern Detection**: Blocks IP addresses, URL shorteners, suspicious TLDs
|
|
341
|
-
- **Path Traversal Prevention**: Detects and blocks `../` and encoded variants
|
|
342
|
-
- **JavaScript Injection Protection**: Prevents `javascript:`, `data:`, and script injections
|
|
343
|
-
- **File Integrity Verification**: SHA-256 hash verification for provider database
|
|
241
|
+
When `NODE_ENV` is set to 'development', the library provides additional insights:
|
|
344
242
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
- β **Typosquatting**: Blocked by domain validation
|
|
350
|
-
- β **URL Shorteners**: Blocked by pattern detection
|
|
351
|
-
- β **Protocol Downgrade**: Blocked by HTTPS enforcement
|
|
352
|
-
- β **Path Traversal**: Blocked by path validation
|
|
353
|
-
- β **Script Injection**: Blocked by content validation
|
|
354
|
-
- β **Supply Chain Attacks**: Blocked by integrity verification
|
|
243
|
+
```typescript
|
|
244
|
+
// Memory usage is automatically logged:
|
|
245
|
+
// π Current memory usage: 0.08 MB
|
|
246
|
+
```
|
|
355
247
|
|
|
356
|
-
###
|
|
248
|
+
### Memory Management
|
|
357
249
|
|
|
358
|
-
|
|
359
|
-
-
|
|
360
|
-
-
|
|
361
|
-
-
|
|
250
|
+
The library implements careful memory management:
|
|
251
|
+
- Initial load: ~0.08MB heap usage
|
|
252
|
+
- Batch operations: ~0.03MB per 1000 operations
|
|
253
|
+
- Maximum load: < 25MB even under heavy concurrent operations
|
|
254
|
+
- Automatic garbage collection hints
|
|
255
|
+
- Memory usage logging in development mode
|
|
362
256
|
|
|
363
|
-
|
|
257
|
+
### Performance Benchmarks
|
|
364
258
|
|
|
365
259
|
This package is designed to be extremely memory efficient and fast:
|
|
366
260
|
|
|
367
|
-
- **Provider loading**: ~0.
|
|
368
|
-
- **Email lookups**: ~0.
|
|
369
|
-
- **Concurrent DNS**: ~0.03MB heap usage, ~
|
|
370
|
-
- **Large scale (1000 ops)**: ~0.
|
|
261
|
+
- **Provider loading**: ~0.08MB heap usage, ~0.5ms
|
|
262
|
+
- **Email lookups**: ~0.03MB heap usage per 100 operations
|
|
263
|
+
- **Concurrent DNS**: ~0.03MB heap usage, ~27ms for 10 lookups
|
|
264
|
+
- **Large scale (1000 ops)**: ~0.03MB heap usage, ~1.1ms total
|
|
371
265
|
- **International validation**: <1ms for complex IDN domains
|
|
372
266
|
|
|
373
267
|
To run benchmarks locally:
|
|
@@ -375,19 +269,11 @@ To run benchmarks locally:
|
|
|
375
269
|
npm run benchmark
|
|
376
270
|
```
|
|
377
271
|
|
|
378
|
-
## Examples
|
|
379
|
-
|
|
380
|
-
Run the modern example to see all features in action:
|
|
381
|
-
|
|
382
|
-
```bash
|
|
383
|
-
npx tsx examples/modern-example.ts
|
|
384
|
-
```
|
|
385
|
-
|
|
386
272
|
## Contributing
|
|
387
273
|
|
|
388
274
|
We welcome contributions! See [CONTRIBUTING.md](docs/CONTRIBUTING.md) for guidelines on adding new email providers.
|
|
389
275
|
|
|
390
|
-
**Quality Assurance**: This project maintains high standards with
|
|
276
|
+
**Quality Assurance**: This project maintains high standards with 424 comprehensive tests achieving 93.16% code coverage (96.46% function coverage).
|
|
391
277
|
**Security Note**: All new providers undergo security validation and must pass our allowlist verification.
|
|
392
278
|
|
|
393
279
|
## Security
|
|
@@ -400,4 +286,4 @@ MIT License - see [LICENSE](LICENSE) file for details.
|
|
|
400
286
|
|
|
401
287
|
---
|
|
402
288
|
|
|
403
|
-
**Zero dependencies β’ TypeScript-first β’ Production ready β’ International support**
|
|
289
|
+
**Zero dependencies β’ TypeScript-first β’ Production ready β’ International support**
|
package/dist/api.d.ts
CHANGED
package/dist/api.js
CHANGED
|
@@ -215,9 +215,9 @@ function getEmailProviderSync(email) {
|
|
|
215
215
|
}
|
|
216
216
|
};
|
|
217
217
|
}
|
|
218
|
-
//
|
|
219
|
-
const {
|
|
220
|
-
const provider =
|
|
218
|
+
// Use cached providers and domain map for efficient lookup
|
|
219
|
+
const { domainMap } = (0, loader_1.loadProviders)();
|
|
220
|
+
const provider = domainMap.get(domain);
|
|
221
221
|
const result = {
|
|
222
222
|
provider: provider || null,
|
|
223
223
|
email,
|
package/dist/concurrent-dns.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements parallel MX/TXT record lookups for 2x faster business domain detection.
|
|
5
5
|
* Uses Promise.allSettled for fault tolerance and intelligent result merging.
|
|
6
6
|
*/
|
|
7
|
-
import { EmailProvider } from './
|
|
7
|
+
import { EmailProvider } from './api';
|
|
8
8
|
/**
|
|
9
9
|
* Configuration for concurrent DNS detection
|
|
10
10
|
*/
|
package/dist/hash-verifier.js
CHANGED
|
@@ -27,9 +27,9 @@ const path_1 = require("path");
|
|
|
27
27
|
*/
|
|
28
28
|
const KNOWN_GOOD_HASHES = {
|
|
29
29
|
// SHA-256 hash of the legitimate emailproviders.json
|
|
30
|
-
'emailproviders.json': '
|
|
30
|
+
'emailproviders.json': 'bdd4fe7d32a8760db2c2a2fcc9d2c07b32cc309f17eb6fd6c57753de0b5d623d',
|
|
31
31
|
// You can add hashes for other critical files
|
|
32
|
-
'package.json': '
|
|
32
|
+
'package.json': '86b76c6907a39775d96677b6d76719c8de6cadd256945134195513101beef489'
|
|
33
33
|
};
|
|
34
34
|
/**
|
|
35
35
|
* Calculates SHA-256 hash of a file or string content
|
package/dist/loader.d.ts
CHANGED
package/dist/loader.js
CHANGED
|
@@ -30,8 +30,8 @@ const DEFAULT_CONFIG = {
|
|
|
30
30
|
*/
|
|
31
31
|
function convertProviderToEmailProvider(compressedProvider) {
|
|
32
32
|
const provider = {
|
|
33
|
-
companyProvider: compressedProvider.
|
|
34
|
-
loginUrl: compressedProvider.
|
|
33
|
+
companyProvider: compressedProvider.companyProvider,
|
|
34
|
+
loginUrl: compressedProvider.loginUrl || null,
|
|
35
35
|
domains: compressedProvider.domains || []
|
|
36
36
|
};
|
|
37
37
|
// Convert DNS detection patterns
|
|
@@ -92,6 +92,10 @@ function loadProvidersInternal(config = {}) {
|
|
|
92
92
|
console.log(`β‘ Loading completed in ${loadTime}ms`);
|
|
93
93
|
console.log(`π Stats: ${providers.length} providers, ${domainCount} domains`);
|
|
94
94
|
}
|
|
95
|
+
if (process.env.NODE_ENV === 'development') {
|
|
96
|
+
const memoryUsageInMB = process.memoryUsage().heapUsed / 1024 / 1024;
|
|
97
|
+
console.log(`π Current memory usage: ${memoryUsageInMB.toFixed(2)} MB`);
|
|
98
|
+
}
|
|
95
99
|
return {
|
|
96
100
|
providers,
|
|
97
101
|
stats: loadingStats
|
package/dist/schema.d.ts
CHANGED
|
@@ -12,9 +12,9 @@ export interface Provider {
|
|
|
12
12
|
/** Provider ID (short identifier) */
|
|
13
13
|
id: string;
|
|
14
14
|
/** Provider display name */
|
|
15
|
-
|
|
16
|
-
/** Login/webmail URL */
|
|
17
|
-
|
|
15
|
+
companyProvider: string;
|
|
16
|
+
/** Login/webmail URL (or null if not available) */
|
|
17
|
+
loginUrl: string | null;
|
|
18
18
|
/** Email domains (omitted if empty) */
|
|
19
19
|
domains?: string[];
|
|
20
20
|
/** DNS detection patterns (flattened) */
|
package/dist/schema.js
CHANGED
|
@@ -51,14 +51,11 @@ function validateProvider(provider) {
|
|
|
51
51
|
if (!provider.id || typeof provider.id !== 'string') {
|
|
52
52
|
errors.push('Provider ID is required and must be a string');
|
|
53
53
|
}
|
|
54
|
-
if (!provider.
|
|
55
|
-
errors.push('
|
|
54
|
+
if (!provider.companyProvider || typeof provider.companyProvider !== 'string') {
|
|
55
|
+
errors.push('Company provider is required and must be a string');
|
|
56
56
|
}
|
|
57
|
-
if (
|
|
58
|
-
errors.push('
|
|
59
|
-
}
|
|
60
|
-
else if (!provider.url.startsWith('https://')) {
|
|
61
|
-
errors.push('Provider URL must use HTTPS');
|
|
57
|
+
if (provider.loginUrl !== null && (typeof provider.loginUrl !== 'string' || !provider.loginUrl.startsWith('https://'))) {
|
|
58
|
+
errors.push('Login URL must be null or a string starting with HTTPS');
|
|
62
59
|
}
|
|
63
60
|
if (provider.domains && !Array.isArray(provider.domains)) {
|
|
64
61
|
errors.push('Domains must be an array');
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikkelscheike/email-provider-links",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "TypeScript library for email provider detection with 93 providers (
|
|
3
|
+
"version": "2.8.0",
|
|
4
|
+
"description": "TypeScript library for email provider detection with 93 providers (207 domains), concurrent DNS resolution, optimized performance, 91.75% test coverage, and enterprise security for login and password reset flows",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -62,17 +62,17 @@
|
|
|
62
62
|
"access": "public"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
|
-
"@jest/globals": "^30.0.
|
|
65
|
+
"@jest/globals": "^30.0.3",
|
|
66
66
|
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
67
67
|
"@semantic-release/exec": "^7.1.0",
|
|
68
68
|
"@semantic-release/git": "^10.0.1",
|
|
69
69
|
"@semantic-release/github": "^11.0.3",
|
|
70
|
-
"@semantic-release/npm": "^12.0.
|
|
70
|
+
"@semantic-release/npm": "^12.0.2",
|
|
71
71
|
"@semantic-release/release-notes-generator": "^14.0.3",
|
|
72
72
|
"@types/jest": "^30.0.0",
|
|
73
|
-
"@types/node": "^24.0.
|
|
73
|
+
"@types/node": "^24.0.4",
|
|
74
74
|
"conventional-changelog-conventionalcommits": "^9.0.0",
|
|
75
|
-
"jest": "^30.0.
|
|
75
|
+
"jest": "^30.0.3",
|
|
76
76
|
"semantic-release": "^24.2.5",
|
|
77
77
|
"ts-jest": "^29.4.0",
|
|
78
78
|
"tsx": "^4.20.3",
|