mirror of
https://github.com/moparisthebest/mail
synced 2024-11-25 02:12:17 -05:00
pull from vinbox, reencrypt, push to inbox works
This commit is contained in:
parent
65e0a7d520
commit
9dec074b0c
@ -12,23 +12,23 @@ app.dao.CloudStorage = function(window, $) {
|
||||
/**
|
||||
* Find the user's corresponding public key
|
||||
*/
|
||||
this.getPublicKey = function(emailAddress, callback) {
|
||||
this.getPublicKey = function(keyId, callback) {
|
||||
var uri;
|
||||
|
||||
uri = app.config.cloudUrl + '/publickey/user/' + emailAddress;
|
||||
uri = app.config.cloudUrl + '/publickey/key/' + keyId;
|
||||
$.ajax({
|
||||
url: uri,
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
success: function(list) {
|
||||
if (!list || list.length === 0) {
|
||||
success: function(key) {
|
||||
if (!key || !key._id) {
|
||||
callback({
|
||||
error: 'No public key for that user!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, list[0]);
|
||||
callback(null, key);
|
||||
},
|
||||
error: function(xhr, textStatus, err) {
|
||||
callback({
|
||||
@ -67,6 +67,31 @@ app.dao.CloudStorage = function(window, $) {
|
||||
// Encrypted Mails
|
||||
//
|
||||
|
||||
/**
|
||||
* Pushes an encrypted item to the user's cloud storage
|
||||
* @param type [String] The type of item e.g. 'email'
|
||||
*/
|
||||
this.putEncryptedItem = function(item, type, emailAddress, folderName, callback) {
|
||||
var uri;
|
||||
|
||||
uri = app.config.cloudUrl + '/' + type + '/user/' + emailAddress + '/folder/' + folderName + '/' + item.id;
|
||||
$.ajax({
|
||||
url: uri,
|
||||
type: 'PUT',
|
||||
data: JSON.stringify(item),
|
||||
contentType: 'application/json',
|
||||
success: function() {
|
||||
callback();
|
||||
},
|
||||
error: function(xhr, textStatus, err) {
|
||||
callback({
|
||||
error: err,
|
||||
status: textStatus
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Lists the encrypted items
|
||||
* @param type [String] The type of item e.g. 'email'
|
||||
|
@ -2,7 +2,7 @@
|
||||
* A high-level Data-Access Api for handling Email synchronization
|
||||
* between the cloud service and the device's local storage
|
||||
*/
|
||||
app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage, naclCrypto) {
|
||||
app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage, naclCrypto, util) {
|
||||
'use strict';
|
||||
|
||||
var keypair; // the user's keypair
|
||||
@ -101,6 +101,92 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage, naclCrypto)
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks the user virtual inbox containing end-2-end encrypted mail items
|
||||
*/
|
||||
this.checkVInbox = function(callback) {
|
||||
var self = this;
|
||||
|
||||
cloudstorage.listEncryptedItems('email', this.account.get('emailAddress'), 'vinbox', function(err, data) {
|
||||
// if virtual inbox is emtpy just callback
|
||||
if (err || !data || data.status || data.length === 0) {
|
||||
callback(); // error
|
||||
return;
|
||||
}
|
||||
|
||||
// asynchronously iterate over the encrypted items
|
||||
var after = _.after(data.length, function() {
|
||||
callback();
|
||||
});
|
||||
|
||||
_.each(data, function(asymCt) {
|
||||
// asymmetric decrypt
|
||||
asymDecryptMail(asymCt, function(err, pt) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// symmetric encrypt and push to cloud
|
||||
symEncryptAndUpload(pt, function(err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: delete items from virtual inbox
|
||||
|
||||
after(); // asynchronously iterate through objects
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function asymDecryptMail(m, callback) {
|
||||
var pubKeyId = m.senderPk.split(';')[1];
|
||||
// pull the sender's public key
|
||||
cloudstorage.getPublicKey(pubKeyId, function(err, senderPk) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// do authenticated decryption
|
||||
naclCrypto.asymDecrypt(m.ciphertext, m.itemIV, senderPk.publicKey, keypair.boxSk, function(plaintext) {
|
||||
callback(null, JSON.parse(plaintext));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function symEncryptAndUpload(email, callback) {
|
||||
var itemKey = util.random(self.account.get('symKeySize')),
|
||||
itemIV = util.random(self.account.get('symIvSize')),
|
||||
keyIV = util.random(self.account.get('symIvSize')),
|
||||
json = JSON.stringify(email),
|
||||
envelope, encryptedKey;
|
||||
|
||||
// symmetrically encrypt item
|
||||
crypto.aesEncrypt(json, itemKey, itemIV, function(ct) {
|
||||
|
||||
// encrypt item key for user
|
||||
encryptedKey = crypto.aesEncryptForUserSync(itemKey, keyIV);
|
||||
envelope = {
|
||||
id: email.id,
|
||||
crypto: 'aes-128-ccm',
|
||||
ciphertext: ct,
|
||||
encryptedKey: encryptedKey,
|
||||
keyIV: keyIV,
|
||||
itemIV: itemIV
|
||||
};
|
||||
|
||||
// push encrypted item to cloud
|
||||
cloudstorage.putEncryptedItem(envelope, 'email', self.account.get('emailAddress'), 'inbox', function(err) {
|
||||
callback(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Synchronize a folder's items from the cloud to the device-storage
|
||||
* @param folderName [String] The name of the folder e.g. 'inbox'
|
||||
@ -108,9 +194,9 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage, naclCrypto)
|
||||
this.syncFromCloud = function(folderName, callback) {
|
||||
var folder, self = this;
|
||||
|
||||
cloudstorage.listEncryptedItems('email', this.account.get('emailAddress'), folderName, function(err, res) {
|
||||
cloudstorage.listEncryptedItems('email', this.account.get('emailAddress'), folderName, function(err, data) {
|
||||
// return if an error occured or if fetched list from cloud storage is empty
|
||||
if (err || !res || res.status || res.length === 0) {
|
||||
if (err || !data || data.status || data.length === 0) {
|
||||
callback({
|
||||
error: err
|
||||
}); // error
|
||||
@ -120,7 +206,7 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage, naclCrypto)
|
||||
// TODO: remove old folder items from devicestorage
|
||||
|
||||
// persist encrypted list in device storage
|
||||
devicestorage.storeEcryptedList(res, 'email_' + folderName, function() {
|
||||
devicestorage.storeEcryptedList(data, 'email_' + folderName, function() {
|
||||
// remove cached folder in account model
|
||||
folder = self.account.get('folders').where({
|
||||
name: folderName
|
||||
|
@ -15,7 +15,7 @@ asyncTest("Init", 1, function() {
|
||||
var naclCrypto = new app.crypto.NaclCrypto(nacl, util);
|
||||
cloudstoragedao_test.storage = new app.dao.DeviceStorage(util, crypto, jsonDao, null);
|
||||
cloudstoragedao_test.cloudstorage = new app.dao.CloudStorage(window, $);
|
||||
cloudstoragedao_test.emailDao = new app.dao.EmailDAO(_, crypto, cloudstoragedao_test.storage, cloudstoragedao_test.cloudstorage, naclCrypto);
|
||||
cloudstoragedao_test.emailDao = new app.dao.EmailDAO(_, crypto, cloudstoragedao_test.storage, cloudstoragedao_test.cloudstorage, naclCrypto, util);
|
||||
|
||||
// clear db before tests
|
||||
jsonDao.clear(function(err) {
|
||||
@ -43,7 +43,7 @@ asyncTest("Persist public key to cloud", 1, function() {
|
||||
});
|
||||
|
||||
asyncTest("Get Public key from cloud", 2, function() {
|
||||
cloudstoragedao_test.cloudstorage.getPublicKey(cloudstoragedao_test.publicKey.get('userId'), function(err, data) {
|
||||
cloudstoragedao_test.cloudstorage.getPublicKey(cloudstoragedao_test.publicKey.get('_id'), function(err, data) {
|
||||
ok(!err && data && data.publicKey, 'Get public key from cloud');
|
||||
deepEqual(data, cloudstoragedao_test.publicKey.toJSON(), 'Public key is equal');
|
||||
|
||||
@ -91,8 +91,15 @@ asyncTest("Init", 1, function() {
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest("Sync emails from cloud", 3, function() {
|
||||
asyncTest("Check virtual inbox, re-encrypt and push to cloud", 1, function() {
|
||||
cloudstoragedao_test.emailDao.checkVInbox(function(err) {
|
||||
ok(!err, 'Synced items');
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest("Sync emails from cloud", 2, function() {
|
||||
cloudstoragedao_test.emailDao.syncFromCloud('inbox', function(err) {
|
||||
ok(!err, 'Synced items');
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user