key ync from cloud works

This commit is contained in:
Tankred Hase 2013-06-03 19:57:15 +02:00
parent 04a3ab2a34
commit 1071d89ee9
6 changed files with 116 additions and 35 deletions

View File

@ -17,12 +17,12 @@
login: function() {
// init email dao and dependencies
var util = new cryptoLib.Util(window, uuid);
var jsonDao = new app.dao.LawnchairDAO(Lawnchair);
var crypto = new app.crypto.Crypto(window, util);
var cloudstorage = new app.dao.CloudStorage(window, $);
var jsonDao = new app.dao.LawnchairDAO(Lawnchair);
var devicestorage = new app.dao.DeviceStorage(util, crypto, jsonDao, null);
var keychain = new app.dao.KeychainDAO(jsonDao, cloudstorage);
this.emailDao = new app.dao.EmailDAO(_, crypto, devicestorage, cloudstorage, util, keychain);
this.emailDao = new app.dao.EmailDAO(jsonDao, crypto, devicestorage, cloudstorage, util, keychain);
var loginView = new app.view.LoginView({
dao: this.emailDao

View File

@ -126,6 +126,36 @@ app.dao.CloudStorage = function(window, $) {
});
};
/**
* Find the user's corresponding public key by email
*/
this.getPublicKeyByUserId = function(userId, callback) {
var uri = app.config.cloudUrl + '/publickey/user/' + userId;
this.get(uri, function(err, keys) {
if (err) {
callback(err);
return;
}
if (!keys || keys.length < 1) {
callback({
errMsg: 'No public key for that user!'
});
return;
}
if (keys.length > 1) {
callback({
errMsg: 'That user has multiple public keys!'
});
return;
}
callback(null, keys[0]);
});
};
/**
* Persist the user's publc key
*/

View File

@ -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, util, keychain) {
app.dao.EmailDAO = function(jsonDB, crypto, devicestorage, cloudstorage, util, keychain) {
'use strict';
/**
@ -11,8 +11,20 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage, util, keycha
this.init = function(account, password, callback) {
this.account = account;
// validate email address
var emailAddress = account.get('emailAddress');
if (!validateEmail(emailAddress)) {
callback({
errMsg: 'The user email address must be specified!'
});
return;
}
// init user's local database
jsonDB.init(emailAddress);
// call getUserKeyPair to read/sync keypair with devicestorage/cloud
keychain.getUserKeyPair(account.get('emailAddress'), function(err, storedKeypair) {
keychain.getUserKeyPair(emailAddress, function(err, storedKeypair) {
if (err) {
callback(err);
return;
@ -23,7 +35,7 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage, util, keycha
function initCrypto(storedKeypair) {
crypto.init({
emailAddress: account.get('emailAddress'),
emailAddress: emailAddress,
password: password,
keySize: account.get('symKeySize'),
rsaKeySize: account.get('asymKeySize'),
@ -201,11 +213,11 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage, util, keycha
cloudstorage.putEncryptedItem(email, 'email', userId, 'outbox', function(err) {
callback(err);
});
function validateEmail(email) {
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
};
function validateEmail(email) {
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
};

View File

@ -50,40 +50,67 @@ app.dao.KeychainDAO = function(jsonDao, cloudstorage) {
* return [Object] The user's key pair {publicKey, privateKey}
*/
this.getUserKeyPair = function(userId, callback) {
// search for user's public key
// search for user's public key locally
jsonDao.list('publickey', 0, null, function(allPubkeys) {
var pubkey = _.findWhere(allPubkeys, {
userId: userId
});
if (!pubkey) {
if (!pubkey || !pubkey._id) {
// no public key by that user id in storage
// TODO: find from cloud
// TODO: persist in local storage
callback();
return;
}
// find from cloud by email address
cloudstorage.getPublicKeyByUserId(userId, function(err, cloudPubkey) {
if (err) {
callback(err);
return;
}
// public key found
// get corresponding private key
fetchEncryptedPrivateKey(pubkey);
if (cloudPubkey && cloudPubkey._id) {
// there is a public key for that user already in the cloud...
// sync keypair to local storage
syncKeypair(cloudPubkey._id);
} else {
// continue without keypair... generate in crypto.js
callback();
return;
}
});
} else {
// that user's public key is already in local storage...
// sync keypair to the cloud
syncKeypair(pubkey._id);
}
});
function fetchEncryptedPrivateKey(publicKey) {
// try to read private key from local storage
lookupPrivateKey(publicKey._id, function(err, privkey) {
if (err || !privkey) {
callback({
errMsg: 'Error looking up private key!',
err: err
});
function syncKeypair(keypairId) {
// persist key pair in local storage
lookupPublicKey(keypairId, function(err, savedPubkey) {
if (err) {
callback(err);
return;
}
// private key found
callback(null, {
publicKey: publicKey,
privateKey: privkey
// persist private key in local storage
lookupPrivateKey(keypairId, function(err, savedPrivkey) {
if (err) {
callback(err);
return;
}
// validate fetched key
if (savedPubkey && savedPubkey.publicKey && savedPrivkey && savedPrivkey.encryptedKey) {
callback(null, {
publicKey: savedPubkey,
privateKey: savedPrivkey
});
return;
} else {
// continue without keypair... generate in crypto.js
callback();
return;
}
});
});
}

View File

@ -39,7 +39,7 @@ asyncTest("Init", 1, function() {
cloudstoragedao_test.storage = new app.dao.DeviceStorage(cloudstoragedao_test.util, cloudstoragedao_test.crypto, jsonDao, null);
cloudstoragedao_test.cloudstorage = new app.dao.CloudStorage(window, $);
cloudstoragedao_test.keychain = new app.dao.KeychainDAO(jsonDao, cloudstoragedao_test.cloudstorage);
cloudstoragedao_test.emailDao = new app.dao.EmailDAO(_, cloudstoragedao_test.crypto, cloudstoragedao_test.storage, cloudstoragedao_test.cloudstorage, cloudstoragedao_test.util, cloudstoragedao_test.keychain);
cloudstoragedao_test.emailDao = new app.dao.EmailDAO(jsonDao, cloudstoragedao_test.crypto, cloudstoragedao_test.storage, cloudstoragedao_test.cloudstorage, cloudstoragedao_test.util, cloudstoragedao_test.keychain);
// clear db before tests
jsonDao.clear(function(err) {
@ -57,7 +57,7 @@ asyncTest("Put public key to cloud", 1, function() {
});
});
asyncTest("Get Public key from cloud", 2, function() {
asyncTest("Get Public key from cloud by id", 2, function() {
cloudstoragedao_test.cloudstorage.getPublicKey(cloudstoragedao_test.keypair.publicKey._id, function(err, data) {
ok(!err && data && data.publicKey, 'Get public key from cloud');
deepEqual(data, cloudstoragedao_test.keypair.publicKey, 'Public key is equal');
@ -66,6 +66,15 @@ asyncTest("Get Public key from cloud", 2, function() {
});
});
asyncTest("Get Public key from cloud by email", 2, function() {
cloudstoragedao_test.cloudstorage.getPublicKeyByUserId(cloudstoragedao_test.keypair.publicKey.userId, function(err, data) {
ok(!err && data && data.publicKey, 'Get public key from cloud');
deepEqual(data, cloudstoragedao_test.keypair.publicKey, 'Public key is equal');
start();
});
});
asyncTest("Delete Public key from cloud", 1, function() {
cloudstoragedao_test.cloudstorage.removePublicKey(cloudstoragedao_test.keypair.publicKey._id, function(err) {
ok(!err, 'Delete public key from cloud');

View File

@ -22,10 +22,13 @@ asyncTest("Init", 3, function() {
},
putPrivateKey: function(prk, callback) {
callback();
},
getPublicKeyByUserId: function(userId, callback) {
callback();
}
};
emaildao_test.keychain = new app.dao.KeychainDAO(jsonDao, cloudstorageStub);
emaildao_test.emailDao = new app.dao.EmailDAO(_, emaildao_test.crypto, emaildao_test.storage, cloudstorageStub, util, emaildao_test.keychain);
emaildao_test.emailDao = new app.dao.EmailDAO(jsonDao, emaildao_test.crypto, emaildao_test.storage, cloudstorageStub, util, emaildao_test.keychain);
// generate test data
emaildao_test.list = new TestData().getEmailCollection(100);