diff --git a/src/lib/letter.ts b/src/lib/letter.ts index 5ae1703..7db2b9b 100644 --- a/src/lib/letter.ts +++ b/src/lib/letter.ts @@ -12,7 +12,7 @@ function parseTextPlainContent(mimeMessage: string) { for (const body of boundaries) { const headers: Record = {}; - const lines = body.split('\r\n'); + const lines = body.split(/\r?\n/); let isLookingForHeaders = true; let content = ''; for (const line of lines) { @@ -33,7 +33,12 @@ function parseTextPlainContent(mimeMessage: string) { if (bodies.length === 0) return mimeMessage; - let chosenBody = bodies.find((body) => body.headers['Content-Type'] === 'text/plain'); + if (bodies[0].headers['content-type']?.toLowerCase().startsWith('multipart/alternative')) + return parseTextPlainContent(bodies[0].content); + + let chosenBody = bodies.find((body) => + body.headers['content-type']?.toLowerCase()?.startsWith('text/plain') + ); if (!chosenBody) chosenBody = bodies[0]; const encoding = chosenBody.headers['content-transfer-encoding']; @@ -43,7 +48,11 @@ function parseTextPlainContent(mimeMessage: string) { case '7bit': return chosenBody.content; case 'base64': - return atob(chosenBody.content.replaceAll('\n', '')); + const raw = atob(chosenBody.content.replaceAll('\n', '')); + const bytes = new Uint8Array(raw.length); + for (let i = 0; i < raw.length; i++) bytes[i] = raw.charCodeAt(i); + const decoder = new TextDecoder('utf8'); + return decoder.decode(bytes); case 'quoted-printable': return chosenBody.content .replace(/=\r\n/g, '')