mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-02 16:15:39 +00:00
- Settings > Backup & reset gets a Mail files section for Import mail and Export all mail, instead of sitting under settings backup. - The pause message names Stalwart's 50000000-byte quota as 50 MB, not 48 MB, and the dialog and settings texts mention .ost files. - The old import's leftovers go: expandImportableEmails and EML_IMPORT_ACCEPT in lib/eml-import.ts, and the strings email_viewer.import_email, mailbox_context_menu.import_email and notifications.import_email_success/_error in all 30 locales. lib/__tests__/eml-import.test.ts loses the tests of the removed functions; its #891 checks that an .eml and an .eml in a ZIP keep their Date header now run against the import's own sources.
28 lines
1.3 KiB
TypeScript
28 lines
1.3 KiB
TypeScript
import { MAX_FUTURE_SENT_AT_MS } from "./email-date";
|
|
|
|
/** Only the header block is needed; don't decode a whole large message. */
|
|
const HEADER_SCAN_BYTES = 64 * 1024;
|
|
|
|
/**
|
|
* Read the `Date` header of a raw RFC 5322 message and return it as a JMAP
|
|
* UTCDate (no fractional seconds). Returns undefined when the header is
|
|
* missing, unparsable, or more than a day in the future.
|
|
*/
|
|
export async function readMessageDate(blob: Blob, now: number = Date.now()): Promise<string | undefined> {
|
|
const head = await blob.slice(0, HEADER_SCAN_BYTES).text();
|
|
return dateFromHeaderBlock(head, now);
|
|
}
|
|
|
|
/** `readMessageDate` for header text already read (anything after the header block is ignored). */
|
|
export function dateFromHeaderBlock(head: string, now: number = Date.now()): string | undefined {
|
|
const end = head.search(/\r?\n\r?\n/);
|
|
const headers = (end === -1 ? head : head.slice(0, end)).replace(/\r?\n[ \t]+/g, " ");
|
|
const match = /^Date:[ \t]*(.+)$/im.exec(headers);
|
|
if (!match) return undefined;
|
|
// Drop RFC 5322 comments such as "(CEST)" before parsing.
|
|
const value = match[1].replace(/\([^)]*\)/g, " ").trim();
|
|
const time = Date.parse(value);
|
|
if (Number.isNaN(time) || time - now > MAX_FUTURE_SENT_AT_MS) return undefined;
|
|
return new Date(time).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
}
|