diff options
author | Yuqian Yang <crupest@crupest.life> | 2025-06-17 19:04:16 +0800 |
---|---|---|
committer | Yuqian Yang <crupest@crupest.life> | 2025-06-17 21:37:43 +0800 |
commit | 874c4a8babc5aac7214e71dfef7743bae23893a3 (patch) | |
tree | d7d39313a442bac49859669bb8d1919267575023 /deno/mail-relay/dovecot.ts | |
parent | 0824de3bae3550674a9ea029b03c5cb8a35cd8e1 (diff) | |
download | crupest-874c4a8babc5aac7214e71dfef7743bae23893a3.tar.gz crupest-874c4a8babc5aac7214e71dfef7743bae23893a3.tar.bz2 crupest-874c4a8babc5aac7214e71dfef7743bae23893a3.zip |
HALF WORK!:mail
Diffstat (limited to 'deno/mail-relay/dovecot.ts')
-rw-r--r-- | deno/mail-relay/dovecot.ts | 55 |
1 files changed, 17 insertions, 38 deletions
diff --git a/deno/mail-relay/dovecot.ts b/deno/mail-relay/dovecot.ts index 55e1e9b..8e6e754 100644 --- a/deno/mail-relay/dovecot.ts +++ b/deno/mail-relay/dovecot.ts @@ -16,10 +16,11 @@ async function runCommand( options: { args: string[]; stdin?: Uint8Array; + suppressResultLog?: boolean; errorCodeMessageMap?: Map<number, string>; }, ): Promise<CommandResult> { - const { args, stdin, errorCodeMessageMap } = options; + const { args, stdin, suppressResultLog, errorCodeMessageMap } = options; console.info(`Run external command ${bin} ${args.join(" ")}`); @@ -33,7 +34,6 @@ async function runCommand( // Write stdin if any. if (stdin != null) { - console.info("Write stdin..."); const writer = process.stdin.getWriter(); await writer.write(stdin); writer.close(); @@ -43,13 +43,13 @@ async function runCommand( const status = await process.status; // Build log message string. - let message = `Command exited with code ${status.code}`; + let message = `External command exited with code ${status.code}`; if (status.signal != null) message += ` (signal: ${status.signal})`; if (errorCodeMessageMap != null && errorCodeMessageMap.has(status.code)) { message += `, ${errorCodeMessageMap.get(status.code)}`; } message += "."; - console.log(message); + suppressResultLog || console.log(message); // Return result. return { @@ -58,8 +58,8 @@ async function runCommand( logMessage: message, }; } catch (cause) { - const message = "Running command threw an error:"; - console.log(message, cause); + const message = `A JS error was thrown when invoking external command:`; + suppressResultLog || console.log(message, cause); return { kind: "throw", cause, logMessage: message + " " + cause }; } } @@ -87,36 +87,34 @@ export class DovecotMailDeliverer extends MailDeliverer { const recipients = [...context.recipients]; if (recipients.length === 0) { - context.result.smtpMessage = - "Failed to deliver to dovecot, no recipients are specified."; - return; + throw new Error( + "Failed to deliver to dovecot, no recipients are specified.", + ); } - console.info(`Deliver to dovecot users: ${recipients.join(", ")}.`); - for (const recipient of recipients) { const result = await runCommand( this.#ldaPath, { args: ["-d", recipient], stdin: utf8Bytes, + suppressResultLog: true, + errorCodeMessageMap: ldaExitCodeMessageMap, }, ); if (result.kind === "exit-success") { context.result.recipients.set(recipient, { - kind: "done", + kind: "success", message: result.logMessage, }); } else { context.result.recipients.set(recipient, { - kind: "fail", + kind: "failure", message: result.logMessage, }); } } - - console.info("Done handling all recipients."); } #queryArgs(mailbox: string, messageId: string) { @@ -128,16 +126,12 @@ export class DovecotMailDeliverer extends MailDeliverer { mailbox: string, messageId: string, ): Promise<void> { - console.info( - `Find and delete mails (user: ${user}, message-id: ${messageId}, mailbox: ${mailbox}).`, - ); await runCommand(this.#doveadmPath, { args: ["expunge", "-u", user, ...this.#queryArgs(mailbox, messageId)], }); } async #saveMail(user: string, mailbox: string, mail: Uint8Array) { - console.info(`Save a mail (user: ${user}, mailbox: ${mailbox}).`); await runCommand(this.#doveadmPath, { args: ["save", "-u", user, "-m", mailbox], stdin: mail, @@ -145,9 +139,6 @@ export class DovecotMailDeliverer extends MailDeliverer { } async #markAsRead(user: string, mailbox: string, messageId: string) { - console.info( - `Mark mails as \\Seen(user: ${user}, message-id: ${messageId}, mailbox: ${mailbox}, user: ${user}).`, - ); await runCommand(this.#doveadmPath, { args: [ "flags", @@ -164,45 +155,33 @@ export class DovecotMailDeliverer extends MailDeliverer { console.info("Save sent mails and delete ones with old message id."); // Try to get from and recipients from headers. - const headers = mail.startSimpleParse().sections().headers(); - const from = headers.from(), - recipients = headers.recipients(), - messageId = headers.messageId(); + const { messageId, from, recipients } = mail.parsed; if (from == null) { - console.warn("Failed to determine from from headers, skip saving."); + console.warn("Failed to get sender (from) in headers, skip saving."); return; } - console.info("Parsed from: ", from); - if (recipients.has(from)) { // So the mail should lie in the Inbox. console.info( - "The mail has the sender itself as one of recipients, skip saving.", + "One recipient of the mail is the sender itself, skip saving.", ); return; } await this.#saveMail(from, "Sent", mail.toUtf8Bytes()); if (messageId != null) { - console.info("Mark sent mail as read."); await this.#markAsRead(from, "Sent", messageId); } else { console.warn( - "New message id of the mail is not found, skip marking as read.", + "Message id of the mail is not found, skip marking as read.", ); } console.info("Schedule deletion of old mails at 15,30,60 seconds later."); [15, 30, 60].forEach((seconds) => setTimeout(() => { - console.info( - `Try to delete mails in Sent. (message-id: ${messageIdToDelete}, ` + - `attempt delay: ${seconds}s) ` + - "Note that the mail may have already been deleted," + - " in which case failures of deletion can be just ignored.", - ); void this.#deleteMail(from, "Sent", messageIdToDelete); }, 1000 * seconds) ); |