2013-04-02 09:02:57 -04:00
|
|
|
/**
|
|
|
|
* High level storage api for handling syncing of data to
|
|
|
|
* and from the cloud.
|
|
|
|
*/
|
|
|
|
app.dao.CloudStorage = function(window, $) {
|
2013-04-01 18:12:15 -04:00
|
|
|
'use strict';
|
2013-03-13 11:58:46 -04:00
|
|
|
|
2013-04-19 07:55:21 -04:00
|
|
|
//
|
|
|
|
// Public Key
|
|
|
|
//
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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) {
|
|
|
|
if (!list || list.length === 0) {
|
|
|
|
callback({
|
|
|
|
error: 'No public key for that user!'
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
callback(null, list[0]);
|
|
|
|
},
|
|
|
|
error: function(xhr, textStatus, err) {
|
|
|
|
callback({
|
|
|
|
error: err,
|
|
|
|
status: textStatus
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
//
|
|
|
|
|
2013-03-13 11:58:46 -04:00
|
|
|
/**
|
2013-04-02 09:02:57 -04:00
|
|
|
* 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)
|
2013-03-13 11:58:46 -04:00
|
|
|
*/
|
2013-04-02 09:02:57 -04:00
|
|
|
this.listEncryptedItems = function(type, emailAddress, folderName, callback) {
|
2013-04-19 07:55:21 -04:00
|
|
|
var uri;
|
2013-03-13 11:58:46 -04:00
|
|
|
|
2013-04-02 09:02:57 -04:00
|
|
|
// 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) {
|
2013-04-19 07:55:21 -04:00
|
|
|
callback(null, list);
|
2013-04-02 09:02:57 -04:00
|
|
|
},
|
|
|
|
error: function(xhr, textStatus, err) {
|
|
|
|
callback({
|
|
|
|
error: err,
|
|
|
|
status: textStatus
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
2013-04-01 18:12:15 -04:00
|
|
|
|
2013-04-19 07:55:21 -04:00
|
|
|
//
|
|
|
|
// Secret Key
|
|
|
|
//
|
|
|
|
|
2013-04-02 09:02:57 -04:00
|
|
|
/**
|
|
|
|
* Persist encrypted user key to cloud service
|
|
|
|
*/
|
2013-04-19 07:55:21 -04:00
|
|
|
this.putUserSecretKey = function(emailAddress, callback) {
|
2013-04-02 09:02:57 -04:00
|
|
|
// fetch user's encrypted secret key from keychain/storage
|
2013-04-18 14:34:02 -04:00
|
|
|
var keyStore = new app.dao.LocalStorageDAO(window),
|
|
|
|
storageId = emailAddress + '_encryptedSymmetricKey',
|
2013-04-19 07:55:21 -04:00
|
|
|
storedKey = keyStore.read(storageId),
|
|
|
|
uri;
|
2013-04-02 09:02:57 -04:00
|
|
|
|
2013-04-18 14:34:02 -04:00
|
|
|
if (!storedKey) {
|
|
|
|
callback({
|
|
|
|
error: 'err',
|
|
|
|
status: 'No key found in storage!'
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
2013-03-13 11:58:46 -04:00
|
|
|
|
2013-04-19 07:55:21 -04:00
|
|
|
uri = app.config.cloudUrl + '/secretkey/user/' + emailAddress + '/key/' + storedKey._id;
|
2013-04-02 09:02:57 -04:00
|
|
|
$.ajax({
|
2013-04-19 07:55:21 -04:00
|
|
|
url: uri,
|
2013-04-02 09:02:57 -04:00
|
|
|
type: 'PUT',
|
2013-04-18 14:34:02 -04:00
|
|
|
data: JSON.stringify(storedKey),
|
2013-04-02 09:02:57 -04:00
|
|
|
contentType: 'application/json',
|
|
|
|
success: function() {
|
|
|
|
callback();
|
|
|
|
},
|
|
|
|
error: function(xhr, textStatus, err) {
|
|
|
|
callback({
|
|
|
|
error: err,
|
|
|
|
status: textStatus
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
2013-03-13 11:58:46 -04:00
|
|
|
|
2013-04-02 09:02:57 -04:00
|
|
|
/**
|
|
|
|
* Get encrypted user key from cloud service
|
|
|
|
*/
|
|
|
|
this.getUserSecretKey = function(emailAddress, callback, replaceCallback) {
|
|
|
|
// fetch user's encrypted secret key from keychain/storage
|
2013-04-18 14:34:02 -04:00
|
|
|
var self = this,
|
|
|
|
keyStore = new app.dao.LocalStorageDAO(window),
|
|
|
|
storageId = emailAddress + '_encryptedSymmetricKey',
|
2013-04-19 07:55:21 -04:00
|
|
|
storedKey = keyStore.read(storageId),
|
|
|
|
uri;
|
2013-04-01 18:12:15 -04:00
|
|
|
|
2013-04-19 07:55:21 -04:00
|
|
|
uri = app.config.cloudUrl + '/secretkey/user/' + emailAddress;
|
2013-04-02 09:02:57 -04:00
|
|
|
$.ajax({
|
2013-04-19 07:55:21 -04:00
|
|
|
url: uri,
|
2013-04-02 09:02:57 -04:00
|
|
|
type: 'GET',
|
|
|
|
dataType: 'json',
|
2013-04-18 14:34:02 -04:00
|
|
|
success: function(keys) {
|
|
|
|
if (!keys || keys.length === 0) {
|
|
|
|
callback({
|
|
|
|
error: 'err',
|
|
|
|
status: 'Key not synced!'
|
2013-04-01 18:12:15 -04:00
|
|
|
});
|
2013-04-18 14:34:02 -04:00
|
|
|
return;
|
2013-04-02 09:02:57 -04:00
|
|
|
}
|
2013-04-18 14:34:02 -04:00
|
|
|
|
|
|
|
handleKey(keys[0], callback);
|
2013-04-02 09:02:57 -04:00
|
|
|
},
|
|
|
|
error: function(xhr, textStatus, err) {
|
|
|
|
callback({
|
|
|
|
error: err,
|
|
|
|
status: textStatus
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2013-04-18 14:34:02 -04:00
|
|
|
|
|
|
|
function handleKey(fetchedKey, callback) {
|
|
|
|
if ((!storedKey || !storedKey.encryptedKey) && fetchedKey && fetchedKey.encryptedKey && fetchedKey.keyIV) {
|
|
|
|
// no local key... persist fetched key
|
|
|
|
keyStore.persist(storageId, fetchedKey);
|
|
|
|
replaceCallback();
|
|
|
|
|
|
|
|
} else if (storedKey && fetchedKey && (storedKey.encryptedKey !== fetchedKey.encryptedKey || storedKey.keyIV !== fetchedKey.keyIV)) {
|
|
|
|
// local and fetched keys are not equal
|
2013-04-19 07:55:21 -04:00
|
|
|
if (window.confirm('Swap local key?')) {
|
2013-04-18 14:34:02 -04:00
|
|
|
// replace local key with fetched key
|
|
|
|
keyStore.persist(storageId, fetchedKey);
|
|
|
|
replaceCallback();
|
|
|
|
} else {
|
2013-04-19 07:55:21 -04:00
|
|
|
if (window.confirm('Swap cloud key?')) {
|
2013-04-18 14:34:02 -04:00
|
|
|
// upload local key to cloud
|
2013-04-19 07:55:21 -04:00
|
|
|
self.putUserSecretKey(emailAddress, callback);
|
2013-04-18 14:34:02 -04:00
|
|
|
} else {
|
|
|
|
callback({
|
|
|
|
error: 'err',
|
|
|
|
status: 'Key not synced!'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// local and cloud keys are equal or cloud key is null
|
|
|
|
callback();
|
|
|
|
}
|
|
|
|
}
|
2013-03-13 11:58:46 -04:00
|
|
|
};
|
2013-04-01 18:12:15 -04:00
|
|
|
|
2013-04-02 09:02:57 -04:00
|
|
|
};
|