mirror of
https://github.com/moparisthebest/mail
synced 2024-12-01 05:12:21 -05:00
400 lines
14 KiB
JavaScript
400 lines
14 KiB
JavaScript
'use strict';
|
|
|
|
var Auth = require('../../../src/js/service/auth'),
|
|
PrivateKey = require('../../../src/js/service/privatekey'),
|
|
PGP = require('../../../src/js/crypto/pgp'),
|
|
Crypto = require('../../../src/js/crypto/crypto'),
|
|
axe = require('axe-logger'),
|
|
appConfig = require('../../../src/js/app-config'),
|
|
util = require('crypto-lib').util,
|
|
Mailbuild = require('mailbuild'),
|
|
mailreader = require('mailreader'),
|
|
ImapClient = require('imap-client');
|
|
|
|
describe('Private Key DAO unit tests', function() {
|
|
|
|
var privkeyDao, authStub, pgpStub, cryptoStub, imapClientStub,
|
|
emailAddress = 'test@example.com',
|
|
keyId = '12345',
|
|
salt = util.random(appConfig.config.symKeySize),
|
|
iv = util.random(appConfig.config.symIvSize),
|
|
encryptedPrivateKey = util.random(1024 * 8);
|
|
|
|
beforeEach(function() {
|
|
authStub = sinon.createStubInstance(Auth);
|
|
authStub.emailAddress = emailAddress;
|
|
pgpStub = sinon.createStubInstance(PGP);
|
|
cryptoStub = sinon.createStubInstance(Crypto);
|
|
privkeyDao = new PrivateKey(authStub, Mailbuild, mailreader, appConfig, pgpStub, cryptoStub, axe);
|
|
imapClientStub = sinon.createStubInstance(ImapClient);
|
|
privkeyDao._imap = imapClientStub;
|
|
});
|
|
|
|
afterEach(function() {});
|
|
|
|
describe('destroy', function() {
|
|
it('should work', function(done) {
|
|
privkeyDao.destroy().then(function() {
|
|
expect(imapClientStub.logout.calledOnce).to.be.true;
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('encrypt', function() {
|
|
it('should fail due to invalid args', function(done) {
|
|
privkeyDao.encrypt().catch(function(err) {
|
|
expect(err.message).to.match(/Incomplete/);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should work', function(done) {
|
|
cryptoStub.deriveKey.returns(resolves('derivedKey'));
|
|
pgpStub.exportKeys.returns(resolves({
|
|
keyId: keyId,
|
|
privateKeyArmored: 'PGP BLOCK'
|
|
}));
|
|
cryptoStub.encrypt.returns(resolves(encryptedPrivateKey));
|
|
|
|
privkeyDao.encrypt('asdf').then(function(encryptedKey) {
|
|
expect(encryptedKey._id).to.equal(keyId);
|
|
expect(encryptedKey.encryptedPrivateKey).to.equal(encryptedPrivateKey);
|
|
expect(encryptedKey.salt).to.exist;
|
|
expect(encryptedKey.iv).to.exist;
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('upload', function() {
|
|
it('should fail due to invalid args', function(done) {
|
|
privkeyDao.upload({}).catch(function(err) {
|
|
expect(err.message).to.match(/Incomplete/);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should work', function(done) {
|
|
var IMAP_KEYS_FOLDER = 'openpgp_keys';
|
|
var fullPath = 'INBOX.' + IMAP_KEYS_FOLDER;
|
|
|
|
imapClientStub.createFolder.withArgs({
|
|
path: IMAP_KEYS_FOLDER
|
|
}).returns(resolves(fullPath));
|
|
imapClientStub.uploadMessage.withArgs(sinon.match(function(arg) {
|
|
expect(arg.path).to.equal(fullPath);
|
|
expect(arg.message).to.exist;
|
|
return true;
|
|
})).returns(resolves());
|
|
|
|
privkeyDao.upload({
|
|
_id: keyId,
|
|
userId: emailAddress,
|
|
encryptedPrivateKey: encryptedPrivateKey,
|
|
salt: salt,
|
|
iv: iv
|
|
}).then(function() {
|
|
expect(imapClientStub.createFolder.calledOnce).to.be.true;
|
|
expect(imapClientStub.uploadMessage.calledOnce).to.be.true;
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('isSynced', function() {
|
|
beforeEach(function() {
|
|
sinon.stub(privkeyDao, '_fetchMessage');
|
|
});
|
|
afterEach(function() {
|
|
privkeyDao._fetchMessage.restore();
|
|
});
|
|
|
|
it('should be synced', function(done) {
|
|
privkeyDao._fetchMessage.returns(resolves({}));
|
|
|
|
privkeyDao.isSynced().then(function(synced) {
|
|
expect(synced).to.be.true;
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should not be synced', function(done) {
|
|
privkeyDao._fetchMessage.returns(resolves());
|
|
|
|
privkeyDao.isSynced().then(function(synced) {
|
|
expect(synced).to.be.false;
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should not be synced in case of error', function(done) {
|
|
privkeyDao._fetchMessage.returns(rejects(new Error()));
|
|
|
|
privkeyDao.isSynced().then(function(synced) {
|
|
expect(synced).to.be.false;
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('download', function() {
|
|
var base64Content = 'AYzsvV+hGMMT4BIl/XFjbl60BaM5DpDYVNyKPnoZ4ZyW1qy1udkQR7VUeNKJw5v2gWOqc3y6KHkZIqybOVro6e8tzhK1Fvpz+rgmME0tbrrh/Dd6QMBXb9c6ZAzgbLdq0sxftqXO9GoxINAVcfGN/MkcOIhonEjIsLSaYY2WLuGOLp8ZNdgO0tPxfcdd/f1hVXH2JRYmkOwStH3y2uYDmUhEWWeLfP2vF57F4NgtK2Ln4Ypn4VDx1SWtI6E1IMpwchpwXssBwzY2uWKUPNbWEwEYDU6pleWCKphc2YBp0ohJg1HfE+Et9/8wsZtQAjTiigZuovRd5ABd6LkCCuPNenmzKvR5os8fbe9HDsAiDYl5OrA1iGTWVcAKec1OWxRWKn3Ktt/v+W39gxvmA6OOSuPkA3PF+1rY2lU05busVlNVmNmv6vY3LTJz4J/jVPP7Bn6+Wl/BwdGC7OagZCORmDUujk4AaIz5y+x/hgS6g9yY8oaY5EGdFCxRpS7aptqiBNIXIpuxGtKZpP3bmjI4pIcVb4xTA57SFTE7czfvlvTjvBSCQP7MGYCNC+SbDRgt1beyM8uUrKiuLTWK+YJ6rvcIvOIEqvUBDR7ak+9S6+fyxw033vNHfQSAagIUC1eq+c8yoUzvtSRISOMEbu7MnjI5i4AQrD5yfJDJdp5NTpZ0Dz3fW3RVmMhghTGN3ch+6vVwkzO2ik11EGTqwaLfOgZuwunEonXLT4v4fJjIFvsl+hMab0keksuW1G8AQCdkNcgDfxMTIz6S/k51yVIGE2DZo1e1LTc7pu8gOCNHtuNMuwzDTZuutWdd0P93ZL7W6j1eq33DShX2zeuxk5S28crn6DdlK5QBYMSpECU1JDKRu1QMBNtiEgGlJaVOi1AQ+cDdZKthMYfJ0MPHCeRyQFMpEYkYUBfhBMnGaiDTmDFMvEy0WGhabKChhtdBF/rlyug8Kx9M60lx1t9dYVbxSmWkqWgUZ36vRwQXPVEWWmRROHtG/V9+CSPCCa9heDDqqj8nKzL0vK9kBG8nh2XlPAVg7ICicTLw0u93pz4US3pRKwfMys1mQNV0z0k0uXB1zJZqDrIsCihcUMC2vFOXg+dNlanPXeP8AMp3ojuMPAClIt+bxTyrjZ7MV0mkDuaWUaeEq2xuaU5cKlG1Aam6vSb3jmURgEzOk1onlkGrCfVUTne18W8V6KL7iG+lX+331baiZVGoMUXT++0T05KYBdTRYL0OZ0P3OPRqilPpxaZCY0NG5rJxC5ij0vnu9ECAvN3xSdiRF7SobVSVFIdc32aY24nLKv8/gSnROgmQbAqeCMOz0bULRyVTe0lzSXBcCgu5gK+KEo8p38trTSJ/S95sKQnyNbrnz2QOIXvzxLrL6/nnC/4pwxXKZ6XqB/2zLVfiJRjUQ1NUC0xDXA==';
|
|
var root = [{
|
|
type: 'attachment',
|
|
content: util.binStr2Uint8Arr(util.base642Str(base64Content))
|
|
}];
|
|
|
|
beforeEach(function() {
|
|
sinon.stub(privkeyDao, '_fetchMessage');
|
|
sinon.stub(privkeyDao, '_parse');
|
|
});
|
|
afterEach(function() {
|
|
privkeyDao._fetchMessage.restore();
|
|
privkeyDao._parse.restore();
|
|
});
|
|
|
|
it('should fail if key not synced', function(done) {
|
|
privkeyDao._fetchMessage.returns(resolves());
|
|
|
|
privkeyDao.download({
|
|
userId: emailAddress,
|
|
keyId: keyId
|
|
}).catch(function(err) {
|
|
expect(err.message).to.match(/not synced/);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should work', function(done) {
|
|
privkeyDao._fetchMessage.returns(resolves({}));
|
|
imapClientStub.getBodyParts.returns(resolves());
|
|
privkeyDao._parse.returns(resolves(root));
|
|
|
|
privkeyDao.download({
|
|
userId: emailAddress,
|
|
keyId: keyId
|
|
}).then(function(privkey) {
|
|
expect(privkey._id).to.equal(keyId);
|
|
expect(privkey.userId).to.equal(emailAddress);
|
|
expect(privkey.encryptedPrivateKey).to.exist;
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('decrypt', function() {
|
|
it('should fail due to invalid args', function(done) {
|
|
privkeyDao.decrypt({}).catch(function(err) {
|
|
expect(err.message).to.match(/Incomplete/);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should fail for invalid code', function(done) {
|
|
cryptoStub.deriveKey.returns(resolves('derivedKey'));
|
|
cryptoStub.decrypt.returns(rejects(new Error()));
|
|
|
|
privkeyDao.decrypt({
|
|
_id: keyId,
|
|
userId: emailAddress,
|
|
code: 'asdf',
|
|
encryptedPrivateKey: encryptedPrivateKey,
|
|
salt: salt,
|
|
iv: iv
|
|
}).catch(function(err) {
|
|
expect(err.message).to.match(/Invalid/);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should fail for invalid key params', function(done) {
|
|
cryptoStub.deriveKey.returns(resolves('derivedKey'));
|
|
cryptoStub.decrypt.returns(resolves('PGP BLOCK'));
|
|
pgpStub.getKeyParams.returns({
|
|
_id: '7890',
|
|
userId: emailAddress
|
|
});
|
|
|
|
privkeyDao.decrypt({
|
|
_id: keyId,
|
|
userId: emailAddress,
|
|
code: 'asdf',
|
|
encryptedPrivateKey: encryptedPrivateKey,
|
|
salt: salt,
|
|
iv: iv
|
|
}).catch(function(err) {
|
|
expect(err.message).to.match(/key parameters/);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should work', function(done) {
|
|
cryptoStub.deriveKey.returns(resolves('derivedKey'));
|
|
cryptoStub.decrypt.returns(resolves('PGP BLOCK'));
|
|
pgpStub.getKeyParams.returns({
|
|
_id: keyId,
|
|
userId: emailAddress
|
|
});
|
|
|
|
privkeyDao.decrypt({
|
|
_id: keyId,
|
|
userId: emailAddress,
|
|
code: 'asdf',
|
|
encryptedPrivateKey: encryptedPrivateKey,
|
|
salt: salt,
|
|
iv: iv
|
|
}).then(function(privkey) {
|
|
expect(privkey._id).to.equal(keyId);
|
|
expect(privkey.userId).to.equal(emailAddress);
|
|
expect(privkey.encryptedKey).to.equal('PGP BLOCK');
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('_fetchMessage', function() {
|
|
it('should fail due to invalid args', function(done) {
|
|
privkeyDao._fetchMessage({}).catch(function(err) {
|
|
expect(err.message).to.match(/Incomplete/);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should fail if imap folder does not exist', function(done) {
|
|
imapClientStub.listWellKnownFolders.returns(resolves({
|
|
Inbox: [{
|
|
path: 'INBOX'
|
|
}],
|
|
Other: [{
|
|
path: 'foo'
|
|
}]
|
|
}));
|
|
imapClientStub.listMessages.returns(rejects(new Error()));
|
|
|
|
privkeyDao._fetchMessage({
|
|
userId: emailAddress,
|
|
keyId: keyId
|
|
}).catch(function(err) {
|
|
expect(err.message).to.match(/Imap folder/);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should work', function(done) {
|
|
imapClientStub.listWellKnownFolders.returns(resolves({
|
|
Inbox: [{
|
|
path: 'INBOX'
|
|
}],
|
|
Other: [{
|
|
path: 'openpgp_keys'
|
|
}]
|
|
}));
|
|
imapClientStub.listMessages.returns(resolves([{
|
|
subject: keyId
|
|
}]));
|
|
|
|
privkeyDao._fetchMessage({
|
|
userId: emailAddress,
|
|
keyId: keyId
|
|
}).then(function(msg) {
|
|
expect(msg.subject).to.equal(keyId);
|
|
expect(imapClientStub.listWellKnownFolders.calledOnce).to.be.true;
|
|
expect(imapClientStub.listMessages.calledOnce).to.be.true;
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should work with path prefix', function(done) {
|
|
imapClientStub.listWellKnownFolders.returns(resolves({
|
|
Inbox: [{
|
|
path: 'INBOX'
|
|
}],
|
|
Other: [{
|
|
path: 'INBOX.openpgp_keys'
|
|
}]
|
|
}));
|
|
imapClientStub.listMessages.returns(resolves([{
|
|
subject: keyId
|
|
}]));
|
|
|
|
privkeyDao._fetchMessage({
|
|
userId: emailAddress,
|
|
keyId: keyId
|
|
}).then(function(msg) {
|
|
expect(msg.subject).to.equal(keyId);
|
|
expect(imapClientStub.listWellKnownFolders.calledOnce).to.be.true;
|
|
expect(imapClientStub.listMessages.calledOnce).to.be.true;
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should work for not matching message', function(done) {
|
|
imapClientStub.listWellKnownFolders.returns(resolves({
|
|
Other: [{
|
|
path: 'INBOX.openpgp_keys'
|
|
}]
|
|
}));
|
|
imapClientStub.listMessages.returns(resolves([{
|
|
subject: '7890'
|
|
}]));
|
|
|
|
privkeyDao._fetchMessage({
|
|
userId: emailAddress,
|
|
keyId: keyId
|
|
}).then(function(msg) {
|
|
expect(msg).to.not.exist;
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should work for no messages', function(done) {
|
|
imapClientStub.listWellKnownFolders.returns(resolves({
|
|
Other: [{
|
|
path: 'INBOX.openpgp_keys'
|
|
}]
|
|
}));
|
|
imapClientStub.listMessages.returns(resolves([]));
|
|
|
|
privkeyDao._fetchMessage({
|
|
userId: emailAddress,
|
|
keyId: keyId
|
|
}).then(function(msg) {
|
|
expect(msg).to.not.exist;
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('_parse', function() {
|
|
var root = {
|
|
foo: 'bar'
|
|
};
|
|
|
|
beforeEach(function() {
|
|
sinon.stub(mailreader, 'parse');
|
|
});
|
|
afterEach(function() {
|
|
mailreader.parse.restore();
|
|
});
|
|
|
|
it('should fail', function(done) {
|
|
mailreader.parse.yields(new Error('asdf'));
|
|
|
|
privkeyDao._parse().catch(function(err) {
|
|
expect(err.message).to.match(/asdf/);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should work', function(done) {
|
|
mailreader.parse.yields(null, root);
|
|
|
|
privkeyDao._parse().then(function(res) {
|
|
expect(res).to.equal(root);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
}); |