@mikkelscheike/email-provider-links 1.7.0 → 1.9.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/dist/index.d.ts CHANGED
@@ -1,374 +1,66 @@
1
1
  /**
2
2
  * Email Provider Links
3
3
  *
4
- * A TypeScript package that provides direct links to email providers
5
- * based on email addresses to streamline login and password reset flows.
6
- *
7
- * The package uses a two-tier detection system:
8
- * 1. Fast domain lookup against a JSON database of known providers
9
- * 2. DNS-based detection for custom business domains using MX/TXT record analysis
10
- *
11
- * @packageDocumentation
12
- */
13
- /**
14
- * Simple rate limiter to prevent excessive DNS queries.
15
- * Tracks request timestamps and enforces a maximum number of requests per time window.
4
+ * A clean, modern email provider detection library with:
5
+ * - 93+ verified email providers covering 180+ domains
6
+ * - Concurrent DNS detection for business domains
7
+ * - Zero runtime dependencies
8
+ * - Comprehensive error handling
9
+ * - Email alias normalization
10
+ *
11
+ * @author Email Provider Links Team
12
+ * @license MIT
16
13
  */
17
- declare class SimpleRateLimiter {
18
- private maxRequests;
19
- private windowMs;
20
- private requestTimestamps;
21
- constructor(maxRequests?: number, windowMs?: number);
22
- /**
23
- * Checks if a request is allowed under the current rate limit.
24
- * @returns true if request is allowed, false if rate limited
25
- */
26
- isAllowed(): boolean;
27
- /**
28
- * Gets the current number of requests in the window.
29
- */
30
- getCurrentCount(): number;
31
- /**
32
- * Gets the time until the rate limit resets (when oldest request expires).
33
- * @returns milliseconds until reset, or 0 if not rate limited
34
- */
35
- getTimeUntilReset(): number;
36
- }
14
+ export { getEmailProvider, getEmailProviderSync, getEmailProviderFast, normalizeEmail, emailsMatch, Config } from './api';
15
+ export type { EmailProvider, EmailProviderResult } from './api';
16
+ export { loadProviders } from './loader';
17
+ export { detectProviderConcurrent } from './concurrent-dns';
18
+ export type { ConcurrentDNSConfig, ConcurrentDNSResult } from './concurrent-dns';
19
+ import { getEmailProvider, getEmailProviderSync, getEmailProviderFast, normalizeEmail, emailsMatch } from './api';
37
20
  /**
38
- * Represents an email provider with its associated domains and login URL.
39
- *
40
- * @interface EmailProvider
41
- * @example
42
- * ```typescript
43
- * {
44
- * companyProvider: "Gmail",
45
- * loginUrl: "https://mail.google.com/mail/",
46
- * domains: ["gmail.com", "googlemail.com"],
47
- * customDomainDetection: {
48
- * mxPatterns: ["aspmx.l.google.com"],
49
- * txtPatterns: ["v=spf1 include:_spf.google.com"]
50
- * }
51
- * }
52
- * ```
21
+ * Get list of all supported email providers
22
+ * @returns Array of all email providers in the database
53
23
  */
54
- export interface EmailProvider {
55
- /** Human-readable name of the email provider company */
56
- companyProvider: string;
57
- /** Direct URL to the provider's login/webmail page */
58
- loginUrl: string;
59
- /** Array of email domains this provider handles (e.g., ['gmail.com', 'googlemail.com']) */
60
- domains: string[];
61
- /** Optional DNS-based detection patterns for custom business domains */
62
- customDomainDetection?: {
63
- /** MX record patterns to match against (e.g., ['aspmx.l.google.com']) */
64
- mxPatterns?: string[];
65
- /** TXT record patterns to match against (e.g., ['v=spf1 include:_spf.google.com']) */
66
- txtPatterns?: string[];
67
- };
68
- }
24
+ export declare function getSupportedProviders(): import("./api").EmailProvider[];
69
25
  /**
70
- * Result object returned by email provider detection functions.
71
- *
72
- * @interface EmailProviderResult
73
- * @example
74
- * ```typescript
75
- * {
76
- * provider: { companyProvider: "Gmail", loginUrl: "https://mail.google.com/mail/", domains: ["gmail.com"] },
77
- * email: "user@gmail.com",
78
- * loginUrl: "https://mail.google.com/mail/",
79
- * detectionMethod: "domain_match"
80
- * }
81
- * ```
82
- */
83
- export interface EmailProviderResult {
84
- /** The detected email provider, or null if not found/behind proxy */
85
- provider: EmailProvider | null;
86
- /** The original email address that was analyzed */
87
- email: string;
88
- /** Direct URL to the email provider's login page, or null if unknown */
89
- loginUrl: string | null;
90
- /** Method used to detect the provider */
91
- detectionMethod?: 'domain_match' | 'mx_record' | 'txt_record' | 'proxy_detected';
92
- /** If a proxy service was detected, which service (e.g., 'Cloudflare') */
93
- proxyService?: string;
94
- }
95
- /**
96
- * Result object returned by DNS-based provider detection.
97
- *
98
- * @interface DNSDetectionResult
99
- * @example
100
- * ```typescript
101
- * {
102
- * provider: { companyProvider: "Google Workspace", ... },
103
- * detectionMethod: "mx_record",
104
- * proxyService: undefined
105
- * }
106
- * ```
107
- */
108
- export interface DNSDetectionResult {
109
- /** The detected email provider, or null if not found/behind proxy */
110
- provider: EmailProvider | null;
111
- /** Method used for DNS-based detection */
112
- detectionMethod: 'mx_record' | 'txt_record' | 'proxy_detected' | null;
113
- /** If a proxy service was detected, which service (e.g., 'Cloudflare') */
114
- proxyService?: string;
115
- }
116
- /**
117
- * Validates if a string is a valid email address using a basic regex pattern.
118
- *
119
- * @param email - The string to validate as an email address
120
- * @returns true if the string matches basic email format, false otherwise
121
- *
122
- * @example
123
- * ```typescript
124
- * isValidEmail('user@gmail.com'); // true
125
- * isValidEmail('invalid-email'); // false
126
- * isValidEmail('user@domain'); // false
127
- * ```
128
- *
129
- * @remarks
130
- * This uses a simple regex pattern that covers most common email formats.
131
- * It may not catch all edge cases defined in RFC 5322, but works for
132
- * standard email addresses.
26
+ * Check if an email provider is supported
27
+ * @param email - Email address to check
28
+ * @returns true if the provider is supported
133
29
  */
134
- export declare function isValidEmail(email: string): boolean;
30
+ export declare function isEmailProviderSupported(email: string): boolean;
135
31
  /**
136
- * Extracts the domain portion from an email address.
137
- *
138
- * @param email - The email address to extract the domain from
139
- * @returns The domain in lowercase, or null if the email is invalid
140
- *
141
- * @example
142
- * ```typescript
143
- * extractDomain('user@Gmail.com'); // 'gmail.com'
144
- * extractDomain('test@yahoo.co.uk'); // 'yahoo.co.uk'
145
- * extractDomain('invalid-email'); // null
146
- * ```
147
- *
148
- * @remarks
149
- * The domain is automatically normalized to lowercase for consistent matching.
32
+ * Extract domain from email address
33
+ * @param email - Email address
34
+ * @returns Domain portion or null if invalid
150
35
  */
151
36
  export declare function extractDomain(email: string): string | null;
152
37
  /**
153
- * Finds an email provider by matching the domain against the known providers database.
154
- * Uses an optimized Map for O(1) lookup performance.
155
- *
156
- * @param domain - The email domain to look up (e.g., 'gmail.com')
157
- * @returns The matching EmailProvider object, or null if not found
158
- *
159
- * @example
160
- * ```typescript
161
- * const provider = findEmailProvider('gmail.com');
162
- * console.log(provider?.companyProvider); // 'Gmail'
163
- * console.log(provider?.loginUrl); // 'https://mail.google.com/mail/'
164
- * ```
165
- *
166
- * @remarks
167
- * This function performs a case-insensitive O(1) lookup using a pre-built Map.
168
- * It only checks the predefined JSON database, not DNS records.
169
- * Performance optimized from O(n*m) to O(1) where n=providers, m=domains per provider.
38
+ * Validate email format
39
+ * @param email - Email address to validate
40
+ * @returns true if valid format
170
41
  */
171
- export declare function findEmailProvider(domain: string): EmailProvider | null;
172
- /**
173
- * Gets email provider information and login URL for a given email address.
174
- * This is the basic/synchronous version that only checks predefined domains.
175
- *
176
- * @param email - The email address to analyze
177
- * @returns EmailProviderResult containing provider info and login URL
178
- *
179
- * @example
180
- * ```typescript
181
- * const result = getEmailProviderLink('user@gmail.com');
182
- * console.log(result.loginUrl); // 'https://mail.google.com/mail/'
183
- * console.log(result.provider?.companyProvider); // 'Gmail'
184
- * ```
185
- *
186
- * @remarks
187
- * This function only checks against the predefined JSON database of known domains.
188
- * It will NOT detect business domains that use major email providers (e.g.,
189
- * mycompany.com using Google Workspace). For comprehensive detection including
190
- * business domains, use {@link getEmailProviderLinkWithDNS} instead.
191
- *
192
- * **Limitations:**
193
- * - Only synchronous operation (no DNS lookups)
194
- * - Limited to domains in the JSON database
195
- * - Won't detect custom business domains
196
- * - No proxy service detection
197
- */
198
- export declare function getEmailProviderLink(email: string): EmailProviderResult;
199
- /**
200
- * Returns an array of all supported email providers.
201
- *
202
- * @returns A copy of the EMAIL_PROVIDERS array
203
- *
204
- * @example
205
- * ```typescript
206
- * const providers = getSupportedProviders();
207
- * console.log(providers.length); // 55+
208
- * console.log(providers[0].companyProvider); // 'Gmail'
209
- * ```
210
- *
211
- * @remarks
212
- * Returns a shallow copy to prevent external modification of the internal
213
- * providers array. The returned array includes both consumer email providers
214
- * (gmail.com, yahoo.com) and business email providers with DNS detection patterns.
215
- */
216
- export declare function getSupportedProviders(): EmailProvider[];
217
- /**
218
- * Checks if an email address uses a supported email provider.
219
- *
220
- * @param email - The email address to check
221
- * @returns true if the provider is supported, false otherwise
222
- *
223
- * @example
224
- * ```typescript
225
- * isEmailProviderSupported('user@gmail.com'); // true
226
- * isEmailProviderSupported('user@unknown.com'); // false
227
- * ```
228
- *
229
- * @remarks
230
- * This is a convenience function that uses {@link getEmailProviderLink} internally.
231
- * It only checks predefined domains, not DNS-based detection. For business
232
- * domain support checking, you would need to use {@link getEmailProviderLinkWithDNS}.
233
- */
234
- export declare function isEmailProviderSupported(email: string): boolean;
235
- /**
236
- * Performs DNS-based detection for custom business domains using MX and TXT record analysis.
237
- * This function is used internally by {@link getEmailProviderLinkWithDNS} but can also be
238
- * called directly to analyze domain email configuration.
239
- *
240
- * @param domain - The domain to analyze (e.g., 'mycompany.com')
241
- * @param timeoutMs - Optional timeout for DNS queries in milliseconds (default: 5000ms)
242
- * @returns Promise resolving to DNSDetectionResult with provider info or proxy detection
243
- *
244
- * @example
245
- * ```typescript
246
- * const result = await detectProviderByDNS('microsoft.com');
247
- * console.log(result.provider?.companyProvider); // 'Microsoft 365 (Business)'
248
- * console.log(result.detectionMethod); // 'mx_record'
249
- * ```
250
- *
251
- * @remarks
252
- * **Detection Algorithm:**
253
- * 1. Checks rate limiting (max 10 requests per minute)
254
- * 2. Performs MX record lookup for the domain
255
- * 3. Checks if MX records match known proxy services (Cloudflare, etc.)
256
- * 4. If proxy detected, returns null provider with proxy info
257
- * 5. Otherwise, matches MX records against business email provider patterns
258
- * 6. If no MX match, falls back to TXT record analysis (SPF records, etc.)
259
- * 7. Returns the first matching provider or null if none found
260
- *
261
- * **Rate Limiting:**
262
- * - Maximum 10 DNS requests per 60-second window
263
- * - Rate limit exceeded returns error with retry information
264
- * - Prevents abuse and excessive DNS queries
265
- *
266
- * **Provider Patterns Checked:**
267
- * - Google Workspace: aspmx.l.google.com, aspmx2.googlemail.com, etc.
268
- * - Microsoft 365: *.protection.outlook.com, *.outlook.com
269
- * - ProtonMail: mail.protonmail.ch, mailsec.protonmail.ch
270
- * - FastMail: *.messagingengine.com
271
- * - And many others...
272
- *
273
- * **Error Handling:**
274
- * DNS lookup failures are caught and the function gracefully falls back
275
- * to the next detection method or returns null if all methods fail.
276
- */
277
- export declare function detectProviderByDNS(domain: string, timeoutMs?: number): Promise<DNSDetectionResult>;
42
+ export declare function isValidEmail(email: string): boolean;
278
43
  /**
279
- * Enhanced email provider detection with automatic DNS-based custom domain detection.
280
- * This is the recommended function for most use cases as it provides comprehensive
281
- * detection coverage including business domains and proxy services.
282
- *
283
- * @param email - The email address to analyze
284
- * @param timeoutMs - Optional timeout for DNS queries in milliseconds (default: 5000ms)
285
- * @returns Promise resolving to EmailProviderResult with provider info and detection method
286
- *
287
- * @example
288
- * ```typescript
289
- * // Consumer email (fast domain match)
290
- * const gmail = await getEmailProviderLinkWithDNS('user@gmail.com');
291
- * console.log(gmail.provider?.companyProvider); // 'Gmail'
292
- * console.log(gmail.detectionMethod); // 'domain_match'
293
- *
294
- * // Business domain (DNS detection)
295
- * const business = await getEmailProviderLinkWithDNS('user@mycompany.com');
296
- * console.log(business.provider?.companyProvider); // 'Google Workspace' (if detected)
297
- * console.log(business.detectionMethod); // 'mx_record'
298
- *
299
- * // Proxied domain (proxy detection)
300
- * const proxied = await getEmailProviderLinkWithDNS('user@proxied-domain.com');
301
- * console.log(proxied.provider); // null
302
- * console.log(proxied.proxyService); // 'Cloudflare'
303
- * console.log(proxied.detectionMethod); // 'proxy_detected'
304
- * ```
305
- *
306
- * @remarks
307
- * **Detection Hierarchy (in order):**
308
- * 1. **Domain Match**: Fast lookup against predefined domains (gmail.com, yahoo.com, etc.)
309
- * 2. **DNS MX Records**: Analyzes mail exchange records for business email providers
310
- * 3. **DNS TXT Records**: Checks SPF and verification records as fallback
311
- * 4. **Proxy Detection**: Identifies when domains are behind CDN/proxy services
312
- *
313
- * **Supported Detection Cases:**
314
- * - ✅ Consumer emails: gmail.com, yahoo.com, outlook.com, etc.
315
- * - ✅ Business domains: Google Workspace, Microsoft 365, ProtonMail Business, etc.
316
- * - ✅ Proxy services: Cloudflare, CloudFront, Fastly, etc.
317
- * - ✅ International providers: QQ Mail, NetEase, Yandex, etc.
318
- *
319
- * **Performance:**
320
- * - Fast for known consumer domains (synchronous JSON lookup)
321
- * - Additional DNS lookup time for unknown domains (~100-500ms)
322
- * - Graceful degradation if DNS lookups fail
323
- *
324
- * **Error Handling:**
325
- * - Invalid email addresses return null provider
326
- * - DNS lookup failures are caught and don't throw errors
327
- * - Network timeouts gracefully fall back to null detection
328
- *
329
- * **Use Cases:**
330
- * - Password reset flows ("Check your Gmail inbox")
331
- * - Login form enhancements (direct links to email providers)
332
- * - Email client detection for support purposes
333
- * - Business domain analysis for enterprise features
44
+ * Library metadata
334
45
  */
335
- export declare function getEmailProviderLinkWithDNS(email: string, timeoutMs?: number): Promise<EmailProviderResult>;
46
+ export declare const PROVIDER_COUNT = 93;
47
+ export declare const DOMAIN_COUNT = 178;
336
48
  /**
337
- * Rate limiting configuration constants and utilities.
338
- * @public
49
+ * Default export for convenience
339
50
  */
340
- export declare const RateLimit: {
341
- MAX_REQUESTS: number;
342
- WINDOW_MS: number;
343
- SimpleRateLimiter: typeof SimpleRateLimiter;
344
- /**
345
- * Gets the current rate limiter instance for inspection or testing.
346
- * @internal
347
- */
348
- getCurrentLimiter: () => SimpleRateLimiter;
349
- };
350
- export * from './alias-detection';
351
- export * from './security/url-validator';
352
- export * from './security/hash-verifier';
353
- export * from './security/secure-loader';
354
51
  declare const _default: {
355
- getEmailProviderLink: typeof getEmailProviderLink;
356
- getEmailProviderLinkWithDNS: typeof getEmailProviderLinkWithDNS;
357
- detectProviderByDNS: typeof detectProviderByDNS;
358
- isValidEmail: typeof isValidEmail;
359
- extractDomain: typeof extractDomain;
360
- findEmailProvider: typeof findEmailProvider;
361
- getSupportedProviders: typeof getSupportedProviders;
362
- isEmailProviderSupported: typeof isEmailProviderSupported;
363
- RateLimit: {
364
- MAX_REQUESTS: number;
365
- WINDOW_MS: number;
366
- SimpleRateLimiter: typeof SimpleRateLimiter;
367
- /**
368
- * Gets the current rate limiter instance for inspection or testing.
369
- * @internal
370
- */
371
- getCurrentLimiter: () => SimpleRateLimiter;
52
+ getEmailProvider: typeof getEmailProvider;
53
+ getEmailProviderSync: typeof getEmailProviderSync;
54
+ getEmailProviderFast: typeof getEmailProviderFast;
55
+ normalizeEmail: typeof normalizeEmail;
56
+ emailsMatch: typeof emailsMatch;
57
+ Config: {
58
+ readonly DEFAULT_DNS_TIMEOUT: 5000;
59
+ readonly MAX_DNS_REQUESTS_PER_MINUTE: 10;
60
+ readonly SUPPORTED_PROVIDERS_COUNT: 93;
61
+ readonly SUPPORTED_DOMAINS_COUNT: 180;
372
62
  };
63
+ PROVIDER_COUNT: number;
64
+ DOMAIN_COUNT: number;
373
65
  };
374
66
  export default _default;