Files
dcrouter/ts/mail/routing/classes.domain.registry.ts

139 lines
3.6 KiB
TypeScript

import type { IEmailDomainConfig } from './interfaces.js';
import { logger } from '../../logger.js';
/**
* 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);
}
}