import { tap, expect } from '@git.zone/tstest/tapbundle'; import * as plugins from '../ts/plugins.js'; import { EmailDomainManager } from '../ts/email/index.js'; import { DcRouterDb, DomainDoc } from '../ts/db/index.js'; import { EmailDomainDoc } from '../ts/db/documents/classes.email-domain.doc.js'; import type { IUnifiedEmailServerOptions } from '@push.rocks/smartmta'; const createTestDb = async () => { const storagePath = plugins.path.join( plugins.os.tmpdir(), `dcrouter-email-domain-manager-${Date.now()}-${Math.random().toString(16).slice(2)}`, ); DcRouterDb.resetInstance(); const db = DcRouterDb.getInstance({ storagePath, dbName: `dcrouter-email-domain-${Date.now()}-${Math.random().toString(16).slice(2)}`, }); await db.start(); await db.getDb().mongoDb.createCollection('__test_init'); return { async cleanup() { await db.stop(); DcRouterDb.resetInstance(); await plugins.fs.promises.rm(storagePath, { recursive: true, force: true }); }, }; }; const testDbPromise = createTestDb(); const clearTestState = async () => { for (const emailDomain of await EmailDomainDoc.findAll()) { await emailDomain.delete(); } for (const domain of await DomainDoc.findAll()) { await domain.delete(); } }; const createDomainDoc = async (id: string, name: string, source: 'dcrouter' | 'provider') => { const doc = new DomainDoc(); doc.id = id; doc.name = name; doc.source = source; doc.authoritative = source === 'dcrouter'; doc.createdAt = Date.now(); doc.updatedAt = Date.now(); doc.createdBy = 'test'; await doc.save(); return doc; }; const createBaseEmailConfig = (): IUnifiedEmailServerOptions => ({ ports: [2525], hostname: 'mail.example.com', domains: [ { domain: 'static.example.com', dnsMode: 'external-dns', }, ], routes: [], }); tap.test('EmailDomainManager syncs managed domains into runtime config and email server', async () => { await testDbPromise; await clearTestState(); const linkedDomain = await createDomainDoc('provider-domain', 'example.com', 'provider'); const updateCalls: Array<{ domains?: any[] }> = []; const dcRouterStub = { options: { emailConfig: createBaseEmailConfig(), }, emailServer: { updateOptions: (options: { domains?: any[] }) => { updateCalls.push(options); }, }, }; const manager = new EmailDomainManager(dcRouterStub); await manager.start(); const created = await manager.createEmailDomain({ linkedDomainId: linkedDomain.id, subdomain: 'mail', dkimSelector: 'selector1', rotateKeys: true, rotationIntervalDays: 30, }); const domainsAfterCreate = dcRouterStub.options.emailConfig.domains; expect(domainsAfterCreate.length).toEqual(2); expect(domainsAfterCreate.some((domain) => domain.domain === 'static.example.com')).toEqual(true); const managedDomain = domainsAfterCreate.find((domain) => domain.domain === 'mail.example.com'); expect(managedDomain).toBeTruthy(); expect(managedDomain?.dnsMode).toEqual('external-dns'); expect(managedDomain?.dkim?.selector).toEqual('selector1'); expect(updateCalls.at(-1)?.domains?.some((domain) => domain.domain === 'mail.example.com')).toEqual(true); await manager.updateEmailDomain(created.id, { rotateKeys: false, rateLimits: { outbound: { messagesPerMinute: 10, }, }, }); const domainsAfterUpdate = dcRouterStub.options.emailConfig.domains; const updatedManagedDomain = domainsAfterUpdate.find((domain) => domain.domain === 'mail.example.com'); expect(updatedManagedDomain?.dkim?.rotateKeys).toEqual(false); expect(updatedManagedDomain?.rateLimits?.outbound?.messagesPerMinute).toEqual(10); await manager.deleteEmailDomain(created.id); expect(dcRouterStub.options.emailConfig.domains.map((domain) => domain.domain)).toEqual(['static.example.com']); }); tap.test('EmailDomainManager rejects domains already present in static config', async () => { await testDbPromise; await clearTestState(); const linkedDomain = await createDomainDoc('static-domain', 'static.example.com', 'provider'); const dcRouterStub = { options: { emailConfig: createBaseEmailConfig(), }, }; const manager = new EmailDomainManager(dcRouterStub); let error: Error | undefined; try { await manager.createEmailDomain({ linkedDomainId: linkedDomain.id }); } catch (err: unknown) { error = err as Error; } expect(error?.message).toEqual('Email domain already configured for static.example.com'); }); tap.test('EmailDomainManager start merges persisted managed domains after restart', async () => { await testDbPromise; await clearTestState(); const linkedDomain = await createDomainDoc('local-domain', 'managed.example.com', 'dcrouter'); const stored = new EmailDomainDoc(); stored.id = 'managed-email-domain'; stored.domain = 'mail.managed.example.com'; stored.linkedDomainId = linkedDomain.id; stored.subdomain = 'mail'; stored.dkim = { selector: 'default', keySize: 2048, rotateKeys: false, rotationIntervalDays: 90, }; stored.dnsStatus = { mx: 'unchecked', spf: 'unchecked', dkim: 'unchecked', dmarc: 'unchecked', }; stored.createdAt = new Date().toISOString(); stored.updatedAt = new Date().toISOString(); await stored.save(); const dcRouterStub = { options: { emailConfig: createBaseEmailConfig(), }, }; const manager = new EmailDomainManager(dcRouterStub); await manager.start(); const managedDomain = dcRouterStub.options.emailConfig.domains.find((domain) => domain.domain === 'mail.managed.example.com'); expect(managedDomain?.dnsMode).toEqual('internal-dns'); }); tap.test('cleanup', async () => { const testDb = await testDbPromise; await clearTestState(); await testDb.cleanup(); await tap.stopForcefully(); }); export default tap.start();