mirror of
https://github.com/moparisthebest/mail
synced 2024-11-22 17:02:17 -05:00
Implement setDeviceName and generateDeviceSecret
This commit is contained in:
parent
4880c162f8
commit
e720753779
@ -5,7 +5,13 @@
|
||||
define(function(require) {
|
||||
'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) {
|
||||
this._localDbDao = localDbDao;
|
||||
@ -176,7 +182,7 @@ define(function(require) {
|
||||
var self = this;
|
||||
|
||||
// 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) {
|
||||
callback(err);
|
||||
return;
|
||||
@ -250,7 +256,7 @@ define(function(require) {
|
||||
* @param {Function} callback(error)
|
||||
*/
|
||||
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])
|
||||
*/
|
||||
KeychainDAO.prototype.getDeviceSecret = function(callback) {
|
||||
var self = this;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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) {
|
||||
callback(err);
|
||||
return;
|
||||
@ -477,7 +525,7 @@ define(function(require) {
|
||||
}
|
||||
|
||||
// lookup in local storage
|
||||
self._localDbDao.read('publickey_' + id, function(err, pubkey) {
|
||||
self._localDbDao.read(DB_PUBLICKEY + '_' + id, function(err, pubkey) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
@ -513,27 +561,27 @@ define(function(require) {
|
||||
*/
|
||||
KeychainDAO.prototype.listLocalPublicKeys = function(callback) {
|
||||
// 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) {
|
||||
this._localDbDao.remove('publickey_' + id, callback);
|
||||
this._localDbDao.remove(DB_PUBLICKEY + '_' + id, callback);
|
||||
};
|
||||
|
||||
KeychainDAO.prototype.lookupPrivateKey = function(id, callback) {
|
||||
// lookup in local storage
|
||||
this._localDbDao.read('privatekey_' + id, callback);
|
||||
this._localDbDao.read(DB_PRIVATEKEY + '_' + id, callback);
|
||||
};
|
||||
|
||||
KeychainDAO.prototype.saveLocalPublicKey = function(pubkey, callback) {
|
||||
// persist public key (email, _id)
|
||||
var pkLookupKey = 'publickey_' + pubkey._id;
|
||||
var pkLookupKey = DB_PUBLICKEY + '_' + pubkey._id;
|
||||
this._localDbDao.persist(pkLookupKey, pubkey, callback);
|
||||
};
|
||||
|
||||
KeychainDAO.prototype.saveLocalPrivateKey = function(privkey, callback) {
|
||||
// persist private key (email, _id)
|
||||
var prkLookupKey = 'privatekey_' + privkey._id;
|
||||
var prkLookupKey = DB_PRIVATEKEY + '_' + privkey._id;
|
||||
this._localDbDao.persist(prkLookupKey, privkey, callback);
|
||||
};
|
||||
|
||||
|
@ -4,18 +4,22 @@ define(function(require) {
|
||||
var LawnchairDAO = require('js/dao/lawnchair-dao'),
|
||||
PublicKeyDAO = require('js/dao/publickey-dao'),
|
||||
KeychainDAO = require('js/dao/keychain-dao'),
|
||||
PrivateKeyDAO = require('js/dao/privatekey-dao'),
|
||||
Crypto = require('js/crypto/crypto'),
|
||||
expect = chai.expect;
|
||||
|
||||
var testUser = 'test@example.com';
|
||||
|
||||
describe('Keychain DAO unit tests', function() {
|
||||
|
||||
var keychainDao, lawnchairDaoStub, pubkeyDaoStub;
|
||||
var keychainDao, lawnchairDaoStub, pubkeyDaoStub, privkeyDaoStub, cryptoStub;
|
||||
|
||||
beforeEach(function() {
|
||||
lawnchairDaoStub = sinon.createStubInstance(LawnchairDAO);
|
||||
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() {});
|
||||
@ -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() {
|
||||
it('should fail', function(done) {
|
||||
var keypair = {
|
||||
|
Loading…
Reference in New Issue
Block a user