import type { IUnifiedEmailServerOptions } from '@push.rocks/smartmta'; import type { DcRouter } from '../classes.dcrouter.js'; import type { ISmtpAccountInfo, ISmtpAccountMailPolicy, ISmtpAccountRecipientScope, ISmtpAccountSenderScope } from '../../dist_ts_interfaces/data/smtp-account.js'; import { type IWorkAppMailRuntimeContribution } from './classes.workapp-mail-manager.js'; /** Route names generated (and owned wholesale) by SmtpAccountManager. */ export declare function isSmtpAccountRouteName(routeName: string): boolean; export interface ISmtpAccountCreateOptions { username: string; description?: string; senderScope?: ISmtpAccountSenderScope; recipientScope?: ISmtpAccountRecipientScope; mailPolicy?: ISmtpAccountMailPolicy; createdBy: string; } export interface ISmtpAccountUpdateOptions { description?: string; senderScope?: ISmtpAccountSenderScope; recipientScope?: ISmtpAccountRecipientScope; mailPolicy?: ISmtpAccountMailPolicy; } export interface ISmtpAccountMutationResult { account: ISmtpAccountInfo; warnings: string[]; } export interface ISmtpAccountSecretResult extends ISmtpAccountMutationResult { /** Plaintext password — exists only in this response, never persisted. */ password: string; } /** * SmtpAccountManager — operator-managed authenticated SMTP submission * accounts, backed by SmtpAccountDoc rows holding hashed SCRAM verifiers only. * * Single composition owner of the email runtime `auth` block and route list: * every runtime application of auth/routes goes through composeEmailConfig / * applyToRuntime here. WorkAppMailManager identities feed in as an explicit * contribution; nothing else writes `auth` wholesale. * * Accounts are served from an in-memory map loaded at start() — the SMTP auth * path (smartmta's Rust bridge, 5s callback timeout) never touches the DB. */ export declare class SmtpAccountManager { private dcRouterRef; private accounts; private started; private mutationChain; /** Explicit upstream capability marker; absence is deliberately fail-closed. */ private get authAccountsCapability(); constructor(dcRouterRef: DcRouter); start(): Promise; stop(): Promise; isStarted(): boolean; getAccountCount(): number; /** * Compose the runtime email config: operator-configured routes/users plus * the workapp identity contribution plus DB-backed SMTP accounts and their * generated relay routes. Idempotent — previously generated entries are * stripped by their reserved name prefixes before re-adding. */ composeEmailConfig(emailConfig: TConfig, workappContribution?: IWorkAppMailRuntimeContribution): Promise; /** * Recompose from the live runtime options and push the result: replace the * whole `auth` block (smartmta toggles listener AUTH live) and re-apply the * route list. */ applyToRuntime(workappContribution?: IWorkAppMailRuntimeContribution): Promise; private buildAuthAccount; /** * One generated relay route per (account × sender-scope domain), name * `smtp-account--`, priority 850 — below workapp * per-address routes (900), above operator-configured DB routes. * * Accounts without a sender scope generate no routes: their relay * permission stays exactly whatever operator-configured routes grant * (this is what keeps the legacy-user migration from widening relay). * * DKIM policy rides on `process.dkim` only — smartmta ≥9.1 resolves the * active selector per sender domain from its domain registry, so no * selector is snapshotted into routes and rotation stays owned by * EmailDomainManager/mail-dns-sync. */ private buildAccountRoutes; /** Map of sender-scope domain -> the scope patterns belonging to it. */ private collectSenderDomainPatterns; private hashDomain; private recordAccountConflictEvent; listAccounts(): Promise; createAccount(options: ISmtpAccountCreateOptions): Promise; updateAccount(id: string, updates: ISmtpAccountUpdateOptions, updatedBy: string): Promise; toggleAccount(id: string, enabled: boolean, updatedBy: string): Promise; rotatePassword(id: string, rotatedBy: string): Promise; deleteAccount(id: string, deletedBy: string): Promise; private requireAccount; private normalizeUsername; private normalizeDomain; private normalizeAddressPattern; private normalizeSenderScope; private normalizeRecipientScope; private normalizeMailPolicy; /** * DKIM signing fails at configuration time, never at delivery time: it is * only allowed when every sender-scope domain is a managed email domain * that is outbound-ready with active DKIM material. */ private assertDkimPolicyAllowed; /** Warn-and-allow: sender domains outside managed email domains are permitted but flagged. */ private collectSenderDomainWarnings; private decorateWithDomainReadiness; private dedupe; private runMutationExclusive; }