mail/src/js/dao/cloudstorage-dao.js

127 lines
3.3 KiB
JavaScript

/**
* High level storage api for handling syncing of data to
* and from the cloud.
*/
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;
// 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(list);
},
error: function(xhr, textStatus, err) {
callback({
error: err,
status: textStatus
});
}
});
};
/**
* Persist encrypted user key to cloud service
*/
this.persistUserSecretKey = function(emailAddress, callback) {
// fetch user's encrypted secret key from keychain/storage
var keyStore = new app.dao.LocalStorageDAO(window);
var storageId = emailAddress + '_encryptedSymmetricKey';
var encryptedKey = keyStore.read(storageId);
var payload = {
userId: emailAddress,
encryptedKey: encryptedKey.key,
keyIV: encryptedKey.iv
};
var uri = app.config.cloudUrl + '/keys/user/' + emailAddress;
$.ajax({
url: uri,
type: 'PUT',
data: JSON.stringify(payload),
contentType: 'application/json',
success: function() {
callback();
},
error: function(xhr, textStatus, err) {
callback({
error: err,
status: textStatus
});
}
});
};
/**
* Get encrypted user key from cloud service
*/
this.getUserSecretKey = function(emailAddress, callback, replaceCallback) {
// fetch user's encrypted secret key from keychain/storage
var self = this;
var keyStore = new app.dao.LocalStorageDAO(window);
var storageId = emailAddress + '_encryptedSymmetricKey';
var storedKey = keyStore.read(storageId);
var uri = app.config.cloudUrl + '/keys/user/' + emailAddress;
$.ajax({
url: uri,
type: 'GET',
dataType: 'json',
success: function(fetchedKey) {
if ((!storedKey || !storedKey.key) && fetchedKey && fetchedKey.encryptedKey && fetchedKey.keyIV) {
// no local key... persist fetched key
keyStore.persist(storageId, {
key: fetchedKey.encryptedKey,
iv: fetchedKey.keyIV
});
replaceCallback();
} else if (storedKey && fetchedKey && (storedKey.key !== fetchedKey.encryptedKey || storedKey.iv !== fetchedKey.keyIV)) {
// local and fetched keys are not equal
if (confirm('Swap local key?')) {
// replace local key with fetched key
keyStore.persist(storageId, {
key: fetchedKey.encryptedKey,
iv: fetchedKey.keyIV
});
replaceCallback();
} else {
if (confirm('Swap cloud key?')) {
// upload local key to cloud
self.persistUserSecretKey(emailAddress, callback);
} else {
callback({
error: 'err',
status: 'Key not synced!'
});
}
}
} else {
// local and cloud keys are equal or cloud key is null
callback();
}
},
error: function(xhr, textStatus, err) {
callback({
error: err,
status: textStatus
});
}
});
};
};