import * as plugins from '../../plugins.js'; import type { OpsServer } from '../classes.opsserver.js'; import * as interfaces from '../../../ts_interfaces/index.js'; /** * CRUD + DNS provisioning handler for email domains. * * Auth: admin JWT or API token with `email-domains:read` / `email-domains:write` scope. */ export class EmailDomainHandler { public typedrouter = new plugins.typedrequest.TypedRouter(); constructor(private opsServerRef: OpsServer) { this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter); this.registerHandlers(); } private async requireAuth( request: { identity?: interfaces.data.IIdentity; apiToken?: string }, requiredScope?: interfaces.data.TApiTokenScope, ): Promise { if (request.identity?.jwt) { try { const isAdmin = await this.opsServerRef.adminHandler.adminIdentityGuard.exec({ identity: request.identity, }); if (isAdmin) return request.identity.userId; } catch { /* fall through */ } } if (request.apiToken) { const tokenManager = this.opsServerRef.dcRouterRef.apiTokenManager; if (tokenManager) { const token = await tokenManager.validateToken(request.apiToken); if (token) { if (!requiredScope || tokenManager.hasScope(token, requiredScope)) { return token.createdBy; } throw new plugins.typedrequest.TypedResponseError('insufficient scope'); } } } throw new plugins.typedrequest.TypedResponseError('unauthorized'); } private get manager() { return this.opsServerRef.dcRouterRef.emailDomainManager; } private registerHandlers(): void { // List all email domains this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getEmailDomains', async (dataArg) => { await this.requireAuth(dataArg, 'email-domains:read' as any); if (!this.manager) return { domains: [] }; return { domains: await this.manager.getAll() }; }, ), ); // Get single email domain this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getEmailDomain', async (dataArg) => { await this.requireAuth(dataArg, 'email-domains:read' as any); if (!this.manager) return { domain: null }; return { domain: await this.manager.getById(dataArg.id) }; }, ), ); // Create email domain this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'createEmailDomain', async (dataArg) => { await this.requireAuth(dataArg, 'email-domains:write' as any); if (!this.manager) { return { success: false, message: 'EmailDomainManager not initialized' }; } try { const domain = await this.manager.createEmailDomain({ linkedDomainId: dataArg.linkedDomainId, dkimSelector: dataArg.dkimSelector, dkimKeySize: dataArg.dkimKeySize, rotateKeys: dataArg.rotateKeys, rotationIntervalDays: dataArg.rotationIntervalDays, }); return { success: true, domain }; } catch (err: unknown) { return { success: false, message: (err as Error).message }; } }, ), ); // Update email domain this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'updateEmailDomain', async (dataArg) => { await this.requireAuth(dataArg, 'email-domains:write' as any); if (!this.manager) { return { success: false, message: 'EmailDomainManager not initialized' }; } try { await this.manager.updateEmailDomain(dataArg.id, { rotateKeys: dataArg.rotateKeys, rotationIntervalDays: dataArg.rotationIntervalDays, rateLimits: dataArg.rateLimits, }); return { success: true }; } catch (err: unknown) { return { success: false, message: (err as Error).message }; } }, ), ); // Delete email domain this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'deleteEmailDomain', async (dataArg) => { await this.requireAuth(dataArg, 'email-domains:write' as any); if (!this.manager) { return { success: false, message: 'EmailDomainManager not initialized' }; } try { await this.manager.deleteEmailDomain(dataArg.id); return { success: true }; } catch (err: unknown) { return { success: false, message: (err as Error).message }; } }, ), ); // Validate DNS records this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'validateEmailDomain', async (dataArg) => { await this.requireAuth(dataArg, 'email-domains:read' as any); if (!this.manager) { return { success: false, message: 'EmailDomainManager not initialized' }; } try { const records = await this.manager.validateDns(dataArg.id); const domain = await this.manager.getById(dataArg.id); return { success: true, domain: domain ?? undefined, records }; } catch (err: unknown) { return { success: false, message: (err as Error).message }; } }, ), ); // Get required DNS records this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getEmailDomainDnsRecords', async (dataArg) => { await this.requireAuth(dataArg, 'email-domains:read' as any); if (!this.manager) return { records: [] }; return { records: await this.manager.getRequiredDnsRecords(dataArg.id) }; }, ), ); // Auto-provision DNS records this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'provisionEmailDomainDns', async (dataArg) => { await this.requireAuth(dataArg, 'email-domains:write' as any); if (!this.manager) { return { success: false, message: 'EmailDomainManager not initialized' }; } try { const provisioned = await this.manager.provisionDnsRecords(dataArg.id); return { success: true, provisioned }; } catch (err: unknown) { return { success: false, message: (err as Error).message }; } }, ), ); } }