2023-06-29 18:26:45 +02:00
import o from "@tutao/otest"
2024-07-03 16:26:17 +02:00
import type { MailBundle } from "../../../../src/mail-app/mail/export/Bundler.js"
import { _formatSmtpDateTime , mailToEml } from "../../../../src/mail-app/mail/export/Exporter.js"
2022-12-27 15:37:40 +01:00
import { base64ToUint8Array , stringToUtf8Uint8Array } from "@tutao/tutanota-utils"
2024-07-01 17:56:41 +02:00
import { createDataFile } from "../../../../src/common/api/common/DataFile.js"
2021-03-02 12:42:41 +01:00
o . spec ( "Exporter" , function ( ) {
o . spec ( "mail to eml" , function ( ) {
o ( "most minimal eml" , function ( ) {
const now = Date . now ( )
const mostMinimalBundle : MailBundle = {
mailId : [ "" , "" ] ,
subject : "" ,
body : "" ,
2022-12-27 15:37:40 +01:00
sender : { address : "complaints@johnbotr.is" } ,
2021-03-02 12:42:41 +01:00
to : [ ] ,
cc : [ ] ,
bcc : [ ] ,
replyTo : [ ] ,
isDraft : false ,
isRead : true ,
sentOn : now ,
receivedOn : now ,
headers : null ,
2022-12-27 15:37:40 +01:00
attachments : [ ] ,
2021-03-02 12:42:41 +01:00
}
const actual = mailToEml ( mostMinimalBundle )
2022-12-27 15:37:40 +01:00
const expected = ` From: complaints@johnbotr.is \ r \ n \
2021-03-09 13:18:11 +01:00
MIME - Version : 1.0 \ r \ n \
Subject : \ r \ n \
Date : $ { _formatSmtpDateTime ( new Date ( now ) ) } \ r \ n \
Content - Type : multipart / related ; boundary = "------------79Bu5A16qPEYcVIZL@tutanota" \ r \ n \
\ r \ n \
-- -- -- -- -- -- -- 79 Bu5A16qPEYcVIZL @tutanota \ r \ n \
Content - Type : text / html ; charset = UTF - 8 \ r \ n \
Content - transfer - encoding : base64 \ r \ n \
\ r \ n \
\ r \ n \
2021-03-02 12:42:41 +01:00
-- -- -- -- -- -- -- 79 Bu5A16qPEYcVIZL @tutanota -- `
const actualLines = actual . split ( "\r\n" )
2021-03-09 13:18:11 +01:00
const expectedLines = expected . split ( "\r\n" )
2021-03-02 12:42:41 +01:00
o ( actualLines . length ) . equals ( expectedLines . length )
for ( let i = 0 ; i < Math . min ( expectedLines . length , actualLines . length ) ; ++ i ) {
o ( actualLines [ i ] ) . equals ( expectedLines [ i ] ) ( ` Line: ${ i } ` )
}
} )
o ( "non minimal eml with no headers" , function ( ) {
const now = Date . now ( )
const subject = "Hey, I know that guy, he’ s a nihilist."
const body = ` I’ m the Dude, so that’ s what you call me. That or, uh, His Dudeness, or uh, Duder, or El Duderino, if you’ re not into the whole brevity thing. <img src="cid:cid123" /> `
const attachment1 = createDataFile ( "file1.txt" , "text/plain" , stringToUtf8Uint8Array ( "this is a text file" ) )
2022-12-27 15:37:40 +01:00
const attachment2 = createDataFile (
"icon10x10.png" ,
"image/png" ,
base64ToUint8Array (
"iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAgVBMVEWgHiCgHh+gHiEAAACfHyGgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiD////HdIxaAAAAKXRSTlMAAAAAAImrqvvx5OX+oGaj1/r1w1MjV7P5lwEPjO+dIRb83pU8BnMqAyX2q3sAAAABYktHRCpTvtSeAAAACXBIWXMAAAcDAAAHAwGHNB/CAAAAB3RJTUUH5AkBDTcdD3SpngAAAE5JREFUCNc9ykUSgDAABMGFCIHg7q7//yCVhGJOfRgw7ug4g3i+BJ4/RdeT0jcMwihODNMsL8qqNm/TousVh3GChRnLuu0HbEIpzusG0b05dgnLISKbuAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMC0wOS0wMVQxMTo1NToyOSswMjowMNbkv24AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjAtMDktMDFUMTE6NTU6MjkrMDI6MDCnuQfSAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAABJRU5ErkJggg==" ,
) ,
)
2021-03-02 12:42:41 +01:00
attachment2 . cid = "123cid"
const bundle : MailBundle = {
mailId : [ "" , "" ] ,
subject ,
body ,
2022-12-27 15:37:40 +01:00
sender : { address : "lorem@ipsum.net" , name : "" } ,
to : [ { name : "guy1" , address : "guy1@guys.net" } , { name : "guy2" , address : "guy2@guys.net" } , { address : "guy2.5@guys.net" } ] ,
cc : [ { address : "guy3@guys.net" } , { name : "Dennis Dennisman" , address : "guy4@guys.net" } ] ,
bcc : [ { address : "guy5@guys.net" } , { name : "Sixth guy" , address : "guy6@guys.net" } ] ,
replyTo : [ { address : "guy7@guys.net" } , { name : "guy8" , address : "guy8@guys.net" } ] ,
2021-03-02 12:42:41 +01:00
isDraft : false ,
isRead : true ,
sentOn : now ,
receivedOn : now ,
headers : null ,
2022-12-27 15:37:40 +01:00
attachments : [ attachment1 , attachment2 ] ,
2021-03-02 12:42:41 +01:00
}
const actual = mailToEml ( bundle )
2022-12-27 15:37:40 +01:00
const expected = ` From: lorem@ipsum.net \ r \ n \
2021-03-09 13:18:11 +01:00
MIME - Version : 1.0 \ r \ n \
To : guy1 < guy1 @ guys.net > , guy2 < guy2 @ guys.net > , < guy2.5 @ guys.net > \ r \ n \
CC : < guy3 @ guys.net > , Dennis Dennisman < guy4 @ guys.net > \ r \ n \
BCC : < guy5 @ guys.net > , Sixth guy < guy6 @ guys.net > \ r \ n \
Subject : = ? UTF - 8 ? B ? SGV5LCBJIGtub3cgdGhhdCBndXksIGhl4oCZcyBhIG5paGlsaXN0Lg == ? = \ r \ n \
Date : $ { _formatSmtpDateTime ( new Date ( now ) ) } \ r \ n \
Content - Type : multipart / related ; boundary = "------------79Bu5A16qPEYcVIZL@tutanota" \ r \ n \
\ r \ n \
-- -- -- -- -- -- -- 79 Bu5A16qPEYcVIZL @tutanota \ r \ n \
Content - Type : text / html ; charset = UTF - 8 \ r \ n \
Content - transfer - encoding : base64 \ r \ n \
\ r \ n \
SeKAmW0gdGhlIER1ZGUsIHNvIHRoYXTigJlzIHdoYXQgeW91IGNhbGwgbWUuIFRoYXQgb3IsIHVoLC \ r \ n \
BIaXMgRHVkZW5lc3MsIG9yIHVoLCBEdWRlciwgb3IgRWwgRHVkZXJpbm8sIGlmIHlvdeKAmXJlIG5v \ r \ n \
dCBpbnRvIHRoZSB3aG9sZSBicmV2aXR5IHRoaW5nLiA8aW1nIHNyYz0iY2lkOmNpZDEyMyIgLz4 = \ r \ n \
\ r \ n \
-- -- -- -- -- -- -- 79 Bu5A16qPEYcVIZL @tutanota \ r \ n \
Content - Type : text / plain ; \ r \ n \
name == ? UTF - 8 ? B ? ZmlsZTEudHh0 ? = \ r \ n \
Content - Transfer - Encoding : base64 \ r \ n \
Content - Disposition : attachment ; \ r \ n \
filename == ? UTF - 8 ? B ? ZmlsZTEudHh0 ? = \ r \ n \
\ r \ n \
dGhpcyBpcyBhIHRleHQgZmlsZQ == \ r \ n \
\ r \ n \
-- -- -- -- -- -- -- 79 Bu5A16qPEYcVIZL @tutanota \ r \ n \
Content - Type : image / png ; \ r \ n \
name == ? UTF - 8 ? B ? aWNvbjEweDEwLnBuZw == ? = \ r \ n \
Content - Transfer - Encoding : base64 \ r \ n \
Content - Disposition : attachment ; \ r \ n \
filename == ? UTF - 8 ? B ? aWNvbjEweDEwLnBuZw == ? = \ r \ n \
Content - Id : < 123cid > \ r \ n \
\ r \ n \
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D + PAAAABGdBTUEAALGPC / xhBQAAACBjSFJNAA \ r \ n \
B6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAgVBMVEWgHiCgHh + gHiEAAACfHyGg \ r \ n \
HiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHi \ r \ n \
CgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiCgHiD ////HdIxa\r\n\
AAAAKXRSTlMAAAAAAImrqvvx5OX + oGaj1 / r1w1MjV7P5lwEPjO + dIRb83pU8BnMqAyX2q3sAAAABYk \ r \ n \
tHRCpTvtSeAAAACXBIWXMAAAcDAAAHAwGHNB / CAAAAB3RJTUUH5AkBDTcdD3SpngAAAE5JREFUCNc9 \ r \ n \
ykUSgDAABMGFCIHg7q7 //yCVhGJOfRgw7ug4g3i+BJ4/RdeT0jcMwihODNMsL8qqNm/TousVh3GChR\r\n\
nLuu0HbEIpzusG0b05dgnLISKbuAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMC0wOS0wMVQxMTo1NToy \ r \ n \
OSswMjowMNbkv24AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjAtMDktMDFUMTE6NTU6MjkrMDI6MDCnuQ \ r \ n \
fSAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm + 48 GgAAAABJRU5ErkJggg == \ r \ n \
\ r \ n \
2021-03-02 12:42:41 +01:00
-- -- -- -- -- -- -- 79 Bu5A16qPEYcVIZL @tutanota -- `
const actualLines = actual . split ( "\r\n" )
2021-03-09 13:18:11 +01:00
const expectedLines = expected . split ( "\r\n" )
2021-03-02 12:42:41 +01:00
o ( actualLines . length ) . equals ( expectedLines . length ) ( "check length" )
for ( let i = 0 ; i < Math . min ( expectedLines . length , actualLines . length ) ; ++ i ) {
o ( actualLines [ i ] ) . equals ( expectedLines [ i ] ) ( ` Line: ${ i } ` )
}
} )
o ( "email with headers" , function ( ) {
2023-09-21 17:28:49 +02:00
// the first few lines have wrong line endings, but we should handle that
const headers = ` Received: from x.y.test \ n \
by example . net \ n \
via TCP \ n \
with ESMTP \ r \ n \
id ABC12345 \ r \ n \
for < mary @ example.net > ; 21 Nov 1997 10 :05 : 43 - 0600 \ r \ n \
Received : from node . example by x . y . test ; 21 Nov 1997 10 :01 : 22 - 0600 \ r \ n \
From : John Doe < jdoe @ node.example > \ r \ n \
To : Mary Smith < mary @ example.net > \ r \ n \
Subject : Saying Hello \ r \ n \
Date : Fri , 21 Nov 1997 09 :55 : 06 - 0600 \ r \ n \
2021-03-02 12:42:41 +01:00
Message - ID : < 1234 @ local.node.example > `
const now = Date . now ( )
const bundle : MailBundle = {
mailId : [ "" , "" ] ,
subject : "Saying hello" ,
body : "" ,
2022-12-27 15:37:40 +01:00
sender : { address : "jdoe@node.example" } ,
to : [ { address : "mary@example.net" } ] ,
2021-03-02 12:42:41 +01:00
cc : [ ] ,
bcc : [ ] ,
replyTo : [ ] ,
isDraft : false ,
isRead : true ,
sentOn : now ,
receivedOn : now ,
headers ,
2022-12-27 15:37:40 +01:00
attachments : [ ] ,
2021-03-02 12:42:41 +01:00
}
const actual = mailToEml ( bundle )
2023-09-21 17:28:49 +02:00
const expected = ` Received: from x.y.test \ r \ n \
by example . net \ r \ n \
via TCP \ r \ n \
with ESMTP \ r \ n \
id ABC12345 \ r \ n \
for < mary @ example.net > ; 21 Nov 1997 10 :05 : 43 - 0600 \ r \ n \
Received : from node . example by x . y . test ; 21 Nov 1997 10 :01 : 22 - 0600 \ r \ n \
From : John Doe < jdoe @ node.example > \ r \ n \
To : Mary Smith < mary @ example.net > \ r \ n \
Subject : Saying Hello \ r \ n \
Date : Fri , 21 Nov 1997 09 :55 : 06 - 0600 \ r \ n \
2021-03-09 13:18:11 +01:00
Message - ID : < 1234 @ local.node.example > \ r \ n \
Content - Type : multipart / related ; boundary = "------------79Bu5A16qPEYcVIZL@tutanota" \ r \ n \
\ r \ n \
-- -- -- -- -- -- -- 79 Bu5A16qPEYcVIZL @tutanota \ r \ n \
Content - Type : text / html ; charset = UTF - 8 \ r \ n \
Content - transfer - encoding : base64 \ r \ n \
\ r \ n \
\ r \ n \
2021-03-02 12:42:41 +01:00
-- -- -- -- -- -- -- 79 Bu5A16qPEYcVIZL @tutanota -- `
const actualLines = actual . split ( "\r\n" )
2021-03-09 13:18:11 +01:00
const expectedLines = expected . split ( "\r\n" )
2021-03-02 12:42:41 +01:00
o ( actualLines . length ) . equals ( expectedLines . length )
for ( let i = 0 ; i < Math . min ( expectedLines . length , actualLines . length ) ; ++ i ) {
o ( actualLines [ i ] ) . equals ( expectedLines [ i ] ) ( ` Line: ${ i } ` )
}
} )
} )
2022-12-27 15:37:40 +01:00
} )