139 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import type { IEmailDomainConfig } from './interfaces.ts';
 | |
| import { logger } from '../../logger.ts';
 | |
| 
 | |
| /**
 | |
|  * Registry for email domain configurations
 | |
|  * Provides fast lookups and validation for domains
 | |
|  */
 | |
| export class DomainRegistry {
 | |
|   private domains: Map<string, IEmailDomainConfig> = new Map();
 | |
|   private defaults: IEmailDomainConfig['dkim'] & {
 | |
|     dnsMode?: 'forward' | 'internal-dns' | 'external-dns';
 | |
|     rateLimits?: IEmailDomainConfig['rateLimits'];
 | |
|   };
 | |
|   
 | |
|   constructor(
 | |
|     domainConfigs: IEmailDomainConfig[],
 | |
|     defaults?: {
 | |
|       dnsMode?: 'forward' | 'internal-dns' | 'external-dns';
 | |
|       dkim?: IEmailDomainConfig['dkim'];
 | |
|       rateLimits?: IEmailDomainConfig['rateLimits'];
 | |
|     }
 | |
|   ) {
 | |
|     // Set defaults
 | |
|     this.defaults = {
 | |
|       dnsMode: defaults?.dnsMode || 'external-dns',
 | |
|       ...this.getDefaultDkimConfig(),
 | |
|       ...defaults?.dkim,
 | |
|       rateLimits: defaults?.rateLimits
 | |
|     };
 | |
|     
 | |
|     // Process and store domain configurations
 | |
|     for (const config of domainConfigs) {
 | |
|       const processedConfig = this.applyDefaults(config);
 | |
|       this.domains.set(config.domain.toLowerCase(), processedConfig);
 | |
|       logger.log('info', `Registered domain: ${config.domain} with DNS mode: ${processedConfig.dnsMode}`);
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   /**
 | |
|    * Get default DKIM configuration
 | |
|    */
 | |
|   private getDefaultDkimConfig(): IEmailDomainConfig['dkim'] {
 | |
|     return {
 | |
|       selector: 'default',
 | |
|       keySize: 2048,
 | |
|       rotateKeys: false,
 | |
|       rotationInterval: 90
 | |
|     };
 | |
|   }
 | |
|   
 | |
|   /**
 | |
|    * Apply defaults to a domain configuration
 | |
|    */
 | |
|   private applyDefaults(config: IEmailDomainConfig): IEmailDomainConfig {
 | |
|     return {
 | |
|       ...config,
 | |
|       dnsMode: config.dnsMode || this.defaults.dnsMode!,
 | |
|       dkim: {
 | |
|         ...this.getDefaultDkimConfig(),
 | |
|         ...this.defaults,
 | |
|         ...config.dkim
 | |
|       },
 | |
|       rateLimits: {
 | |
|         ...this.defaults.rateLimits,
 | |
|         ...config.rateLimits,
 | |
|         outbound: {
 | |
|           ...this.defaults.rateLimits?.outbound,
 | |
|           ...config.rateLimits?.outbound
 | |
|         },
 | |
|         inbound: {
 | |
|           ...this.defaults.rateLimits?.inbound,
 | |
|           ...config.rateLimits?.inbound
 | |
|         }
 | |
|       }
 | |
|     };
 | |
|   }
 | |
|   
 | |
|   /**
 | |
|    * Check if a domain is registered
 | |
|    */
 | |
|   isDomainRegistered(domain: string): boolean {
 | |
|     return this.domains.has(domain.toLowerCase());
 | |
|   }
 | |
|   
 | |
|   /**
 | |
|    * Check if an email address belongs to a registered domain
 | |
|    */
 | |
|   isEmailRegistered(email: string): boolean {
 | |
|     const domain = this.extractDomain(email);
 | |
|     if (!domain) return false;
 | |
|     return this.isDomainRegistered(domain);
 | |
|   }
 | |
|   
 | |
|   /**
 | |
|    * Get domain configuration
 | |
|    */
 | |
|   getDomainConfig(domain: string): IEmailDomainConfig | undefined {
 | |
|     return this.domains.get(domain.toLowerCase());
 | |
|   }
 | |
|   
 | |
|   /**
 | |
|    * Get domain configuration for an email address
 | |
|    */
 | |
|   getEmailDomainConfig(email: string): IEmailDomainConfig | undefined {
 | |
|     const domain = this.extractDomain(email);
 | |
|     if (!domain) return undefined;
 | |
|     return this.getDomainConfig(domain);
 | |
|   }
 | |
|   
 | |
|   /**
 | |
|    * Extract domain from email address
 | |
|    */
 | |
|   private extractDomain(email: string): string | null {
 | |
|     const parts = email.toLowerCase().split('@');
 | |
|     if (parts.length !== 2) return null;
 | |
|     return parts[1];
 | |
|   }
 | |
|   
 | |
|   /**
 | |
|    * Get all registered domains
 | |
|    */
 | |
|   getAllDomains(): string[] {
 | |
|     return Array.from(this.domains.keys());
 | |
|   }
 | |
|   
 | |
|   /**
 | |
|    * Get all domain configurations
 | |
|    */
 | |
|   getAllConfigs(): IEmailDomainConfig[] {
 | |
|     return Array.from(this.domains.values());
 | |
|   }
 | |
|   
 | |
|   /**
 | |
|    * Get domains by DNS mode
 | |
|    */
 | |
|   getDomainsByMode(mode: 'forward' | 'internal-dns' | 'external-dns'): IEmailDomainConfig[] {
 | |
|     return Array.from(this.domains.values()).filter(config => config.dnsMode === mode);
 | |
|   }
 | |
| } |