mirror of
https://github.com/moparisthebest/mail
synced 2025-01-30 22:50:17 -05:00
implemented public key cloud storage methods
This commit is contained in:
parent
f4ed6010e6
commit
e943dfd304
@ -75,6 +75,17 @@ app.crypto.Crypto = function(window, util) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Derive an asymmetric keypait from the user's secret
|
||||
*/
|
||||
this.deriveKeyPair = function(naclCrypto, id) {
|
||||
var keys = naclCrypto.generateKeypair(symmetricUserKey);
|
||||
if (id) {
|
||||
keys.id = id;
|
||||
}
|
||||
return keys;
|
||||
};
|
||||
|
||||
//
|
||||
// En/Decrypts single item
|
||||
//
|
||||
|
@ -5,23 +5,30 @@
|
||||
app.dao.CloudStorage = function(window, $) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Lists the encrypted items
|
||||
* @param type [String] The type of item e.g. 'email'
|
||||
* @param offset [Number] The offset of items to fetch (0 is the last stored item)
|
||||
* @param num [Number] The number of items to fetch (null means fetch all)
|
||||
*/
|
||||
this.listEncryptedItems = function(type, emailAddress, folderName, callback) {
|
||||
var folder, uri, self = this;
|
||||
//
|
||||
// Public Key
|
||||
//
|
||||
|
||||
// fetch encrypted json objects from cloud service
|
||||
uri = app.config.cloudUrl + '/' + type + '/user/' + emailAddress + '/folder/' + folderName;
|
||||
/**
|
||||
* Find the user's corresponding public key
|
||||
*/
|
||||
this.getPublicKey = function(emailAddress, callback) {
|
||||
var uri;
|
||||
|
||||
uri = app.config.cloudUrl + '/publickey/user/' + emailAddress;
|
||||
$.ajax({
|
||||
url: uri,
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
success: function(list) {
|
||||
callback(list);
|
||||
if (!list || list.length === 0) {
|
||||
callback({
|
||||
error: 'No public key for that user!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, list[0]);
|
||||
},
|
||||
error: function(xhr, textStatus, err) {
|
||||
callback({
|
||||
@ -32,14 +39,74 @@ app.dao.CloudStorage = function(window, $) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Persist the user's publc key
|
||||
*/
|
||||
this.putPublicKey = function(pubkey, callback) {
|
||||
var uri;
|
||||
|
||||
uri = app.config.cloudUrl + '/publickey/user/' + pubkey.userId + '/key/' + pubkey._id;
|
||||
$.ajax({
|
||||
url: uri,
|
||||
type: 'PUT',
|
||||
data: JSON.stringify(pubkey),
|
||||
contentType: 'application/json',
|
||||
success: function() {
|
||||
callback();
|
||||
},
|
||||
error: function(xhr, textStatus, err) {
|
||||
callback({
|
||||
error: err,
|
||||
status: textStatus
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
// Encrypted Mails
|
||||
//
|
||||
|
||||
/**
|
||||
* Lists the encrypted items
|
||||
* @param type [String] The type of item e.g. 'email'
|
||||
* @param offset [Number] The offset of items to fetch (0 is the last stored item)
|
||||
* @param num [Number] The number of items to fetch (null means fetch all)
|
||||
*/
|
||||
this.listEncryptedItems = function(type, emailAddress, folderName, callback) {
|
||||
var uri;
|
||||
|
||||
// fetch encrypted json objects from cloud service
|
||||
uri = app.config.cloudUrl + '/' + type + '/user/' + emailAddress + '/folder/' + folderName;
|
||||
$.ajax({
|
||||
url: uri,
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
success: function(list) {
|
||||
callback(null, list);
|
||||
},
|
||||
error: function(xhr, textStatus, err) {
|
||||
callback({
|
||||
error: err,
|
||||
status: textStatus
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
// Secret Key
|
||||
//
|
||||
|
||||
/**
|
||||
* Persist encrypted user key to cloud service
|
||||
*/
|
||||
this.persistUserSecretKey = function(emailAddress, callback) {
|
||||
this.putUserSecretKey = function(emailAddress, callback) {
|
||||
// fetch user's encrypted secret key from keychain/storage
|
||||
var keyStore = new app.dao.LocalStorageDAO(window),
|
||||
storageId = emailAddress + '_encryptedSymmetricKey',
|
||||
storedKey = keyStore.read(storageId);
|
||||
storedKey = keyStore.read(storageId),
|
||||
uri;
|
||||
|
||||
if (!storedKey) {
|
||||
callback({
|
||||
@ -49,8 +116,9 @@ app.dao.CloudStorage = function(window, $) {
|
||||
return;
|
||||
}
|
||||
|
||||
uri = app.config.cloudUrl + '/secretkey/user/' + emailAddress + '/key/' + storedKey._id;
|
||||
$.ajax({
|
||||
url: app.config.cloudUrl + '/secretkey/user/' + emailAddress + '/key/' + storedKey._id,
|
||||
url: uri,
|
||||
type: 'PUT',
|
||||
data: JSON.stringify(storedKey),
|
||||
contentType: 'application/json',
|
||||
@ -74,10 +142,12 @@ app.dao.CloudStorage = function(window, $) {
|
||||
var self = this,
|
||||
keyStore = new app.dao.LocalStorageDAO(window),
|
||||
storageId = emailAddress + '_encryptedSymmetricKey',
|
||||
storedKey = keyStore.read(storageId);
|
||||
storedKey = keyStore.read(storageId),
|
||||
uri;
|
||||
|
||||
uri = app.config.cloudUrl + '/secretkey/user/' + emailAddress;
|
||||
$.ajax({
|
||||
url: app.config.cloudUrl + '/secretkey/user/' + emailAddress,
|
||||
url: uri,
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
success: function(keys) {
|
||||
@ -107,14 +177,14 @@ app.dao.CloudStorage = function(window, $) {
|
||||
|
||||
} else if (storedKey && fetchedKey && (storedKey.encryptedKey !== fetchedKey.encryptedKey || storedKey.keyIV !== fetchedKey.keyIV)) {
|
||||
// local and fetched keys are not equal
|
||||
if (confirm('Swap local key?')) {
|
||||
if (window.confirm('Swap local key?')) {
|
||||
// replace local key with fetched key
|
||||
keyStore.persist(storageId, fetchedKey);
|
||||
replaceCallback();
|
||||
} else {
|
||||
if (confirm('Swap cloud key?')) {
|
||||
if (window.confirm('Swap cloud key?')) {
|
||||
// upload local key to cloud
|
||||
self.persistUserSecretKey(emailAddress, callback);
|
||||
self.putUserSecretKey(emailAddress, callback);
|
||||
} else {
|
||||
callback({
|
||||
error: 'err',
|
||||
|
@ -91,10 +91,12 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage) {
|
||||
this.syncFromCloud = function(folderName, callback) {
|
||||
var folder, self = this;
|
||||
|
||||
cloudstorage.listEncryptedItems('email', this.account.get('emailAddress'), folderName, function(res) {
|
||||
cloudstorage.listEncryptedItems('email', this.account.get('emailAddress'), folderName, function(err, res) {
|
||||
// return if an error occured or if fetched list from cloud storage is empty
|
||||
if (!res || res.status || res.length === 0) {
|
||||
callback(res); // error
|
||||
if (err || !res || res.status || res.length === 0) {
|
||||
callback({
|
||||
error: err
|
||||
}); // error
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -33,12 +33,12 @@
|
||||
textVisible: true
|
||||
});
|
||||
// sync from cloud
|
||||
this.dao.syncFromCloud(this.folder, function(res) {
|
||||
this.dao.syncFromCloud(this.folder, function(err) {
|
||||
$.mobile.loading('hide');
|
||||
|
||||
// check for error
|
||||
if (res && res.status) {
|
||||
alert('Syncing failed!');
|
||||
if (err) {
|
||||
window.alert('Syncing failed!');
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,13 @@ var cloudstoragedao_test = {
|
||||
user: 'test@atlasdev.onmicrosoft.com',
|
||||
password: 'Xoza76645',
|
||||
keySize: 128,
|
||||
ivSize: 104
|
||||
ivSize: 104,
|
||||
privateKey: "Bv51afjeuH8CatKo75HOHQRT1B3amvF+DEwijka79nA=",
|
||||
publicKey: new app.model.PublicKey({
|
||||
_id: "da4bfa93-ba87-490e-877c-e4020a6f6729",
|
||||
userId: 'test@atlasdev.onmicrosoft.com',
|
||||
publicKey: "yHUhh3Pcbjmh2k367pSXfE8hDwPsAxQs0QETm9mfmz0="
|
||||
})
|
||||
};
|
||||
|
||||
asyncTest("Init", 1, function() {
|
||||
@ -24,6 +30,22 @@ asyncTest("Init", 1, function() {
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest("Persist public key to cloud", 1, function() {
|
||||
cloudstoragedao_test.cloudstorage.putPublicKey(cloudstoragedao_test.publicKey.toJSON(), function(err) {
|
||||
ok(!err, 'Persist key to cloud');
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest("Get Public key from cloud", 2, function() {
|
||||
cloudstoragedao_test.cloudstorage.getPublicKey(cloudstoragedao_test.user, function(err, data) {
|
||||
ok(!err && data && data.publicKey, 'Get public key from cloud');
|
||||
deepEqual(data, cloudstoragedao_test.publicKey.toJSON(), 'Public key is equal');
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest("Get user secret key from cloud", 1, function() {
|
||||
cloudstoragedao_test.cloudstorage.getUserSecretKey(cloudstoragedao_test.user, function(err) {
|
||||
@ -40,7 +62,7 @@ asyncTest("Get user secret key from cloud", 1, function() {
|
||||
});
|
||||
|
||||
asyncTest("Persist user secret key to cloud", 1, function() {
|
||||
cloudstoragedao_test.cloudstorage.persistUserSecretKey(cloudstoragedao_test.user, function(err) {
|
||||
cloudstoragedao_test.cloudstorage.putUserSecretKey(cloudstoragedao_test.user, function(err) {
|
||||
ok(!err, 'Persist key to cloud');
|
||||
|
||||
start();
|
||||
@ -58,8 +80,8 @@ asyncTest("Sync emails from cloud", 3, function() {
|
||||
cloudstoragedao_test.emailDao.init(account, cloudstoragedao_test.password, function() {
|
||||
ok(true, 'Init complete');
|
||||
|
||||
cloudstoragedao_test.emailDao.syncFromCloud('inbox', function(res) {
|
||||
ok(!res, 'Synced items');
|
||||
cloudstoragedao_test.emailDao.syncFromCloud('inbox', function(err) {
|
||||
ok(!err, 'Synced items');
|
||||
|
||||
cloudstoragedao_test.emailDao.listItems('inbox', 0, null, function(collection) {
|
||||
ok(collection.length > 0, 'Read synced items');
|
||||
|
@ -47,12 +47,13 @@
|
||||
<script src="../js/app-config.js"></script>
|
||||
<script>
|
||||
app.config.workerPath = '../js';
|
||||
//app.config.cloudUrl = 'http://localhost:8888';
|
||||
app.config.cloudUrl = 'http://localhost:8888';
|
||||
</script>
|
||||
|
||||
<script src="../js/model/email-model.js"></script>
|
||||
<script src="../js/model/folder-model.js"></script>
|
||||
<script src="../js/model/account-model.js"></script>
|
||||
<script src="../js/model/publickey-model.js"></script>
|
||||
|
||||
<script src="../js/crypto/util.js"></script>
|
||||
<script src="../js/crypto/pbkdf2.js"></script>
|
||||
|
Loading…
Reference in New Issue
Block a user