mirror of
https://github.com/moparisthebest/mail
synced 2025-01-30 22:50:17 -05:00
add missing methods and tests
This commit is contained in:
parent
150cf23948
commit
0c1003c48f
@ -434,10 +434,136 @@ define(function(require) {
|
||||
}
|
||||
};
|
||||
|
||||
EmailDAO.prototype.markRead = function(options, callback) {
|
||||
this._imapClient.updateFlags({
|
||||
path: options.folder,
|
||||
uid: options.uid,
|
||||
unread: false
|
||||
}, callback);
|
||||
};
|
||||
|
||||
EmailDAO.prototype.markAnswered = function(options, callback) {
|
||||
this._imapClient.updateFlags({
|
||||
path: options.folder,
|
||||
uid: options.uid,
|
||||
answered: true
|
||||
}, callback);
|
||||
};
|
||||
|
||||
EmailDAO.prototype.encryptedSend = function(options, callback) {
|
||||
var self = this,
|
||||
email = options.email;
|
||||
|
||||
// validate the email input
|
||||
if (!email.to || !email.from || !email.to[0].address || !email.from[0].address) {
|
||||
callback({
|
||||
errMsg: 'Invalid email object!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// validate email addresses
|
||||
for (var i = email.to.length - 1; i >= 0; i--) {
|
||||
if (!util.validateEmailAddress(email.to[i].address)) {
|
||||
callback({
|
||||
errMsg: 'Invalid recipient: ' + email.to[i].address
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!util.validateEmailAddress(email.from[0].address)) {
|
||||
callback({
|
||||
errMsg: 'Invalid sender: ' + email.from
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// only support single recipient for e-2-e encryption
|
||||
// check if receiver has a public key
|
||||
self._keychain.getReceiverPublicKey(email.to[0].address, function(err, receiverPubkey) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// validate public key
|
||||
if (!receiverPubkey) {
|
||||
callback({
|
||||
errMsg: 'User has no public key yet!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// public key found... encrypt and send
|
||||
self._encrypt({
|
||||
email: email,
|
||||
keys: receiverPubkey.publicKey
|
||||
}, function(err, email) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
self.send({
|
||||
email: email
|
||||
}, callback);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
EmailDAO.prototype.send = function(options, callback) {
|
||||
this._smtpClient.send(options.email, callback);
|
||||
};
|
||||
|
||||
//
|
||||
// Internal API
|
||||
//
|
||||
|
||||
// Encryption API
|
||||
|
||||
EmailDAO.prototype._encrypt = function(options, callback) {
|
||||
var self = this,
|
||||
pt = options.email.body;
|
||||
|
||||
options.keys = [options.keys] || [];
|
||||
|
||||
// get own public key so send message can be read
|
||||
self._crypto.exportKeys(function(err, ownKeys) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// add own public key to receiver list
|
||||
options.keys.push(ownKeys.publicKeyArmored);
|
||||
// encrypt the email
|
||||
self._crypto.encrypt(pt, options.keys, function(err, ct) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// bundle encrypted email together for sending
|
||||
frameEncryptedMessage(options.email, ct);
|
||||
callback(null, options.email);
|
||||
});
|
||||
});
|
||||
|
||||
function frameEncryptedMessage(email, ct) {
|
||||
var greeting,
|
||||
message = str.message + '\n\n\n',
|
||||
signature = '\n\n' + str.signature + '\n\n';
|
||||
|
||||
// get first name of recipient
|
||||
greeting = 'Hi ' + (email.to[0].name || email.to[0].address).split('@')[0].split('.')[0].split(' ')[0] + ',\n\n';
|
||||
|
||||
// build encrypted text body
|
||||
email.body = greeting + message + ct + signature;
|
||||
email.subject = email.subject;
|
||||
}
|
||||
};
|
||||
|
||||
// Local Storage API
|
||||
|
||||
EmailDAO.prototype._localListMessages = function(options, callback) {
|
||||
|
@ -15,7 +15,7 @@ define(function(require) {
|
||||
var dao, keychainStub, imapClientStub, smtpClientStub, pgpStub, devicestorageStub;
|
||||
|
||||
var emailAddress, passphrase, asymKeySize, mockkeyId, dummyEncryptedMail,
|
||||
dummyDecryptedMail, mockKeyPair, account;
|
||||
dummyDecryptedMail, mockKeyPair, account, publicKey;
|
||||
|
||||
beforeEach(function() {
|
||||
emailAddress = 'asdf@asdf.com';
|
||||
@ -60,6 +60,7 @@ define(function(require) {
|
||||
emailAddress: emailAddress,
|
||||
asymKeySize: asymKeySize,
|
||||
};
|
||||
publicKey = "-----BEGIN PUBLIC KEY-----\r\n" + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxy+Te5dyeWd7g0P+8LNO7fZDQ\r\n" + "g96xTb1J6pYE/pPTMlqhB6BRItIYjZ1US5q2vk5Zk/5KasBHAc9RbCqvh9v4XFEY\r\n" + "JVmTXC4p8ft1LYuNWIaDk+R3dyYXmRNct/JC4tks2+8fD3aOvpt0WNn3R75/FGBt\r\n" + "h4BgojAXDE+PRQtcVQIDAQAB\r\n" + "-----END PUBLIC KEY-----";
|
||||
|
||||
keychainStub = sinon.createStubInstance(KeychainDAO);
|
||||
imapClientStub = sinon.createStubInstance(ImapClient);
|
||||
@ -694,7 +695,198 @@ define(function(require) {
|
||||
folder: folder
|
||||
}, after);
|
||||
});
|
||||
});
|
||||
|
||||
describe('markAsRead', function() {
|
||||
it('should work', function(done) {
|
||||
imapClientStub.updateFlags.yields();
|
||||
|
||||
dao.markRead({
|
||||
folder: 'asdf',
|
||||
uid: 1
|
||||
}, function(err) {
|
||||
expect(imapClientStub.updateFlags.calledOnce).to.be.true;
|
||||
expect(err).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('markAsAnswered', function() {
|
||||
it('should work', function(done) {
|
||||
imapClientStub.updateFlags.yields();
|
||||
|
||||
dao.markAnswered({
|
||||
folder: 'asdf',
|
||||
uid: 1
|
||||
}, function(err) {
|
||||
expect(imapClientStub.updateFlags.calledOnce).to.be.true;
|
||||
expect(err).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('send', function() {
|
||||
it('should work', function(done) {
|
||||
smtpClientStub.send.withArgs(dummyEncryptedMail).yields();
|
||||
|
||||
dao.send({
|
||||
email: dummyEncryptedMail
|
||||
}, function(err) {
|
||||
expect(err).to.not.exist;
|
||||
expect(smtpClientStub.send.calledOnce).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('encryptedSend', function() {
|
||||
it('should work', function(done) {
|
||||
var encryptStub = sinon.stub(dao, '_encrypt').yields(null, {});
|
||||
keychainStub.getReceiverPublicKey.withArgs(dummyDecryptedMail.to[0].address).yields(null, {
|
||||
_id: "fcf8b4aa-5d09-4089-8b4f-e3bc5091daf3",
|
||||
userId: dummyDecryptedMail.to[0].address,
|
||||
publicKey: publicKey
|
||||
});
|
||||
smtpClientStub.send.yields();
|
||||
|
||||
dao.encryptedSend({
|
||||
email: dummyDecryptedMail
|
||||
}, function(err) {
|
||||
expect(err).to.not.exist;
|
||||
|
||||
expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true;
|
||||
expect(encryptStub.calledOnce).to.be.true;
|
||||
expect(smtpClientStub.send.calledOnce).to.be.true;
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should not work when encryption fails', function(done) {
|
||||
var encryptStub = sinon.stub(dao, '_encrypt').yields({});
|
||||
keychainStub.getReceiverPublicKey.withArgs(dummyDecryptedMail.to[0].address).yields(null, {
|
||||
_id: "fcf8b4aa-5d09-4089-8b4f-e3bc5091daf3",
|
||||
userId: dummyDecryptedMail.to[0].address,
|
||||
publicKey: publicKey
|
||||
});
|
||||
|
||||
dao.encryptedSend({
|
||||
email: dummyDecryptedMail
|
||||
}, function(err) {
|
||||
expect(err).to.exist;
|
||||
|
||||
expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true;
|
||||
expect(encryptStub.calledOnce).to.be.true;
|
||||
expect(smtpClientStub.send.called).to.be.false;
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should not work when key retrieval fails', function(done) {
|
||||
var encryptStub = sinon.stub(dao, '_encrypt');
|
||||
keychainStub.getReceiverPublicKey.withArgs(dummyDecryptedMail.to[0].address).yields({});
|
||||
|
||||
dao.encryptedSend({
|
||||
email: dummyDecryptedMail
|
||||
}, function(err) {
|
||||
expect(err).to.exist;
|
||||
|
||||
expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true;
|
||||
expect(encryptStub.called).to.be.false;
|
||||
expect(smtpClientStub.send.called).to.be.false;
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should not work invalid recipients', function(done) {
|
||||
var encryptStub = sinon.stub(dao, '_encrypt');
|
||||
dummyDecryptedMail.to[0].address = 'asd@asd';
|
||||
|
||||
dao.encryptedSend({
|
||||
email: dummyDecryptedMail
|
||||
}, function(err) {
|
||||
expect(err).to.exist;
|
||||
|
||||
expect(keychainStub.getReceiverPublicKey.called).to.be.false;
|
||||
expect(encryptStub.called).to.be.false;
|
||||
expect(smtpClientStub.send.called).to.be.false;
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should not work with without sender', function(done) {
|
||||
var encryptStub = sinon.stub(dao, '_encrypt');
|
||||
dummyDecryptedMail.from[0].address = 'asd@asd';
|
||||
|
||||
dao.encryptedSend({
|
||||
email: dummyDecryptedMail
|
||||
}, function(err) {
|
||||
expect(err).to.exist;
|
||||
|
||||
expect(keychainStub.getReceiverPublicKey.called).to.be.false;
|
||||
expect(encryptStub.called).to.be.false;
|
||||
expect(smtpClientStub.send.called).to.be.false;
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should not work without recipients', function(done) {
|
||||
var encryptStub = sinon.stub(dao, '_encrypt');
|
||||
delete dummyDecryptedMail.to;
|
||||
|
||||
dao.encryptedSend({
|
||||
email: dummyDecryptedMail
|
||||
}, function(err) {
|
||||
expect(err).to.exist;
|
||||
|
||||
expect(keychainStub.getReceiverPublicKey.called).to.be.false;
|
||||
expect(encryptStub.called).to.be.false;
|
||||
expect(smtpClientStub.send.called).to.be.false;
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should not work with without sender', function(done) {
|
||||
var encryptStub = sinon.stub(dao, '_encrypt');
|
||||
delete dummyDecryptedMail.from;
|
||||
|
||||
dao.encryptedSend({
|
||||
email: dummyDecryptedMail
|
||||
}, function(err) {
|
||||
expect(err).to.exist;
|
||||
|
||||
expect(keychainStub.getReceiverPublicKey.called).to.be.false;
|
||||
expect(encryptStub.called).to.be.false;
|
||||
expect(smtpClientStub.send.called).to.be.false;
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('_encrypt', function() {
|
||||
it('should work without attachments', function(done) {
|
||||
var ct = 'OMGSOENCRYPTED';
|
||||
|
||||
pgpStub.exportKeys.yields(null, {
|
||||
privateKeyArmored: mockKeyPair.privateKey.encryptedKey,
|
||||
publicKeyArmored: mockKeyPair.publicKey.publicKey
|
||||
});
|
||||
pgpStub.encrypt.yields(null, ct);
|
||||
|
||||
dao._encrypt({
|
||||
email: dummyDecryptedMail
|
||||
}, function(err) {
|
||||
expect(err).to.not.exist;
|
||||
|
||||
expect(pgpStub.exportKeys.calledOnce).to.be.true;
|
||||
expect(pgpStub.encrypt.calledOnce).to.be.true;
|
||||
expect(dummyDecryptedMail.body).to.contain(ct);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user