aboutsummaryrefslogtreecommitdiff
path: root/services/docker/mail-server/aws-sendmail/delivers/dovecot.ts
diff options
context:
space:
mode:
Diffstat (limited to 'services/docker/mail-server/aws-sendmail/delivers/dovecot.ts')
-rw-r--r--services/docker/mail-server/aws-sendmail/delivers/dovecot.ts56
1 files changed, 56 insertions, 0 deletions
diff --git a/services/docker/mail-server/aws-sendmail/delivers/dovecot.ts b/services/docker/mail-server/aws-sendmail/delivers/dovecot.ts
new file mode 100644
index 0000000..e30c558
--- /dev/null
+++ b/services/docker/mail-server/aws-sendmail/delivers/dovecot.ts
@@ -0,0 +1,56 @@
+import { Logger } from "../logger.ts";
+import { MailDeliverContext, MailDeliverer } from "../deliver.ts";
+
+export class DovecotMailDeliverer extends MailDeliverer {
+ constructor(private readonly logger: Logger) {
+ super("dovecot");
+ }
+
+ readonly ldaBin = "dovecot-lda";
+
+ protected override doPrepare(
+ rawMail: string,
+ ): Promise<MailDeliverContext> {
+ return Promise.resolve(new MailDeliverContext(rawMail));
+ }
+
+ protected override async doDeliver(
+ context: MailDeliverContext,
+ ): Promise<void> {
+ const { logger, ldaBin } = this;
+ const { rawMail } = context;
+ let status;
+
+ try {
+ const utf8Encoder = new TextEncoder();
+ // TODO: A problem here is if mail is VERY long, this will block for a long time.
+ // Maybe some task queue can be used.
+ const utf8Stream = utf8Encoder.encode(rawMail);
+
+ const ldaCommand = new Deno.Command(ldaBin, {
+ stdin: "piped",
+ stdout: "piped",
+ stderr: "piped",
+ });
+ const ldaProcess = ldaCommand.spawn();
+ logger.logProgramOutput(ldaProcess, ldaBin);
+
+ const stdinWriter = ldaProcess.stdin.getWriter();
+ await stdinWriter.ready;
+ await stdinWriter.write(utf8Stream);
+ await stdinWriter.ready;
+
+ status = await ldaProcess.status;
+ } catch (cause) {
+ this.throwError(
+ "external error.",
+ rawMail,
+ cause,
+ );
+ }
+
+ if (!status.success) {
+ this.throwError(`${ldaBin} exited with non-zero.`, rawMail);
+ }
+ }
+}