diff --git a/src/js/crypto/crypto.js b/src/js/crypto/crypto.js
index c33fc61..facabec 100644
--- a/src/js/crypto/crypto.js
+++ b/src/js/crypto/crypto.js
@@ -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
//
diff --git a/src/js/dao/cloudstorage-dao.js b/src/js/dao/cloudstorage-dao.js
index 3bb1d22..19d5f19 100644
--- a/src/js/dao/cloudstorage-dao.js
+++ b/src/js/dao/cloudstorage-dao.js
@@ -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',
diff --git a/src/js/dao/email-dao.js b/src/js/dao/email-dao.js
index a26b0f8..fad3a7e 100644
--- a/src/js/dao/email-dao.js
+++ b/src/js/dao/email-dao.js
@@ -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;
}
diff --git a/src/js/view/messagelist-view.js b/src/js/view/messagelist-view.js
index a5f7d53..f5ded12 100644
--- a/src/js/view/messagelist-view.js
+++ b/src/js/view/messagelist-view.js
@@ -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;
}
diff --git a/test/integration/cloudstorage-dao-test.js b/test/integration/cloudstorage-dao-test.js
index 94c8bff..2168edc 100644
--- a/test/integration/cloudstorage-dao-test.js
+++ b/test/integration/cloudstorage-dao-test.js
@@ -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');
diff --git a/test/integration/index.html b/test/integration/index.html
index 9d90095..94c7f27 100644
--- a/test/integration/index.html
+++ b/test/integration/index.html
@@ -47,12 +47,13 @@
+