diff --git a/README.md b/README.md index 80f464f..2b3911b 100644 --- a/README.md +++ b/README.md @@ -274,11 +274,16 @@ export interface SendConfig { * allowes preprocessors to hande different email types */ internalTag?: string | symbol; + headers: Record; } ``` All of it should be clear by name except: +#### headers + +Add custom headers to the email. + #### mimeContent There are use cases where you want to do encoding etc. on your own. This option diff --git a/client/basic/client.ts b/client/basic/client.ts index fada1d0..b7d8773 100644 --- a/client/basic/client.ts +++ b/client/basic/client.ts @@ -143,6 +143,13 @@ export class SMTPClient { await this.#connection.writeCmd("Date: ", config.date); + const obj = Object.entries(config.headers); + + for (let i = 0; i < obj.length; i++) { + const [name, value] = obj[i]; + await this.#connection.writeCmd(name + ": ", value); + } + if (config.inReplyTo) { await this.#connection.writeCmd("InReplyTo: ", config.inReplyTo); } diff --git a/config/mail/headers.ts b/config/mail/headers.ts new file mode 100644 index 0000000..1acadc7 --- /dev/null +++ b/config/mail/headers.ts @@ -0,0 +1,13 @@ +export interface Headers { + [headerName: string]: string; +} + +export function validateHeaders( + headers: Headers, +) { + return !(Object.keys(headers).some((v) => + v.includes("\n") || v.includes("\r") + ) || Object.values(headers).some((v) => + v.includes("\n") || v.includes("\r") + )); +} diff --git a/config/mail/mod.ts b/config/mail/mod.ts index 02e1a3e..41ed58d 100644 --- a/config/mail/mod.ts +++ b/config/mail/mod.ts @@ -13,7 +13,7 @@ import { validateEmailList, } from "./email.ts"; import { ResolvedClientOptions } from "../client.ts"; - +import { Headers, validateHeaders } from "./headers.ts"; /** * Config for a mail */ @@ -37,6 +37,7 @@ export interface SendConfig { * allowes preprocessors to hande different email types */ internalTag?: string | symbol; + headers?: Headers; } export interface ResolvedSendConfig { @@ -53,6 +54,7 @@ export interface ResolvedSendConfig { priority?: "high" | "normal" | "low"; attachments: ResolvedAttachment[]; internalTag?: string | symbol; + headers: Headers; } export function resolveSendConfig(config: SendConfig): ResolvedSendConfig { @@ -72,6 +74,7 @@ export function resolveSendConfig(config: SendConfig): ResolvedSendConfig { priority, attachments, internalTag, + headers, } = config; return { @@ -94,6 +97,7 @@ export function resolveSendConfig(config: SendConfig): ResolvedSendConfig { references, priority, internalTag, + headers: headers ?? ({} as Headers), }; } @@ -160,6 +164,10 @@ export function validateConfig( warn.push("You should provide at least html or text content!"); } + if (!validateHeaders(config.headers)) { + errors.push(`Headers are not allowed to include linebreaks!`); + } + if (client.client.warning === "log" && warn.length > 0) { console.warn(warn.join("\n")); }