import * as plugins from '../../plugins.js'; import { DcRouterDb } from '../classes.dcrouter-db.js'; import type { ISmtpScramVerifier } from '@push.rocks/smartmta'; import type { ISmtpAccountInfo, ISmtpAccountMailPolicy, ISmtpAccountRecipientScope, ISmtpAccountSenderScope, } from '../../../ts_interfaces/data/smtp-account.js'; const getDb = () => DcRouterDb.getInstance().getDb(); /** * Operator-managed authenticated SMTP submission account. * * At rest the credential is exclusively a hashed SCRAM-SHA-256 verifier — * the plaintext password is machine-generated, shown once at create/rotate * time, and never persisted. `toApiObject()` never exposes the verifier. */ @plugins.smartdata.Collection(() => getDb()) export class SmtpAccountDoc extends plugins.smartdata.SmartDataDbDoc { @plugins.smartdata.unI() @plugins.smartdata.svDb() public id!: string; @plugins.smartdata.index({ unique: true }) @plugins.smartdata.svDb() public username!: string; @plugins.smartdata.svDb() public description: string = ''; @plugins.smartdata.svDb() public enabled: boolean = true; /** Hashed credential only — never a plaintext password. */ @plugins.smartdata.svDb() public credentialVerifier!: ISmtpScramVerifier; @plugins.smartdata.svDb() public senderScope!: ISmtpAccountSenderScope; @plugins.smartdata.svDb() public recipientScope!: ISmtpAccountRecipientScope; @plugins.smartdata.svDb() public mailPolicy!: ISmtpAccountMailPolicy; @plugins.smartdata.svDb() public createdAt!: number; @plugins.smartdata.svDb() public updatedAt!: number; @plugins.smartdata.svDb() public createdBy!: string; @plugins.smartdata.svDb() public lastRotatedAt?: number; constructor() { super(); } /** Wire representation — never carries the verifier or any secret. */ public toApiObject(): ISmtpAccountInfo { return { id: this.id, username: this.username, description: this.description || '', enabled: this.enabled, senderScope: { addresses: [...(this.senderScope?.addresses || [])], domains: [...(this.senderScope?.domains || [])], }, recipientScope: { mode: this.recipientScope?.mode || 'any', addresses: [...(this.recipientScope?.addresses || [])], domains: [...(this.recipientScope?.domains || [])], }, mailPolicy: { dkimSign: Boolean(this.mailPolicy?.dkimSign), ...(this.mailPolicy?.queue ? { queue: this.mailPolicy.queue } : {}), }, createdAt: this.createdAt, updatedAt: this.updatedAt, createdBy: this.createdBy, ...(this.lastRotatedAt ? { lastRotatedAt: this.lastRotatedAt } : {}), }; } public static async findById(id: string): Promise { return await SmtpAccountDoc.getInstance({ id }); } public static async findByUsername(username: string): Promise { return await SmtpAccountDoc.getInstance({ username }); } public static async findAll(): Promise { return await SmtpAccountDoc.getInstances({}); } }