mirror of
https://github.com/moparisthebest/mail
synced 2025-02-16 23:20:09 -05:00
implement encrypted send to new user
This commit is contained in:
parent
04e672552b
commit
4a0e8a072c
@ -141,9 +141,6 @@ define(function(require) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate a new UUID for the new email
|
|
||||||
email.id = util.UUID();
|
|
||||||
|
|
||||||
// only support single recipient for e-2-e encryption
|
// only support single recipient for e-2-e encryption
|
||||||
// check if receiver has a public key
|
// check if receiver has a public key
|
||||||
self._keychain.getReveiverPublicKey(email.to[0].address, function(err, receiverPubkey) {
|
self._keychain.getReveiverPublicKey(email.to[0].address, function(err, receiverPubkey) {
|
||||||
@ -155,9 +152,7 @@ define(function(require) {
|
|||||||
// validate public key
|
// validate public key
|
||||||
if (!receiverPubkey) {
|
if (!receiverPubkey) {
|
||||||
// user hasn't registered a public key yet... invite
|
// user hasn't registered a public key yet... invite
|
||||||
callback({
|
self.encryptForNewUser(email, callback);
|
||||||
errMsg: 'No public key found for: ' + email.from
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,9 +166,54 @@ define(function(require) {
|
|||||||
*/
|
*/
|
||||||
EmailDAO.prototype.encryptForUser = function(email, receiverPubkey, callback) {
|
EmailDAO.prototype.encryptForUser = function(email, receiverPubkey, callback) {
|
||||||
var self = this,
|
var self = this,
|
||||||
ptItems = [email],
|
ptItems = bundleForEncryption(email),
|
||||||
receiverPubkeys = [receiverPubkey],
|
receiverPubkeys = [receiverPubkey];
|
||||||
i;
|
|
||||||
|
// encrypt the email
|
||||||
|
crypto.encryptListForUser(ptItems, receiverPubkeys, function(err, encryptedList) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bundle encrypted email together for sending
|
||||||
|
bundleEncryptedItems(email, encryptedList);
|
||||||
|
|
||||||
|
self.send(email, callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt an email symmetrically for a new user, write the secret one time key to the cloudstorage REST service, and send the email client side via SMTP.
|
||||||
|
*/
|
||||||
|
EmailDAO.prototype.encryptForNewUser = function(email, callback) {
|
||||||
|
var self = this,
|
||||||
|
ptItems = bundleForEncryption(email);
|
||||||
|
|
||||||
|
crypto.symEncryptList(ptItems, function(err, result) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bundle encrypted email together for sending
|
||||||
|
bundleEncryptedItems(email, result.list);
|
||||||
|
|
||||||
|
// TODO: write result.key to REST endpoint
|
||||||
|
|
||||||
|
self.send(email, callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Give the email a newly generated UUID, remove its attachments, and bundle all plaintext items to a batchable array for encryption.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function bundleForEncryption(email) {
|
||||||
|
var ptItems = [email];
|
||||||
|
|
||||||
|
// generate a new UUID for the new email
|
||||||
|
email.id = util.UUID();
|
||||||
|
|
||||||
// add attachment to encryption batch and remove from email object
|
// add attachment to encryption batch and remove from email object
|
||||||
if (email.attachments) {
|
if (email.attachments) {
|
||||||
@ -184,15 +224,18 @@ define(function(require) {
|
|||||||
delete email.attachments;
|
delete email.attachments;
|
||||||
}
|
}
|
||||||
|
|
||||||
// encrypt the email
|
return ptItems;
|
||||||
crypto.encryptListForUser(ptItems, receiverPubkeys, function(err, encryptedList) {
|
|
||||||
if (err) {
|
|
||||||
callback(err);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frame the encrypted email message and append the encrypted attachments.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function bundleEncryptedItems(email, encryptedList) {
|
||||||
|
var i;
|
||||||
|
|
||||||
// replace body and subject of the email with encrypted versions
|
// replace body and subject of the email with encrypted versions
|
||||||
email = self.frameEncryptedMessage(email, encryptedList[0]);
|
email = frameEncryptedMessage(email, encryptedList[0]);
|
||||||
|
|
||||||
// add encrypted attachments
|
// add encrypted attachments
|
||||||
if (encryptedList.length > 1) {
|
if (encryptedList.length > 1) {
|
||||||
@ -205,15 +248,13 @@ define(function(require) {
|
|||||||
uint8Array: util.binStr2Uint8Arr(JSON.stringify(encryptedList[i]))
|
uint8Array: util.binStr2Uint8Arr(JSON.stringify(encryptedList[i]))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
self.send(email, callback);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frames an encrypted message in base64 Format
|
* Frames an encrypted message in base64 Format.
|
||||||
*/
|
*/
|
||||||
EmailDAO.prototype.frameEncryptedMessage = function(email, ct) {
|
|
||||||
|
function frameEncryptedMessage(email, ct) {
|
||||||
var to, greeting, ctBase64;
|
var to, greeting, ctBase64;
|
||||||
|
|
||||||
// get first name of recipient
|
// get first name of recipient
|
||||||
@ -226,7 +267,7 @@ define(function(require) {
|
|||||||
email.subject = SUBJECT;
|
email.subject = SUBJECT;
|
||||||
|
|
||||||
return email;
|
return email;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send an actual message object via smtp
|
* Send an actual message object via smtp
|
||||||
|
@ -135,6 +135,21 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should work for a new user', function(done) {
|
||||||
|
keychainStub.getReveiverPublicKey.yields(null, null);
|
||||||
|
smtpClientStub.send.yields();
|
||||||
|
|
||||||
|
emailDao.smtpSend(dummyMail, function(err) {
|
||||||
|
expect(keychainStub.getReveiverPublicKey.calledOnce).to.be.true;
|
||||||
|
expect(smtpClientStub.send.calledOnce).to.be.true;
|
||||||
|
smtpClientStub.send.calledWith(sinon.match(function(o) {
|
||||||
|
return typeof o.attachments === 'undefined';
|
||||||
|
}));
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should work without attachments', function(done) {
|
it('should work without attachments', function(done) {
|
||||||
keychainStub.getReveiverPublicKey.yields(null, {
|
keychainStub.getReveiverPublicKey.yields(null, {
|
||||||
_id: "fcf8b4aa-5d09-4089-8b4f-e3bc5091daf3",
|
_id: "fcf8b4aa-5d09-4089-8b4f-e3bc5091daf3",
|
||||||
|
Loading…
Reference in New Issue
Block a user