import type { ApiSettings } from "../types"; import { apiFetch } from "./client"; export type MailSecurity = "plain" | "tls" | "starttls"; export type MailProfileScope = "system" | "tenant" | "user" | "group" | "campaign"; export type MailSmtpTestPayload = { host?: string | null; port?: number | null; username?: string | null; password?: string | null; security?: MailSecurity; timeout_seconds?: number; }; export type MailImapTestPayload = MailSmtpTestPayload & { sent_folder?: string | null; }; export type MailTransportCredentialsPayload = { username?: string | null; password?: string | null; }; export type MailServerProfileCredentialsPayload = { smtp?: MailTransportCredentialsPayload; imap?: MailTransportCredentialsPayload; }; export type MailConnectionTestResponse = { ok: boolean; protocol: "smtp" | "imap"; host?: string | null; port?: number | null; security?: MailSecurity | string | null; message: string; details?: Record; }; export type MailImapFolderResponse = { name: string; flags?: string[]; message_count?: number | null; unseen_count?: number | null; }; export type MailImapFolderListResponse = { ok: boolean; protocol: "imap"; host?: string | null; port?: number | null; security?: MailSecurity | string | null; message: string; folders: MailImapFolderResponse[]; detected_sent_folder?: string | null; details?: Record; }; export type MailMailboxAttachment = { filename?: string | null; content_type: string; size_bytes: number; }; export type MailMailboxMessageSummary = { uid: string; folder: string; subject?: string | null; from_header?: string | null; to_header?: string | null; cc_header?: string | null; bcc_header?: string | null; date?: string | null; message_id?: string | null; flags?: string[]; size_bytes?: number | null; body_preview?: string | null; attachment_count?: number; }; export type MailMailboxMessageDetail = MailMailboxMessageSummary & { body_text?: string | null; body_html?: string | null; headers?: Record; attachments?: MailMailboxAttachment[]; }; export type MailMailboxMessageListResponse = { profile_id: string; folder: string; host?: string | null; port?: number | null; security?: MailSecurity | string | null; total_count?: number; offset?: number; limit?: number; messages: MailMailboxMessageSummary[]; }; export type MailMailboxMessageResponse = { profile_id: string; folder: string; host?: string | null; port?: number | null; security?: MailSecurity | string | null; message: MailMailboxMessageDetail; }; export type MailServerProfile = { id: string; tenant_id?: string | null; scope_type: MailProfileScope; scope_id?: string | null; name: string; slug: string; description?: string | null; is_active: boolean; smtp: MailSmtpTestPayload; imap?: MailImapTestPayload | null; credentials?: MailServerProfileCredentialsPayload | null; smtp_password_configured: boolean; imap_password_configured: boolean; created_at: string; updated_at: string; }; export type MailServerProfileListResponse = { profiles: MailServerProfile[] }; export const mailProfilePatternKeys = [ "smtp_hosts", "imap_hosts", "envelope_senders", "from_headers", "recipient_domains" ] as const; export type MailProfilePatternKey = typeof mailProfilePatternKeys[number]; export type MailProfilePatternRules = Partial>; export const mailProfilePolicyLimitKeys = [ "allowed_profile_ids", "allow_user_profiles", "allow_group_profiles", "allow_campaign_profiles", "smtp_credentials.inherit", "imap_credentials.inherit", "whitelist.smtp_hosts", "whitelist.imap_hosts", "whitelist.envelope_senders", "whitelist.from_headers", "whitelist.recipient_domains", "blacklist.smtp_hosts", "blacklist.imap_hosts", "blacklist.envelope_senders", "blacklist.from_headers", "blacklist.recipient_domains" ] as const; export type MailProfilePolicyLimitKey = typeof mailProfilePolicyLimitKeys[number]; export type MailProfilePolicyLimitPermissions = Partial>; export type MailCredentialPolicy = { inherit?: boolean | null; }; export type MailProfilePolicy = { allowed_profile_ids?: string[] | null; allow_user_profiles?: boolean | null; allow_group_profiles?: boolean | null; allow_campaign_profiles?: boolean | null; smtp_credentials?: MailCredentialPolicy | null; imap_credentials?: MailCredentialPolicy | null; whitelist?: MailProfilePatternRules | null; blacklist?: MailProfilePatternRules | null; allow_lower_level_limits?: MailProfilePolicyLimitPermissions | null; }; export type PolicySourceStep = { scope_type: string; scope_id?: string | null; label: string; applied_fields?: string[]; policy?: MailProfilePolicy | null; }; export type MailProfilePolicyResponse = { scope_type: MailProfileScope; scope_id?: string | null; policy: MailProfilePolicy; effective_policy?: MailProfilePolicy | null; parent_policy?: MailProfilePolicy | null; effective_policy_sources?: PolicySourceStep[]; parent_policy_sources?: PolicySourceStep[]; }; export type MailServerProfilePayload = { name: string; slug?: string | null; description?: string | null; is_active?: boolean; scope_type?: MailProfileScope; scope_id?: string | null; smtp: MailSmtpTestPayload; imap?: MailImapTestPayload | null; credentials?: MailServerProfileCredentialsPayload | null; }; export async function listMailServerProfiles(settings: ApiSettings, includeInactive = false, campaignId?: string): Promise { const params = new URLSearchParams(); if (includeInactive) params.set("include_inactive", "true"); if (campaignId) params.set("campaign_id", campaignId); const suffix = params.toString() ? `?${params.toString()}` : ""; const response = await apiFetch(settings, `/api/v1/mail/profiles${suffix}`); return response.profiles ?? []; } export async function createMailServerProfile(settings: ApiSettings, payload: MailServerProfilePayload): Promise { return apiFetch(settings, "/api/v1/mail/profiles", { method: "POST", body: JSON.stringify(payload) }); } export type MailServerProfileUpdatePayload = Partial & { clear_imap?: boolean }; export async function updateMailServerProfile(settings: ApiSettings, profileId: string, payload: MailServerProfileUpdatePayload): Promise { return apiFetch(settings, `/api/v1/mail/profiles/${encodeURIComponent(profileId)}`, { method: "PATCH", body: JSON.stringify(payload) }); } export async function deactivateMailServerProfile(settings: ApiSettings, profileId: string): Promise { return apiFetch(settings, `/api/v1/mail/profiles/${encodeURIComponent(profileId)}`, { method: "DELETE" }); } export async function getMailProfilePolicy( settings: ApiSettings, scopeType: MailProfileScope, scopeId?: string | null, campaignId?: string | null ): Promise { const params = new URLSearchParams(); if (scopeId) params.set("scope_id", scopeId); if (campaignId) params.set("campaign_id", campaignId); const suffix = params.toString() ? `?${params.toString()}` : ""; return apiFetch(settings, `/api/v1/mail/policies/${encodeURIComponent(scopeType)}${suffix}`); } export async function updateMailProfilePolicy( settings: ApiSettings, scopeType: MailProfileScope, policy: MailProfilePolicy, scopeId?: string | null ): Promise { const params = new URLSearchParams(); if (scopeId) params.set("scope_id", scopeId); const suffix = params.toString() ? `?${params.toString()}` : ""; return apiFetch(settings, `/api/v1/mail/policies/${encodeURIComponent(scopeType)}${suffix}`, { method: "PUT", body: JSON.stringify({ policy }) }); } export async function testMailProfileSmtp(settings: ApiSettings, profileId: string): Promise { return apiFetch(settings, `/api/v1/mail/profiles/${encodeURIComponent(profileId)}/test-smtp`, { method: "POST" }); } export async function testMailProfileImap(settings: ApiSettings, profileId: string): Promise { return apiFetch(settings, `/api/v1/mail/profiles/${encodeURIComponent(profileId)}/test-imap`, { method: "POST" }); } export async function listMailProfileImapFolders(settings: ApiSettings, profileId: string): Promise { return apiFetch(settings, `/api/v1/mail/profiles/${encodeURIComponent(profileId)}/list-imap-folders`, { method: "POST" }); } export async function listMailboxFolders(settings: ApiSettings, profileId: string): Promise { return apiFetch(settings, `/api/v1/mail/profiles/${encodeURIComponent(profileId)}/mailbox/folders`); } export async function listMailboxMessages( settings: ApiSettings, profileId: string, folder = "INBOX", limit = 50, offset = 0 ): Promise { const params = new URLSearchParams({ folder, limit: String(limit), offset: String(offset) }); return apiFetch(settings, `/api/v1/mail/profiles/${encodeURIComponent(profileId)}/mailbox/messages?${params.toString()}`); } export async function getMailboxMessage( settings: ApiSettings, profileId: string, folder: string, uid: string ): Promise { const params = new URLSearchParams({ folder }); return apiFetch(settings, `/api/v1/mail/profiles/${encodeURIComponent(profileId)}/mailbox/messages/${encodeURIComponent(uid)}?${params.toString()}`); } export async function testSmtpSettings( settings: ApiSettings, payload: MailSmtpTestPayload ): Promise { return apiFetch(settings, "/api/v1/mail/test-smtp", { method: "POST", body: JSON.stringify(payload) }); } export async function testImapSettings( settings: ApiSettings, payload: MailImapTestPayload ): Promise { return apiFetch(settings, "/api/v1/mail/test-imap", { method: "POST", body: JSON.stringify(payload) }); } export async function listImapFolders( settings: ApiSettings, payload: MailImapTestPayload ): Promise { return apiFetch(settings, "/api/v1/mail/list-imap-folders", { method: "POST", body: JSON.stringify(payload) }); } export type MockMailboxMessage = { id: string; kind: "smtp" | "imap_append" | string; created_at: string; envelope_from?: string | null; envelope_recipients?: string[]; subject?: string | null; from_header?: string | null; to_header?: string | null; cc_header?: string | null; bcc_header?: string | null; message_id?: string | null; size_bytes?: number; body_preview?: string | null; attachment_count?: number; folder?: string | null; raw_eml?: string | null; headers?: Record; attachments?: Array<{ filename?: string | null; content_type?: string | null; size_bytes?: number }>; }; export type MockMailboxListResponse = { messages: MockMailboxMessage[]; }; export type MockMailboxMessageResponse = { message: MockMailboxMessage; }; export type MockMailboxFailureConfig = { fail_next_smtp?: boolean | null; fail_next_imap?: boolean | null; smtp_reject_recipients_containing?: string | null; }; export async function listMockMailboxMessages(settings: ApiSettings, kind?: string): Promise { const suffix = kind ? `?kind=${encodeURIComponent(kind)}` : ""; return apiFetch(settings, `/api/v1/dev/mailbox/messages${suffix}`); } export async function getMockMailboxMessage(settings: ApiSettings, id: string): Promise { return apiFetch(settings, `/api/v1/dev/mailbox/messages/${encodeURIComponent(id)}`); } export async function clearMockMailboxMessages(settings: ApiSettings): Promise<{ deleted_count: number }> { return apiFetch<{ deleted_count: number }>(settings, "/api/v1/dev/mailbox/messages", { method: "DELETE" }); } export async function updateMockMailboxFailures(settings: ApiSettings, payload: MockMailboxFailureConfig): Promise<{ config: MockMailboxFailureConfig }> { return apiFetch<{ config: MockMailboxFailureConfig }>(settings, "/api/v1/dev/mailbox/failures", { method: "POST", body: JSON.stringify(payload) }); }