wildduck/test/filtering-test.js

401 lines
18 KiB
JavaScript
Raw Normal View History

/*eslint no-unused-expressions: 0, prefer-arrow-callback: 0, no-console: 0 */
/* global before */
'use strict';
2017-10-20 04:33:36 +08:00
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
const crypto = require('crypto');
//const util = require('util');
const chai = require('chai');
const request = require('request');
const fs = require('fs');
const simpleParser = require('mailparser').simpleParser;
const nodemailer = require('nodemailer');
const { ImapFlow } = require('imapflow');
const transporter = nodemailer.createTransport({
lmtp: true,
host: 'localhost',
port: 2424,
logger: false,
debug: false,
tls: {
rejectUnauthorized: false
}
});
const expect = chai.expect;
chai.config.includeStack = true;
2019-08-27 21:20:23 +08:00
const URL = 'http://127.0.0.1:8080';
const user2PubKey = fs.readFileSync(__dirname + '/fixtures/user2-public.key', 'utf-8');
const user3PubKey = fs.readFileSync(__dirname + '/fixtures/user3-public.key', 'utf-8');
2020-05-08 15:55:07 +08:00
describe('Send multiple messages', function () {
this.timeout(100 * 1000); // eslint-disable-line
let userIds = [];
before(done => {
request.post(
URL + '/users',
{
json: {
username: 'user1',
password: 'secretpass',
address: 'user1@example.com',
name: 'user1'
}
},
(err, meta, response) => {
expect(err).to.not.exist;
expect(response.success).to.be.true;
userIds.push(response.id);
request.post(
URL + '/users',
{
json: {
username: 'user2',
password: 'secretpass',
address: 'user2@example.com',
name: 'user2',
pubKey: user2PubKey,
2017-10-30 19:41:53 +08:00
encryptMessages: true,
encryptForwarded: true
}
},
(err, meta, response) => {
expect(err).to.not.exist;
expect(response.success).to.be.true;
userIds.push(response.id);
request.post(
URL + '/users',
{
json: {
username: 'user3',
password: 'secretpass',
address: 'user3@example.com',
name: 'user3',
pubKey: user3PubKey,
2017-10-30 19:41:53 +08:00
encryptMessages: true,
encryptForwarded: true
}
},
(err, meta, response) => {
expect(err).to.not.exist;
expect(response.success).to.be.true;
userIds.push(response.id);
request.post(
URL + '/users',
{
json: {
username: 'user4',
password: 'secretpass',
address: 'user4@example.com',
name: 'user4',
pubKey: user2PubKey,
2017-10-30 19:41:53 +08:00
encryptMessages: false,
encryptForwarded: true
}
},
(err, meta, response) => {
expect(err).to.not.exist;
expect(response.success).to.be.true;
userIds.push(response.id);
request.post(
URL + '/users',
{
json: {
username: 'user5',
password: 'secretpass',
address: 'user5@example.com',
name: 'user5'
}
},
(err, meta, response) => {
expect(err).to.not.exist;
expect(response.success).to.be.true;
userIds.push(response.id);
done();
}
);
}
);
}
);
}
);
}
);
});
it('Should have users set', done => {
expect(userIds.length).to.equal(5);
done();
});
it('Send mail to all users', done => {
let recipients = ['user1@example.com', 'user2@example.com', 'user3@example.com', 'user4@example.com', 'user5@example.com'];
let subject = 'Test ööö message [' + Date.now() + ']';
transporter.sendMail(
{
envelope: {
from: 'andris@kreata.ee',
to: recipients
},
headers: {
// set to Yes to send this message to Junk folder
'x-rspamd-spam': 'No'
},
from: 'Kärbes 🐧 <andris@kreata.ee>',
to: recipients.map((rcpt, i) => ({ name: 'User #' + (i + 1), address: rcpt })),
subject,
text: 'Hello world! Current time is ' + new Date().toString(),
html:
'<p>Hello world! Current time is <em>' +
new Date().toString() +
'</em> <img src="cid:note@example.com"/> <img src="http://www.neti.ee/img/neti-logo-2015-1.png"></p>',
attachments: [
// attachment as plaintext
{
filename: 'notes.txt',
content: 'Some notes about this e-mail',
contentType: 'text/plain' // optional, would be detected from the filename
},
// Small Binary Buffer attachment, should be kept with message
{
filename: 'image.png',
2018-05-11 19:39:23 +08:00
content: Buffer.from(
'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/' +
'//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U' +
'g9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC',
'base64'
),
cid: 'note@example.com' // should be as unique as possible
},
// Large Binary Buffer attachment, should be kept separately
{
path: __dirname + '/../examples/swan.jpg',
filename: 'swän.jpg'
}
]
},
(err, info) => {
expect(err).to.not.exist;
expect(info.accepted).to.deep.equal(['user1@example.com', 'user2@example.com', 'user3@example.com', 'user4@example.com', 'user5@example.com']);
let getFirstMessage = (userId, callback) => {
request(URL + '/users/' + userId + '/mailboxes', { json: true }, (err, meta, response) => {
expect(err).to.not.exist;
expect(response.success).to.be.true;
let inbox = response.results.find(mbox => mbox.path === 'INBOX');
request(URL + '/users/' + userId + '/mailboxes/' + inbox.id + '/messages', { json: true }, (err, meta, response) => {
expect(err).to.not.exist;
expect(response.success).to.be.true;
let message = response.results[0];
expect(message).to.exist;
request(URL + '/users/' + userId + '/mailboxes/' + inbox.id + '/messages/' + message.id, { json: true }, (err, meta, message) => {
expect(err).to.not.exist;
let processAttachments = next => {
let pos = 0;
let getAttachments = () => {
if (pos >= message.attachments.length) {
return next();
}
let attachment = message.attachments[pos++];
2017-11-30 19:57:25 +08:00
request(
URL +
'/users/' +
message.user +
'/mailboxes/' +
message.mailbox +
'/messages/' +
message.id +
'/attachments/' +
attachment.id,
{ encoding: null },
(err, meta, raw) => {
expect(err).to.not.exist;
attachment.raw = raw;
setImmediate(getAttachments);
}
);
};
setImmediate(getAttachments);
};
processAttachments(() => {
request(
URL + '/users/' + userId + '/mailboxes/' + inbox.id + '/messages/' + message.id + '/message.eml',
(err, meta, raw) => {
expect(err).to.not.exist;
message.raw = raw;
simpleParser(raw, (err, parsed) => {
expect(err).to.not.exist;
message.parsed = parsed;
callback(null, message);
});
}
);
});
});
});
});
};
let checkNormalUsers = next => {
let npos = 0;
let nusers = [1, 4, 5];
let checkUser = () => {
if (npos >= nusers.length) {
return next();
}
let user = nusers[npos++];
getFirstMessage(userIds[user - 1], (err, message) => {
expect(err).to.not.exist;
expect(message.subject).to.equal(subject);
expect(message.attachments.length).to.equal(3);
expect(message.parsed.attachments.length).to.equal(3);
for (let i = 0; i < message.attachments.length; i++) {
2020-05-08 15:55:07 +08:00
let hashA = crypto.createHash('md5').update(message.attachments[i].raw).digest('hex');
let hashB = crypto.createHash('md5').update(message.parsed.attachments[i].content).digest('hex');
expect(hashA).equal(hashB);
}
expect(message.parsed.to.value).deep.equal([
{ address: 'user1@example.com', name: 'User #1' },
{ address: 'user2@example.com', name: 'User #2' },
{ address: 'user3@example.com', name: 'User #3' },
{ address: 'user4@example.com', name: 'User #4' },
{ address: 'user5@example.com', name: 'User #5' }
]);
expect(message.parsed.headers.get('delivered-to').value[0].address).equal('user' + user + '@example.com');
setImmediate(checkUser);
});
};
setImmediate(checkUser);
};
let checkEncryptedUsers = next => {
let npos = 0;
let nusers = [2, 3];
let checkUser = () => {
if (npos >= nusers.length) {
return next();
}
let user = nusers[npos++];
getFirstMessage(userIds[user - 1], (err, message) => {
expect(err).to.not.exist;
expect(message.subject).to.equal(subject);
expect(message.parsed.to.value).deep.equal([
{ address: 'user1@example.com', name: 'User #1' },
{ address: 'user2@example.com', name: 'User #2' },
{ address: 'user3@example.com', name: 'User #3' },
{ address: 'user4@example.com', name: 'User #4' },
{ address: 'user5@example.com', name: 'User #5' }
]);
expect(message.parsed.headers.get('delivered-to').value[0].address).equal('user' + user + '@example.com');
expect(message.parsed.attachments.length).equal(2);
expect(message.parsed.attachments[0].contentType).equal('application/pgp-encrypted');
expect(message.parsed.attachments[0].content.toString()).equal('Version: 1\r\n');
expect(message.parsed.attachments[1].contentType).equal('application/octet-stream');
expect(message.parsed.attachments[1].filename).equal('encrypted.asc');
expect(message.parsed.attachments[1].size).gte(1000000);
setImmediate(checkUser);
});
};
setImmediate(checkUser);
};
checkNormalUsers(() => checkEncryptedUsers(() => done()));
}
);
});
2017-10-20 04:33:36 +08:00
it('should fetch messages from IMAP', done => {
2018-05-11 19:39:23 +08:00
let imagePng = Buffer.from(
2017-10-20 04:33:36 +08:00
'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/' +
'//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U' +
'g9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC',
'base64'
);
let textTxt = 'Some notes about this e-mail';
let swanJpg = fs.readFileSync(__dirname + '/../examples/swan.jpg');
let checksums = [
2020-05-08 15:55:07 +08:00
crypto.createHash('md5').update(imagePng).digest('hex'),
crypto.createHash('md5').update(Buffer.from(textTxt)).digest('hex'),
crypto.createHash('md5').update(swanJpg).digest('hex')
2017-10-20 04:33:36 +08:00
];
const client = new ImapFlow({
host: '127.0.0.1',
port: 9993,
secure: true,
2017-10-20 04:33:36 +08:00
auth: {
user: 'user4',
pass: 'secretpass'
},
tls: {
rejectUnauthorized: false
},
clientInfo: {
name: 'My Client',
version: '0.1'
2017-10-20 04:33:36 +08:00
}
});
client.on('error', err => {
2017-10-20 04:33:36 +08:00
expect(err).to.not.exist;
done();
});
client.on('close', () => done());
2017-10-20 04:33:36 +08:00
client
.connect()
.then(async () => {
const result = await client.list();
const folders = result.map(mbox => ({ name: mbox.name, specialUse: mbox.specialUse || false })).sort((a, b) => a.name.localeCompare(b.name));
2017-10-20 04:33:36 +08:00
expect(folders).to.deep.equal([
{ name: 'Drafts', specialUse: '\\Drafts' },
{ name: 'INBOX', specialUse: '\\Inbox' },
2017-10-20 04:33:36 +08:00
{ name: 'Junk', specialUse: '\\Junk' },
{ name: 'Sent Mail', specialUse: '\\Sent' },
{ name: 'Trash', specialUse: '\\Trash' }
]);
const mailbox = await client.mailboxOpen('INBOX');
expect(mailbox.exists).gte(1);
2017-10-20 04:33:36 +08:00
let messages = [];
for await (let msg of client.fetch(mailbox.exists, { uid: true, source: true })) {
messages.push(msg);
}
expect(messages.length).equal(1);
let messageInfo = messages[0];
let parsed = await simpleParser(messageInfo.source);
checksums.forEach((checksum, i) => {
expect(checksum).to.equal(parsed.attachments[i].checksum);
2017-10-20 04:33:36 +08:00
});
client.close();
})
.catch(err => {
expect(err).to.not.exist;
client.close();
2017-10-20 04:33:36 +08:00
});
});
});