mirror of
https://github.com/moparisthebest/mail
synced 2024-11-22 08:52:15 -05:00
sending end-2-end encrypted emails internally work
This commit is contained in:
parent
a4f03bdca1
commit
699871276c
@ -84,6 +84,14 @@ define(['jquery', 'js/app-config'], function($, app) {
|
||||
self.put(item, uri, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Deliver an email to the user's outbox
|
||||
*/
|
||||
self.deliverEmail = function(email, from, to, callback) {
|
||||
var uri = app.config.cloudUrl + '/email/user/' + from + '/folder/outbox/' + email.id + '?to=' + to;
|
||||
self.put(email, uri, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete an encrypted item from the cloud
|
||||
* @param type [String] The type of item e.g. 'email'
|
||||
|
@ -143,7 +143,7 @@ define(['underscore', 'cryptoLib/util', 'js/crypto/crypto', 'js/dao/lawnchair-da
|
||||
var filter = '';
|
||||
if (localItems && localItems.length > 0) {
|
||||
// sync delta of last item sent date
|
||||
filter = '?date=' + localItems[localItems.length - 1].sentDate;
|
||||
//filter = '?date=' + localItems[localItems.length - 1].sentDate;
|
||||
startSync(filter);
|
||||
} else {
|
||||
// do a full sync of all items on the cloud
|
||||
@ -225,9 +225,9 @@ define(['underscore', 'cryptoLib/util', 'js/crypto/crypto', 'js/dao/lawnchair-da
|
||||
|
||||
// validate email addresses
|
||||
var invalidRecipient;
|
||||
_.each(email.to, function(address) {
|
||||
if (!validateEmail(address)) {
|
||||
invalidRecipient = address;
|
||||
_.each(email.to, function(i) {
|
||||
if (!validateEmail(i.address)) {
|
||||
invalidRecipient = i.address;
|
||||
}
|
||||
});
|
||||
if (invalidRecipient) {
|
||||
@ -236,7 +236,7 @@ define(['underscore', 'cryptoLib/util', 'js/crypto/crypto', 'js/dao/lawnchair-da
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!validateEmail(email.from)) {
|
||||
if (!validateEmail(email.from[0].address)) {
|
||||
callback({
|
||||
errMsg: 'Invalid sender: ' + email.from
|
||||
});
|
||||
@ -245,11 +245,59 @@ define(['underscore', 'cryptoLib/util', 'js/crypto/crypto', 'js/dao/lawnchair-da
|
||||
|
||||
// generate a new UUID for the new email
|
||||
email.id = util.UUID();
|
||||
// set sent date
|
||||
email.sentDate = util.formatDate(new Date());
|
||||
|
||||
// send email to cloud service
|
||||
cloudstorage.putEncryptedItem(email, 'email', userId, 'outbox', function(err) {
|
||||
callback(err);
|
||||
// only support single recipient for e-2-e encryption
|
||||
var recipient = email.to[0].address;
|
||||
|
||||
// check if receiver has a public key
|
||||
keychain.getReveiverPublicKey(recipient, function(err, receiverPubkey) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (receiverPubkey) {
|
||||
// public key found... encrypt and send
|
||||
encrypt(email, receiverPubkey);
|
||||
} else {
|
||||
// no public key found... send plaintext mail via SMTP
|
||||
send(email);
|
||||
}
|
||||
});
|
||||
|
||||
function encrypt(email, receiverPubkey) {
|
||||
// encrypt the email
|
||||
crypto.encryptListForUser([email], [receiverPubkey], function(err, encryptedList) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
var ct = encryptedList[0];
|
||||
|
||||
var envelope = {
|
||||
id: email.id,
|
||||
crypto: 'rsa-1024-sha-256-aes-128-cbc',
|
||||
sentDate: email.sentDate,
|
||||
ciphertext: ct.ciphertext,
|
||||
encryptedKey: ct.encryptedKey,
|
||||
iv: ct.iv,
|
||||
signature: ct.signature,
|
||||
senderPk: ct.senderPk
|
||||
};
|
||||
|
||||
send(envelope);
|
||||
});
|
||||
}
|
||||
|
||||
function send(email) {
|
||||
// send email to cloud service
|
||||
cloudstorage.deliverEmail(email, userId, recipient, function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -46,6 +46,51 @@ define(['underscore', 'js/dao/lawnchair-dao'], function(_, jsonDao) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Look up a reveiver's public key by user id
|
||||
* @param userId [String] the receiver's email address
|
||||
*/
|
||||
self.getReveiverPublicKey = function(userId, callback) {
|
||||
// search local keyring for public key
|
||||
jsonDao.list('publickey', 0, null, function(allPubkeys) {
|
||||
var pubkey = _.findWhere(allPubkeys, {
|
||||
userId: userId
|
||||
});
|
||||
|
||||
if (!pubkey || !pubkey._id) {
|
||||
// no public key by that user id in storage
|
||||
// find from cloud by email address
|
||||
cloudstorage.getPublicKeyByUserId(userId, function(err, cloudPubkey) {
|
||||
if (err || !cloudPubkey) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
if (cloudPubkey && cloudPubkey._id) {
|
||||
// there is a public key for that user already in the cloud...
|
||||
// save to local storage
|
||||
saveLocalPublicKey(cloudPubkey, function(err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, cloudPubkey);
|
||||
});
|
||||
} else {
|
||||
// no public key for that user
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
// that user's public key is already in local storage
|
||||
callback(null, pubkey);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the local user's key either from local storage
|
||||
* or fetches it from the cloud. The private key is encrypted.
|
||||
|
@ -105,11 +105,21 @@ define(['jquery', 'underscore', 'backbone', 'js/app-config'], function($, _, Bac
|
||||
var signature = '\n\nSent with whiteout mail - get your free mailbox for end-2-end encrypted messaging!\nhttps://mail.whiteout.io';
|
||||
|
||||
var email = {
|
||||
from: self.account,
|
||||
to: to,
|
||||
to: [],
|
||||
subject: page.find('#subjectInput').val(),
|
||||
body: page.find('#bodyTextarea').val() + signature
|
||||
};
|
||||
email.from = [{
|
||||
name: '',
|
||||
address: self.account
|
||||
}
|
||||
];
|
||||
to.forEach(function(address) {
|
||||
email.to.push({
|
||||
name: '',
|
||||
address: address
|
||||
});
|
||||
});
|
||||
|
||||
// post message to main window
|
||||
app.util.postMessage('sendEmail', {
|
||||
|
@ -161,13 +161,40 @@ define(['js/dao/email-dao', 'js/dao/keychain-dao', 'js/dao/lawnchair-dao',
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest("Send Plaintext Email item", 1, function() {
|
||||
asyncTest("Send e-2-e Encrypted Email item", 1, function() {
|
||||
var email = {
|
||||
from: cloudstoragedaoTest.user, // sender address
|
||||
to: [cloudstoragedaoTest.user], // list of receivers
|
||||
subject: 'Client Email DAO Test', // Subject line
|
||||
body: 'Hello world' // plaintext body
|
||||
};
|
||||
email.from = [{
|
||||
address: cloudstoragedaoTest.user
|
||||
}
|
||||
];
|
||||
email.to = [{
|
||||
address: cloudstoragedaoTest.user
|
||||
}
|
||||
];
|
||||
|
||||
cloudstoragedaoTest.emailDao.sendEmail(email, function(err) {
|
||||
ok(!err, 'Email sent');
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest("Send Plaintext Email item", 1, function() {
|
||||
var email = {
|
||||
subject: 'Client Email DAO Test', // Subject line
|
||||
body: 'Hello world' // plaintext body
|
||||
};
|
||||
email.from = [{
|
||||
address: cloudstoragedaoTest.user
|
||||
}
|
||||
];
|
||||
email.to = [{
|
||||
address: 'safewithme.testuser@gmail.com'
|
||||
}
|
||||
];
|
||||
|
||||
cloudstoragedaoTest.emailDao.sendEmail(email, function(err) {
|
||||
ok(!err, 'Email sent');
|
||||
|
@ -81,4 +81,13 @@ define(['js/dao/keychain-dao', 'js/dao/lawnchair-dao'], function(KeychainDAO, js
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest("Get User Keypair", 2, function() {
|
||||
keychaindaoTest.keychainDao.getReveiverPublicKey(keychaindaoTest.user, function(err, pubkey) {
|
||||
ok(!err);
|
||||
ok(pubkey && pubkey.publicKey);
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
Loading…
Reference in New Issue
Block a user