mirror of
https://github.com/moparisthebest/mail
synced 2024-11-26 02:42:17 -05:00
Implement setDeviceName and generateDeviceSecret
This commit is contained in:
parent
4880c162f8
commit
e720753779
@ -5,7 +5,13 @@
|
|||||||
define(function(require) {
|
define(function(require) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var _ = require('underscore');
|
var _ = require('underscore'),
|
||||||
|
util = require('js/crypto/util');
|
||||||
|
|
||||||
|
var DB_PUBLICKEY = 'publickey',
|
||||||
|
DB_PRIVATEKEY = 'privatekey',
|
||||||
|
DB_DEVICENAME = 'devicename',
|
||||||
|
DB_DEVICEKEY = 'devicekey';
|
||||||
|
|
||||||
var KeychainDAO = function(localDbDao, publicKeyDao, privateKeyDao, crypto) {
|
var KeychainDAO = function(localDbDao, publicKeyDao, privateKeyDao, crypto) {
|
||||||
this._localDbDao = localDbDao;
|
this._localDbDao = localDbDao;
|
||||||
@ -176,7 +182,7 @@ define(function(require) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
// search local keyring for public key
|
// search local keyring for public key
|
||||||
self._localDbDao.list('publickey', 0, null, function(err, allPubkeys) {
|
self._localDbDao.list(DB_PUBLICKEY, 0, null, function(err, allPubkeys) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
@ -250,7 +256,7 @@ define(function(require) {
|
|||||||
* @param {Function} callback(error)
|
* @param {Function} callback(error)
|
||||||
*/
|
*/
|
||||||
KeychainDAO.prototype.setDeviceName = function(deviceName, callback) {
|
KeychainDAO.prototype.setDeviceName = function(deviceName, callback) {
|
||||||
callback(new Error('Not yet implemented!'));
|
this._localDbDao.persist(DB_DEVICENAME, deviceName, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -258,15 +264,57 @@ define(function(require) {
|
|||||||
* @param {Function} callback(error, deviceSecret:[base64 encoded string])
|
* @param {Function} callback(error, deviceSecret:[base64 encoded string])
|
||||||
*/
|
*/
|
||||||
KeychainDAO.prototype.getDeviceSecret = function(callback) {
|
KeychainDAO.prototype.getDeviceSecret = function(callback) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
// check if deviceName is already persisted in storage and if not return an error
|
// check if deviceName is already persisted in storage and if not return an error
|
||||||
|
self._localDbDao.read(DB_DEVICENAME, function(err, deviceName) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// generate random deviceKeys or get from storage
|
if (!deviceName) {
|
||||||
|
callback(new Error('Device name not set!'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// persist deviceKeys to local storage (in plaintext)
|
readOrGenerateDeviceKey(function(deviceKey) {
|
||||||
|
generateDeciceSecret(deviceName, deviceKey);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// encrypt: deviceSecret = Es(deviceKeys, deviceName) -> callback
|
// generate random deviceKey or get from storage
|
||||||
|
function readOrGenerateDeviceKey(localCallback) {
|
||||||
|
self._localDbDao.read(DB_DEVICEKEY, function(err, storedDevKey) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
callback(new Error('Not yet implemented!'));
|
if (storedDevKey) {
|
||||||
|
// a device key is already available locally
|
||||||
|
localCallback(storedDevKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate random deviceKey
|
||||||
|
var deviceKey = util.random(256);
|
||||||
|
// persist deviceKey to local storage (in plaintext)
|
||||||
|
self._localDbDao.persist(DB_DEVICEKEY, deviceKey, function(err) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
localCallback(deviceKey);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// encrypt: deviceSecret = Es(deviceKey, deviceName) -> callback
|
||||||
|
function generateDeciceSecret(deviceName, deviceKey) {
|
||||||
|
self._crypto.encrypt(deviceName, deviceKey, callback);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -357,7 +405,7 @@ define(function(require) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
// search for user's public key locally
|
// search for user's public key locally
|
||||||
self._localDbDao.list('publickey', 0, null, function(err, allPubkeys) {
|
self._localDbDao.list(DB_PUBLICKEY, 0, null, function(err, allPubkeys) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
@ -477,7 +525,7 @@ define(function(require) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// lookup in local storage
|
// lookup in local storage
|
||||||
self._localDbDao.read('publickey_' + id, function(err, pubkey) {
|
self._localDbDao.read(DB_PUBLICKEY + '_' + id, function(err, pubkey) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
@ -513,27 +561,27 @@ define(function(require) {
|
|||||||
*/
|
*/
|
||||||
KeychainDAO.prototype.listLocalPublicKeys = function(callback) {
|
KeychainDAO.prototype.listLocalPublicKeys = function(callback) {
|
||||||
// search local keyring for public key
|
// search local keyring for public key
|
||||||
this._localDbDao.list('publickey', 0, null, callback);
|
this._localDbDao.list(DB_PUBLICKEY, 0, null, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
KeychainDAO.prototype.removeLocalPublicKey = function(id, callback) {
|
KeychainDAO.prototype.removeLocalPublicKey = function(id, callback) {
|
||||||
this._localDbDao.remove('publickey_' + id, callback);
|
this._localDbDao.remove(DB_PUBLICKEY + '_' + id, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
KeychainDAO.prototype.lookupPrivateKey = function(id, callback) {
|
KeychainDAO.prototype.lookupPrivateKey = function(id, callback) {
|
||||||
// lookup in local storage
|
// lookup in local storage
|
||||||
this._localDbDao.read('privatekey_' + id, callback);
|
this._localDbDao.read(DB_PRIVATEKEY + '_' + id, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
KeychainDAO.prototype.saveLocalPublicKey = function(pubkey, callback) {
|
KeychainDAO.prototype.saveLocalPublicKey = function(pubkey, callback) {
|
||||||
// persist public key (email, _id)
|
// persist public key (email, _id)
|
||||||
var pkLookupKey = 'publickey_' + pubkey._id;
|
var pkLookupKey = DB_PUBLICKEY + '_' + pubkey._id;
|
||||||
this._localDbDao.persist(pkLookupKey, pubkey, callback);
|
this._localDbDao.persist(pkLookupKey, pubkey, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
KeychainDAO.prototype.saveLocalPrivateKey = function(privkey, callback) {
|
KeychainDAO.prototype.saveLocalPrivateKey = function(privkey, callback) {
|
||||||
// persist private key (email, _id)
|
// persist private key (email, _id)
|
||||||
var prkLookupKey = 'privatekey_' + privkey._id;
|
var prkLookupKey = DB_PRIVATEKEY + '_' + privkey._id;
|
||||||
this._localDbDao.persist(prkLookupKey, privkey, callback);
|
this._localDbDao.persist(prkLookupKey, privkey, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,18 +4,22 @@ define(function(require) {
|
|||||||
var LawnchairDAO = require('js/dao/lawnchair-dao'),
|
var LawnchairDAO = require('js/dao/lawnchair-dao'),
|
||||||
PublicKeyDAO = require('js/dao/publickey-dao'),
|
PublicKeyDAO = require('js/dao/publickey-dao'),
|
||||||
KeychainDAO = require('js/dao/keychain-dao'),
|
KeychainDAO = require('js/dao/keychain-dao'),
|
||||||
|
PrivateKeyDAO = require('js/dao/privatekey-dao'),
|
||||||
|
Crypto = require('js/crypto/crypto'),
|
||||||
expect = chai.expect;
|
expect = chai.expect;
|
||||||
|
|
||||||
var testUser = 'test@example.com';
|
var testUser = 'test@example.com';
|
||||||
|
|
||||||
describe('Keychain DAO unit tests', function() {
|
describe('Keychain DAO unit tests', function() {
|
||||||
|
|
||||||
var keychainDao, lawnchairDaoStub, pubkeyDaoStub;
|
var keychainDao, lawnchairDaoStub, pubkeyDaoStub, privkeyDaoStub, cryptoStub;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
lawnchairDaoStub = sinon.createStubInstance(LawnchairDAO);
|
lawnchairDaoStub = sinon.createStubInstance(LawnchairDAO);
|
||||||
pubkeyDaoStub = sinon.createStubInstance(PublicKeyDAO);
|
pubkeyDaoStub = sinon.createStubInstance(PublicKeyDAO);
|
||||||
keychainDao = new KeychainDAO(lawnchairDaoStub, pubkeyDaoStub);
|
privkeyDaoStub = new sinon.createStubInstance(PrivateKeyDAO);
|
||||||
|
cryptoStub = new sinon.createStubInstance(Crypto);
|
||||||
|
keychainDao = new KeychainDAO(lawnchairDaoStub, pubkeyDaoStub, privkeyDaoStub, cryptoStub);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function() {});
|
afterEach(function() {});
|
||||||
@ -574,6 +578,84 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('setDeviceName', function() {
|
||||||
|
it('should work', function(done) {
|
||||||
|
lawnchairDaoStub.persist.yields();
|
||||||
|
|
||||||
|
keychainDao.setDeviceName('iPhone', done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getDeviceSecret', function() {
|
||||||
|
it('should fail when device name is not set', function(done) {
|
||||||
|
lawnchairDaoStub.read.withArgs('devicename').yields();
|
||||||
|
|
||||||
|
keychainDao.getDeviceSecret(function(err, deviceSecret) {
|
||||||
|
expect(err.message).to.equal('Device name not set!');
|
||||||
|
expect(deviceSecret).to.not.exist;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail due to erorr when reading device name', function(done) {
|
||||||
|
lawnchairDaoStub.read.withArgs('devicename').yields(42);
|
||||||
|
|
||||||
|
keychainDao.getDeviceSecret(function(err, deviceSecret) {
|
||||||
|
expect(err).to.equal(42);
|
||||||
|
expect(deviceSecret).to.not.exist;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail due to erorr when reading device key', function(done) {
|
||||||
|
lawnchairDaoStub.read.withArgs('devicename').yields(null, 'iPhone');
|
||||||
|
lawnchairDaoStub.read.withArgs('devicekey').yields(42);
|
||||||
|
|
||||||
|
keychainDao.getDeviceSecret(function(err, deviceSecret) {
|
||||||
|
expect(err).to.equal(42);
|
||||||
|
expect(deviceSecret).to.not.exist;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail due to erorr when storing device key', function(done) {
|
||||||
|
lawnchairDaoStub.read.withArgs('devicename').yields(null, 'iPhone');
|
||||||
|
lawnchairDaoStub.read.withArgs('devicekey').yields();
|
||||||
|
lawnchairDaoStub.persist.withArgs('devicekey').yields(42);
|
||||||
|
|
||||||
|
keychainDao.getDeviceSecret(function(err, deviceSecret) {
|
||||||
|
expect(err).to.equal(42);
|
||||||
|
expect(deviceSecret).to.not.exist;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should work when device key is not set', function(done) {
|
||||||
|
lawnchairDaoStub.read.withArgs('devicename').yields(null, 'iPhone');
|
||||||
|
lawnchairDaoStub.read.withArgs('devicekey').yields();
|
||||||
|
lawnchairDaoStub.persist.withArgs('devicekey').yields();
|
||||||
|
cryptoStub.encrypt.yields(null, 'secret');
|
||||||
|
|
||||||
|
keychainDao.getDeviceSecret(function(err, deviceSecret) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
expect(deviceSecret).to.equal('secret');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should work when device key is set', function(done) {
|
||||||
|
lawnchairDaoStub.read.withArgs('devicename').yields(null, 'iPhone');
|
||||||
|
lawnchairDaoStub.read.withArgs('devicekey').yields(null, 'key');
|
||||||
|
cryptoStub.encrypt.withArgs('iPhone', 'key').yields(null, 'secret');
|
||||||
|
|
||||||
|
keychainDao.getDeviceSecret(function(err, deviceSecret) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
expect(deviceSecret).to.equal('secret');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('put user keypair', function() {
|
describe('put user keypair', function() {
|
||||||
it('should fail', function(done) {
|
it('should fail', function(done) {
|
||||||
var keypair = {
|
var keypair = {
|
||||||
|
Loading…
Reference in New Issue
Block a user