2022-02-11 18:01:07 +08:00
|
|
|
|
|
|
|
import { ParseMime } from 'Mime/Parser';
|
|
|
|
import { AttachmentModel } from 'Model/Attachment';
|
2022-05-12 05:13:24 +08:00
|
|
|
import { EmailModel } from 'Model/Email';
|
2022-02-11 18:01:07 +08:00
|
|
|
import { FileInfo } from 'Common/File';
|
|
|
|
import { BEGIN_PGP_MESSAGE } from 'Stores/User/Pgp';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string data
|
|
|
|
* @param MessageModel message
|
|
|
|
*/
|
|
|
|
export function MimeToMessage(data, message)
|
|
|
|
{
|
|
|
|
let signed;
|
|
|
|
const struct = ParseMime(data);
|
|
|
|
if (struct.headers) {
|
|
|
|
let html = struct.getByContentType('text/html');
|
|
|
|
html = html ? html.body : '';
|
|
|
|
|
2022-05-12 05:13:24 +08:00
|
|
|
if (struct.headers.subject) {
|
|
|
|
message.subject(struct.headers.subject.value);
|
|
|
|
}
|
|
|
|
['from','to'].forEach(name => {
|
2022-05-12 21:11:07 +08:00
|
|
|
if (struct.headers[name] && !message[name].length) {
|
2022-05-12 05:13:24 +08:00
|
|
|
let mail = new EmailModel;
|
|
|
|
mail.parse(struct.headers[name].value);
|
|
|
|
message[name].push(mail);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2022-02-11 18:01:07 +08:00
|
|
|
struct.forEach(part => {
|
|
|
|
let cd = part.header('content-disposition'),
|
|
|
|
cid = part.header('content-id'),
|
|
|
|
type = part.header('content-type');
|
|
|
|
if (cid || cd) {
|
|
|
|
// if (cd && 'attachment' === cd.value) {
|
|
|
|
let attachment = new AttachmentModel;
|
|
|
|
attachment.mimeType = type.value;
|
|
|
|
attachment.fileName = type.name || (cd && cd.params.filename) || '';
|
|
|
|
attachment.fileNameExt = attachment.fileName.replace(/^.+(\.[a-z]+)$/, '$1');
|
|
|
|
attachment.fileType = FileInfo.getType('', type.value);
|
|
|
|
attachment.url = part.dataUrl;
|
|
|
|
attachment.friendlySize = FileInfo.friendlySize(part.body.length);
|
|
|
|
/*
|
|
|
|
attachment.isThumbnail = false;
|
|
|
|
attachment.contentLocation = '';
|
|
|
|
attachment.download = '';
|
|
|
|
attachment.folder = '';
|
|
|
|
attachment.uid = '';
|
|
|
|
attachment.mimeIndex = part.id;
|
|
|
|
*/
|
|
|
|
attachment.cid = cid ? cid.value : '';
|
|
|
|
if (cid && html) {
|
|
|
|
let cid = 'cid:' + attachment.contentId(),
|
|
|
|
found = html.includes(cid);
|
|
|
|
attachment.isInline(found);
|
|
|
|
attachment.isLinked(found);
|
|
|
|
found && (html = html
|
|
|
|
.replace('src="' + cid + '"', 'src="' + attachment.url + '"')
|
|
|
|
.replace("src='" + cid + "'", "src='" + attachment.url + "'")
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
message.attachments.push(attachment);
|
|
|
|
}
|
|
|
|
} else if ('multipart/signed' === type.value && 'application/pgp-signature' === type.params.protocol) {
|
|
|
|
signed = {
|
|
|
|
MicAlg: type.micalg,
|
|
|
|
BodyPart: part.parts[0],
|
|
|
|
SigPart: part.parts[1]
|
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
const text = struct.getByContentType('text/plain');
|
|
|
|
message.plain(text ? text.body : '');
|
|
|
|
message.html(html);
|
|
|
|
} else {
|
|
|
|
message.plain(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!signed && message.plain().includes(BEGIN_PGP_MESSAGE)) {
|
|
|
|
signed = true;
|
|
|
|
}
|
|
|
|
message.pgpSigned(signed);
|
|
|
|
|
|
|
|
// TODO: Verify instantly?
|
|
|
|
}
|