feat(rust): scaffold Rust workspace and fix TypeScript build errors
- Add @git.zone/tsrust with linux_amd64/linux_arm64 cross-compilation - Scaffold Rust workspace with 5 crates: mailer-core, mailer-smtp, mailer-security, mailer-napi, mailer-bin - Fix all TypeScript compilation errors for upgraded dependencies (smartfile v13, mailauth v4.13, smartproxy v23) - Replace smartfile.fs/memory with @push.rocks/smartfs throughout codebase - Fix .ts import extensions to .js for NodeNext module resolution - Update DKIMSignOptions usage to match mailauth v4.13 API - Add MTA error classes with permissive signatures for legacy SMTP client - Replace removed DcRouter/StorageManager/deliverability imports with local interfaces
This commit is contained in:
@@ -1,8 +1,18 @@
|
||||
import * as plugins from '../../plugins.ts';
|
||||
import type { IEmailDomainConfig } from './interfaces.ts';
|
||||
import { logger } from '../../logger.ts';
|
||||
import type { DcRouter } from '../../classes.dcrouter.ts';
|
||||
import type { StorageManager } from '../../storage/index.ts';
|
||||
import * as plugins from '../../plugins.js';
|
||||
import type { IEmailDomainConfig } from './interfaces.js';
|
||||
import { logger } from '../../logger.js';
|
||||
/** External DcRouter interface shape used by DnsManager */
|
||||
interface IDcRouterLike {
|
||||
storageManager: IStorageManagerLike;
|
||||
dnsServer?: any;
|
||||
options?: { dnsNsDomains?: string[]; dnsScopes?: string[] };
|
||||
}
|
||||
|
||||
/** External StorageManager interface shape used by DnsManager */
|
||||
interface IStorageManagerLike {
|
||||
get(key: string): Promise<string | null>;
|
||||
set(key: string, value: string): Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* DNS validation result
|
||||
@@ -30,10 +40,10 @@ interface IDnsRecords {
|
||||
* Handles both validation and creation of DNS records
|
||||
*/
|
||||
export class DnsManager {
|
||||
private dcRouter: DcRouter;
|
||||
private storageManager: StorageManager;
|
||||
private dcRouter: IDcRouterLike;
|
||||
private storageManager: IStorageManagerLike;
|
||||
|
||||
constructor(dcRouter: DcRouter) {
|
||||
constructor(dcRouter: IDcRouterLike) {
|
||||
this.dcRouter = dcRouter;
|
||||
this.storageManager = dcRouter.storageManager;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as plugins from '../../plugins.ts';
|
||||
import * as paths from '../../paths.ts';
|
||||
import { DKIMCreator } from '../security/classes.dkimcreator.ts';
|
||||
import * as plugins from '../../plugins.js';
|
||||
import * as paths from '../../paths.js';
|
||||
import { DKIMCreator } from '../security/classes.dkimcreator.js';
|
||||
|
||||
/**
|
||||
* Interface for DNS record information
|
||||
@@ -57,7 +57,7 @@ export class DNSManager {
|
||||
}
|
||||
|
||||
// Ensure the DNS records directory exists
|
||||
plugins.smartfile.fs.ensureDirSync(paths.dnsRecordsDir);
|
||||
plugins.fs.mkdirSync(paths.dnsRecordsDir, { recursive: true });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -417,7 +417,7 @@ export class DNSManager {
|
||||
public async saveDnsRecommendations(domain: string, records: IDnsRecord[]): Promise<void> {
|
||||
try {
|
||||
const filePath = plugins.path.join(paths.dnsRecordsDir, `${domain}.recommendations.json`);
|
||||
plugins.smartfile.memory.toFsSync(JSON.stringify(records, null, 2), filePath);
|
||||
await plugins.smartfs.file(filePath).write(JSON.stringify(records, null, 2));
|
||||
console.log(`DNS recommendations for ${domain} saved to ${filePath}`);
|
||||
} catch (error) {
|
||||
console.error(`Error saving DNS recommendations for ${domain}:`, error);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { IEmailDomainConfig } from './interfaces.ts';
|
||||
import { logger } from '../../logger.ts';
|
||||
import type { IEmailDomainConfig } from './interfaces.js';
|
||||
import { logger } from '../../logger.js';
|
||||
|
||||
/**
|
||||
* Registry for email domain configurations
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { EmailProcessingMode } from '../delivery/interfaces.ts';
|
||||
import type { EmailProcessingMode } from '../delivery/interfaces.js';
|
||||
|
||||
// Re-export EmailProcessingMode type
|
||||
export type { EmailProcessingMode };
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as plugins from '../../plugins.ts';
|
||||
import * as plugins from '../../plugins.js';
|
||||
import { EventEmitter } from 'node:events';
|
||||
import type { IEmailRoute, IEmailMatch, IEmailAction, IEmailContext } from './interfaces.ts';
|
||||
import type { Email } from '../core/classes.email.ts';
|
||||
import type { IEmailRoute, IEmailMatch, IEmailAction, IEmailContext } from './interfaces.js';
|
||||
import type { Email } from '../core/classes.email.js';
|
||||
|
||||
/**
|
||||
* Email router that evaluates routes and determines actions
|
||||
|
||||
@@ -1,35 +1,63 @@
|
||||
import * as plugins from '../../plugins.ts';
|
||||
import * as paths from '../../paths.ts';
|
||||
import * as plugins from '../../plugins.js';
|
||||
import * as paths from '../../paths.js';
|
||||
import { EventEmitter } from 'events';
|
||||
import { logger } from '../../logger.ts';
|
||||
import { logger } from '../../logger.js';
|
||||
import {
|
||||
SecurityLogger,
|
||||
SecurityLogLevel,
|
||||
SecurityEventType
|
||||
} from '../../security/index.ts';
|
||||
import { DKIMCreator } from '../security/classes.dkimcreator.ts';
|
||||
import { IPReputationChecker } from '../../security/classes.ipreputationchecker.ts';
|
||||
import {
|
||||
IPWarmupManager,
|
||||
type IIPWarmupConfig,
|
||||
SenderReputationMonitor,
|
||||
type IReputationMonitorConfig
|
||||
} from '../../deliverability/index.ts';
|
||||
import { EmailRouter } from './classes.email.router.ts';
|
||||
import type { IEmailRoute, IEmailAction, IEmailContext, IEmailDomainConfig } from './interfaces.ts';
|
||||
import { Email } from '../core/classes.email.ts';
|
||||
import { DomainRegistry } from './classes.domain.registry.ts';
|
||||
import { DnsManager } from './classes.dns.manager.ts';
|
||||
import { BounceManager, BounceType, BounceCategory } from '../core/classes.bouncemanager.ts';
|
||||
import { createSmtpServer } from '../delivery/smtpserver/index.ts';
|
||||
import { createPooledSmtpClient } from '../delivery/smtpclient/create-client.ts';
|
||||
import type { SmtpClient } from '../delivery/smtpclient/smtp-client.ts';
|
||||
import { MultiModeDeliverySystem, type IMultiModeDeliveryOptions } from '../delivery/classes.delivery.system.ts';
|
||||
import { UnifiedDeliveryQueue, type IQueueOptions } from '../delivery/classes.delivery.queue.ts';
|
||||
import { UnifiedRateLimiter, type IHierarchicalRateLimits } from '../delivery/classes.unified.rate.limiter.ts';
|
||||
import { SmtpState } from '../delivery/interfaces.ts';
|
||||
import type { EmailProcessingMode, ISmtpSession as IBaseSmtpSession } from '../delivery/interfaces.ts';
|
||||
import type { DcRouter } from '../../classes.dcrouter.ts';
|
||||
} from '../../security/index.js';
|
||||
import { DKIMCreator } from '../security/classes.dkimcreator.js';
|
||||
import { IPReputationChecker } from '../../security/classes.ipreputationchecker.js';
|
||||
// Deliverability types (IPWarmupManager and SenderReputationMonitor are optional external modules)
|
||||
interface IIPWarmupConfig {
|
||||
enabled?: boolean;
|
||||
ips?: string[];
|
||||
[key: string]: any;
|
||||
}
|
||||
interface IReputationMonitorConfig {
|
||||
enabled?: boolean;
|
||||
domains?: string[];
|
||||
[key: string]: any;
|
||||
}
|
||||
interface IPWarmupManager {
|
||||
getWarmupStatus(ip: string): any;
|
||||
addIPToWarmup(ip: string, config?: any): void;
|
||||
removeIPFromWarmup(ip: string): void;
|
||||
updateMetrics(ip: string, metrics: any): void;
|
||||
canSendMoreToday(ip: string): boolean;
|
||||
canSendMoreThisHour(ip: string): boolean;
|
||||
getBestIPForSending(...args: any[]): string | null;
|
||||
setActiveAllocationPolicy(policy: string): void;
|
||||
recordSend(...args: any[]): void;
|
||||
}
|
||||
interface SenderReputationMonitor {
|
||||
getReputationData(domain: string): any;
|
||||
getReputationSummary(): any;
|
||||
addDomain(domain: string): void;
|
||||
removeDomain(domain: string): void;
|
||||
recordSendEvent(domain: string, event: any): void;
|
||||
}
|
||||
import { EmailRouter } from './classes.email.router.js';
|
||||
import type { IEmailRoute, IEmailAction, IEmailContext, IEmailDomainConfig } from './interfaces.js';
|
||||
import { Email } from '../core/classes.email.js';
|
||||
import { DomainRegistry } from './classes.domain.registry.js';
|
||||
import { DnsManager } from './classes.dns.manager.js';
|
||||
import { BounceManager, BounceType, BounceCategory } from '../core/classes.bouncemanager.js';
|
||||
import { createSmtpServer } from '../delivery/smtpserver/index.js';
|
||||
import { createPooledSmtpClient } from '../delivery/smtpclient/create-client.js';
|
||||
import type { SmtpClient } from '../delivery/smtpclient/smtp-client.js';
|
||||
import { MultiModeDeliverySystem, type IMultiModeDeliveryOptions } from '../delivery/classes.delivery.system.js';
|
||||
import { UnifiedDeliveryQueue, type IQueueOptions } from '../delivery/classes.delivery.queue.js';
|
||||
import { UnifiedRateLimiter, type IHierarchicalRateLimits } from '../delivery/classes.unified.rate.limiter.js';
|
||||
import { SmtpState } from '../delivery/interfaces.js';
|
||||
import type { EmailProcessingMode, ISmtpSession as IBaseSmtpSession } from '../delivery/interfaces.js';
|
||||
/** External DcRouter interface shape used by UnifiedEmailServer */
|
||||
interface DcRouter {
|
||||
storageManager: any;
|
||||
dnsServer?: any;
|
||||
options?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extended SMTP session interface with route information
|
||||
@@ -127,7 +155,7 @@ export interface ISmtpSession extends IBaseSmtpSession {
|
||||
/**
|
||||
* Authentication data for SMTP
|
||||
*/
|
||||
import type { ISmtpAuth } from '../delivery/interfaces.ts';
|
||||
import type { ISmtpAuth } from '../delivery/interfaces.js';
|
||||
export type IAuthData = ISmtpAuth;
|
||||
|
||||
/**
|
||||
@@ -166,8 +194,8 @@ export class UnifiedEmailServer extends EventEmitter {
|
||||
public dkimCreator: DKIMCreator;
|
||||
private ipReputationChecker: IPReputationChecker; // TODO: Implement IP reputation checks in processEmailByMode
|
||||
private bounceManager: BounceManager;
|
||||
private ipWarmupManager: IPWarmupManager;
|
||||
private senderReputationMonitor: SenderReputationMonitor;
|
||||
private ipWarmupManager: IPWarmupManager | null;
|
||||
private senderReputationMonitor: SenderReputationMonitor | null;
|
||||
public deliveryQueue: UnifiedDeliveryQueue;
|
||||
public deliverySystem: MultiModeDeliverySystem;
|
||||
private rateLimiter: UnifiedRateLimiter; // TODO: Implement rate limiting in SMTP server handlers
|
||||
@@ -206,21 +234,10 @@ export class UnifiedEmailServer extends EventEmitter {
|
||||
storageManager: dcRouter.storageManager
|
||||
});
|
||||
|
||||
// Initialize IP warmup manager
|
||||
this.ipWarmupManager = IPWarmupManager.getInstance(options.ipWarmupConfig || {
|
||||
enabled: true,
|
||||
ipAddresses: [],
|
||||
targetDomains: []
|
||||
});
|
||||
|
||||
// Initialize sender reputation monitor with storage manager
|
||||
this.senderReputationMonitor = SenderReputationMonitor.getInstance(
|
||||
options.reputationMonitorConfig || {
|
||||
enabled: true,
|
||||
domains: []
|
||||
},
|
||||
dcRouter.storageManager
|
||||
);
|
||||
// IP warmup manager and sender reputation monitor are optional
|
||||
// They will be initialized when the deliverability module is available
|
||||
this.ipWarmupManager = null;
|
||||
this.senderReputationMonitor = null;
|
||||
|
||||
// Initialize domain registry
|
||||
this.domainRegistry = new DomainRegistry(options.domains, options.defaults);
|
||||
@@ -836,15 +853,21 @@ export class UnifiedEmailServer extends EventEmitter {
|
||||
}
|
||||
|
||||
// Sign the email
|
||||
const dkimDomain = options.dkimOptions.domainName;
|
||||
const dkimSelector = options.dkimOptions.keySelector || 'mta';
|
||||
const dkimPrivateKey = (await this.dkimCreator.readDKIMKeys(dkimDomain)).privateKey;
|
||||
const signResult = await plugins.dkimSign(rawEmail, {
|
||||
signingDomain: dkimDomain,
|
||||
selector: dkimSelector,
|
||||
privateKey: dkimPrivateKey,
|
||||
canonicalization: 'relaxed/relaxed',
|
||||
algorithm: 'rsa-sha256',
|
||||
signTime: new Date(),
|
||||
signatureData: [
|
||||
{
|
||||
signingDomain: options.dkimOptions.domainName,
|
||||
selector: options.dkimOptions.keySelector || 'mta',
|
||||
privateKey: (await this.dkimCreator.readDKIMKeys(options.dkimOptions.domainName)).privateKey,
|
||||
signingDomain: dkimDomain,
|
||||
selector: dkimSelector,
|
||||
privateKey: dkimPrivateKey,
|
||||
algorithm: 'rsa-sha256',
|
||||
canonicalization: 'relaxed/relaxed'
|
||||
}
|
||||
@@ -1435,6 +1458,9 @@ export class UnifiedEmailServer extends EventEmitter {
|
||||
|
||||
// Sign the email
|
||||
const signResult = await plugins.dkimSign(rawEmail, {
|
||||
signingDomain: domain,
|
||||
selector: selector,
|
||||
privateKey: privateKey,
|
||||
canonicalization: 'relaxed/relaxed',
|
||||
algorithm: 'rsa-sha256',
|
||||
signTime: new Date(),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Email routing components
|
||||
export * from './classes.email.router.ts';
|
||||
export * from './classes.unified.email.server.ts';
|
||||
export * from './classes.dns.manager.ts';
|
||||
export * from './interfaces.ts';
|
||||
export * from './classes.domain.registry.ts';
|
||||
export * from './classes.email.router.js';
|
||||
export * from './classes.unified.email.server.js';
|
||||
export * from './classes.dns.manager.js';
|
||||
export * from './interfaces.js';
|
||||
export * from './classes.domain.registry.js';
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Email } from '../core/classes.email.ts';
|
||||
import type { IExtendedSmtpSession } from './classes.unified.email.server.ts';
|
||||
import type { Email } from '../core/classes.email.js';
|
||||
import type { IExtendedSmtpSession } from './classes.unified.email.server.js';
|
||||
|
||||
/**
|
||||
* Route configuration for email routing
|
||||
|
||||
Reference in New Issue
Block a user