diff options
Diffstat (limited to 'deno/mail-relay/aws')
-rw-r--r-- | deno/mail-relay/aws/app.ts | 29 | ||||
-rw-r--r-- | deno/mail-relay/aws/deliver.ts | 10 | ||||
-rw-r--r-- | deno/mail-relay/aws/fetch.ts | 8 | ||||
-rw-r--r-- | deno/mail-relay/aws/mail.ts | 31 |
4 files changed, 40 insertions, 38 deletions
diff --git a/deno/mail-relay/aws/app.ts b/deno/mail-relay/aws/app.ts index cb275ae..a8a9895 100644 --- a/deno/mail-relay/aws/app.ts +++ b/deno/mail-relay/aws/app.ts @@ -6,7 +6,6 @@ import { FetchHttpHandler } from "@smithy/fetch-http-handler"; // @ts-types="npm:@types/yargs" import yargs from "yargs"; -import { LogFileProvider } from "@crupest/base/log"; import { ConfigDefinition, ConfigProvider } from "@crupest/base/config"; import { CronTask } from "@crupest/base/cron"; @@ -19,6 +18,7 @@ import { import { AwsMailDeliverer } from "./deliver.ts"; import { AwsMailFetcher, AwsS3MailConsumer } from "./fetch.ts"; import { createHono, createInbound, createSmtp, sendMail } from "../app.ts"; +import { DovecotMailDeliverer } from "../dovecot.ts"; const PREFIX = "crupest-mail-server"; const CONFIG_DEFINITIONS = { @@ -47,6 +47,10 @@ const CONFIG_DEFINITIONS = { description: "full path of lda executable", default: "/dovecot/libexec/dovecot/dovecot-lda", }, + doveadmPath: { + description: "full path of doveadm executable", + default: "/dovecot/bin/doveadm", + }, inboundFallback: { description: "comma separated addresses used as fallback recipients", default: "", @@ -96,14 +100,18 @@ function createAwsOptions({ function createOutbound( awsOptions: ReturnType<typeof createAwsOptions>, db: DbService, + local?: DovecotMailDeliverer, ) { const deliverer = new AwsMailDeliverer(awsOptions); deliverer.preHooks.push( new AwsMailMessageIdRewriteHook(db.messageIdToAws.bind(db)), ); deliverer.postHooks.push( - new AwsMailMessageIdSaveHook((original, aws) => - db.addMessageIdMap({ message_id: original, aws_message_id: aws }).then() + new AwsMailMessageIdSaveHook( + async (original, aws, context) => { + await db.addMessageIdMap({ message_id: original, aws_message_id: aws }); + void local?.saveNewSent(context.mail, original); + }, ), ); return deliverer; @@ -155,10 +163,7 @@ function createCron(fetcher: AwsMailFetcher, consumer: AwsS3MailConsumer) { function createBaseServices() { const config = new ConfigProvider(PREFIX, CONFIG_DEFINITIONS); Deno.mkdirSync(config.get("dataPath"), { recursive: true }); - const logFileProvider = new LogFileProvider( - join(config.get("dataPath"), "log"), - ); - return { config, logFileProvider }; + return { config }; } function createAwsFetchOnlyServices() { @@ -177,11 +182,12 @@ function createAwsFetchOnlyServices() { function createAwsRecycleOnlyServices() { const services = createAwsFetchOnlyServices(); - const { config, logFileProvider } = services; + const { config } = services; - const inbound = createInbound(logFileProvider, { + const inbound = createInbound({ fallback: config.getList("inboundFallback"), ldaPath: config.get("ldaPath"), + doveadmPath: config.get("doveadmPath"), aliasFile: join(config.get("dataPath"), "aliases.csv"), mailDomain: config.get("mailDomain"), }); @@ -190,12 +196,13 @@ function createAwsRecycleOnlyServices() { return { ...services, inbound, recycler }; } + function createAwsServices() { const services = createAwsRecycleOnlyServices(); - const { config, awsOptions } = services; + const { config, awsOptions, inbound } = services; const dbService = new DbService(join(config.get("dataPath"), "db.sqlite")); - const outbound = createOutbound(awsOptions, dbService); + const outbound = createOutbound(awsOptions, dbService, inbound); return { ...services, dbService, outbound }; } diff --git a/deno/mail-relay/aws/deliver.ts b/deno/mail-relay/aws/deliver.ts index 4dd4b3a..52438cb 100644 --- a/deno/mail-relay/aws/deliver.ts +++ b/deno/mail-relay/aws/deliver.ts @@ -44,15 +44,15 @@ export class AwsMailDeliverer extends SyncMailDeliverer { `${res.MessageId}@${this.#aws.region}.amazonses.com`; } + context.result.smtpMessage = `AWS Message ID: ${context.result.awsMessageId}`; context.result.recipients.set("*", { - kind: "done", - message: - `Successfully called aws send-email, message id ${context.result.awsMessageId}.`, + kind: "success", + message: `Succeeded to call aws send-email api.`, }); } catch (cause) { context.result.recipients.set("*", { - kind: "fail", - message: "An error was thrown when calling aws send-email." + cause, + kind: "failure", + message: "A JS error was thrown when calling aws send-email." + cause, cause, }); } diff --git a/deno/mail-relay/aws/fetch.ts b/deno/mail-relay/aws/fetch.ts index 9278e63..b9954c8 100644 --- a/deno/mail-relay/aws/fetch.ts +++ b/deno/mail-relay/aws/fetch.ts @@ -50,8 +50,6 @@ export class AwsMailFetcher { } async listLiveMails(): Promise<string[]> { - console.info("Begin to retrieve live mails."); - const listCommand = new ListObjectsV2Command({ Bucket: this.#bucket, Prefix: this.#livePrefix, @@ -99,11 +97,7 @@ export class AwsMailFetcher { await consumer(rawMail, s3Key); console.info(`Done consuming s3 mail ${s3Key}.`); - const date = new Mail(rawMail) - .startSimpleParse() - .sections() - .headers() - .date(); + const { date } = new Mail(rawMail).parsed; const dateString = date != null ? toFileNameString(date, true) : "invalid-date"; diff --git a/deno/mail-relay/aws/mail.ts b/deno/mail-relay/aws/mail.ts index cc05d23..0f86705 100644 --- a/deno/mail-relay/aws/mail.ts +++ b/deno/mail-relay/aws/mail.ts @@ -8,42 +8,43 @@ export class AwsMailMessageIdRewriteHook implements MailDeliverHook { } async callback(context: MailDeliverContext): Promise<void> { - console.info("Rewrite message ids..."); const addresses = context.mail.simpleFindAllAddresses(); - console.info(`Addresses found in mail: ${addresses.join(", ")}.`); for (const address of addresses) { const awsMessageId = await this.#lookup(address); if (awsMessageId != null && awsMessageId.length !== 0) { - console.info(`Rewrite ${address} to ${awsMessageId}.`); + console.info(`Rewrite address-line string in mail: ${address} => ${awsMessageId}.`); context.mail.raw = context.mail.raw.replaceAll(address, awsMessageId); } } - console.info("Done rewrite message ids."); } } export class AwsMailMessageIdSaveHook implements MailDeliverHook { readonly #record; - constructor(record: (original: string, aws: string) => Promise<void>) { + constructor( + record: ( + original: string, + aws: string, + context: MailDeliverContext, + ) => Promise<void>, + ) { this.#record = record; } async callback(context: MailDeliverContext): Promise<void> { - console.info("Save aws message ids..."); - const messageId = context.mail - .startSimpleParse() - .sections() - .headers() - .messageId(); + const messageId = context.mail.parsed.messageId; if (messageId == null) { - console.info("Original mail does not have message id. Skip saving."); + console.warn("Original mail does not have message id, skip saving message id map."); return; } if (context.result.awsMessageId != null) { - console.info(`Saving ${messageId} => ${context.result.awsMessageId}.`); - await this.#record(messageId, context.result.awsMessageId); + console.info(`Save message id map: ${messageId} => ${context.result.awsMessageId}.`); + context.mail.raw = context.mail.raw.replaceAll( + messageId, + context.result.awsMessageId, + ); + await this.#record(messageId, context.result.awsMessageId, context); } - console.info("Done save message ids."); } } |