import { IsBoolean, IsEmail, IsIn, IsInt, IsOptional, IsString, Max, Min, } from 'class-validator'; /** * DTO for creating or updating the per-tenant TenderEmailConfig (Phase 14, * Plan 03, INGEST-05/CONFIG-02, D-06/D-07). Mirrors DkvConfigDto's mailbox * fields exactly — this is a SEPARATE, tenant-scoped alert mailbox, not the * DKV invoice inbox (D-03). * * Security: * - T-14-03-02: senderFilter validated as email address (injection mitigation) * - T-14-03-02: port constrained to 1-65535 * - T-14-03-02: protocol/encryption constrained with @IsIn */ export class TenderEmailConfigDto { /** Inbox protocol — 'imap' for IMAP, 'exchange' for Exchange (EWS). */ @IsIn(['imap', 'exchange']) protocol!: string; /** Mail server hostname/IP (IMAP) or full EWS endpoint URL (Exchange). */ @IsOptional() @IsString() host?: string; /** TCP port. Standard values: 993 (IMAP SSL/TLS), 143 (IMAP STARTTLS), 443 (EWS). */ @IsOptional() @IsInt() @Min(1) @Max(65535) port?: number; /** TLS mode: 'none' | 'starttls' | 'ssl-tls'. */ @IsIn(['none', 'starttls', 'ssl-tls']) encryption!: string; /** IMAP folder to monitor (e.g. "INBOX"). Exchange resolves via display name. */ @IsOptional() @IsString() folder?: string; /** * Sender email address to filter by. Validated as email address to * prevent header injection (mirrors DkvConfigDto / T-07-04). */ @IsOptional() @IsEmail() senderFilter?: string; /** Exchange only: Windows domain (optional). */ @IsOptional() @IsString() domain?: string; /** Inbox username (stored encrypted; blank on load, T-07-12). */ @IsOptional() @IsString() username?: string; /** * Inbox password (stored encrypted; blank on load). * T-07-12: never returned to the frontend in responses. */ @IsOptional() @IsString() password?: string; /** Whether the email-alert poll is active for this tenant's mailbox. */ @IsOptional() @IsBoolean() isActive?: boolean; }