WIP test
This commit is contained in:
parent
e109550d9b
commit
39e85396db
7 changed files with 123 additions and 42 deletions
|
|
@ -24,7 +24,7 @@ var Storage = module.exports.Storage = require('./Storage');
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Identity(email, password, opts) {
|
function Identity(password, opts) {
|
||||||
preconditions.checkArgument(opts);
|
preconditions.checkArgument(opts);
|
||||||
|
|
||||||
this.storage = Identity._getStorage(opts, password);
|
this.storage = Identity._getStorage(opts, password);
|
||||||
|
|
@ -133,7 +133,7 @@ Identity.anyWallet = function(opts, cb) {
|
||||||
Identity.create = function(email, password, opts, cb) {
|
Identity.create = function(email, password, opts, cb) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
|
|
||||||
var iden = new Identity(email, password, opts);
|
var iden = new Identity(password, opts);
|
||||||
|
|
||||||
Identity._createProfile(email, password, iden.storage, function(err, profile) {
|
Identity._createProfile(email, password, iden.storage, function(err, profile) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
@ -183,7 +183,7 @@ Identity.prototype.validate = function(authcode, cb) {
|
||||||
* @return {undefined}
|
* @return {undefined}
|
||||||
*/
|
*/
|
||||||
Identity.open = function(email, password, opts, cb) {
|
Identity.open = function(email, password, opts, cb) {
|
||||||
var iden = new Identity(email, password, opts);
|
var iden = new Identity(password, opts);
|
||||||
|
|
||||||
Identity._openProfile(email, password, iden.storage, function(err, profile) {
|
Identity._openProfile(email, password, iden.storage, function(err, profile) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
@ -301,10 +301,7 @@ Identity.prototype.importWallet = function(base64, password, skipFields, cb) {
|
||||||
preconditions.checkArgument(password);
|
preconditions.checkArgument(password);
|
||||||
preconditions.checkArgument(cb);
|
preconditions.checkArgument(cb);
|
||||||
|
|
||||||
this.storage.savePassphrase();
|
var obj = this.storage.decrypt(base64, password);
|
||||||
this.storage.setPassword(password);
|
|
||||||
var obj = this.storage.decrypt(base64);
|
|
||||||
this.storage.restorePassphrase();
|
|
||||||
|
|
||||||
var readOpts = {
|
var readOpts = {
|
||||||
storage: this.storage,
|
storage: this.storage,
|
||||||
|
|
@ -339,24 +336,60 @@ Identity.prototype.closeWallet = function(wid, cb) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @desc Return a base64 encrypted version of the wallet
|
* @desc Return a base64 encrypted version of the wallet
|
||||||
* @return {string} base64 encoded string
|
* @return {string} base64 encoded string
|
||||||
*/
|
*/
|
||||||
Identity.prototype.toEncryptedObj = function() {
|
Identity.import = function(str, password, opts, cb) {
|
||||||
|
preconditions.checkArgument(str);
|
||||||
|
console.log('[Identity.js.347:str::]',str); //TODO
|
||||||
|
|
||||||
|
|
||||||
|
var json = JSON.parse(str);
|
||||||
|
preconditions.checkArgument(_.isNumber(json.iterations));
|
||||||
|
|
||||||
|
|
||||||
|
var iden = new Identity(password, opts);
|
||||||
|
iden.profile = Profile.import(json.profile, password, iden.storage);
|
||||||
|
|
||||||
|
json.wallets = json.wallets || {};
|
||||||
|
|
||||||
|
var l = json.wallets.length,
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
if (!l)
|
||||||
|
return cb(null, iden);
|
||||||
|
|
||||||
|
_.each(this.wallets, function(wstr) {
|
||||||
|
iden.importWallet(wstr, password, skipFields, function(err, w) {
|
||||||
|
if (err) return cb(err);
|
||||||
|
log.debug('Wallet ' + w.getId() + ' imported');
|
||||||
|
|
||||||
|
if (++i == l)
|
||||||
|
iden.store(cb);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc Return JSON with base64 encoded strings for wallets and profile, and iteration count
|
||||||
|
* @return {string} Stringify JSON
|
||||||
|
*/
|
||||||
|
Identity.prototype.export = function() {
|
||||||
var ret = {};
|
var ret = {};
|
||||||
ret.iterations = this.storage.iterations;
|
ret.iterations = this.storage.iterations;
|
||||||
|
ret.profile = this.profile.export();
|
||||||
ret.wallets = {};
|
ret.wallets = {};
|
||||||
|
|
||||||
_.each(this.openWallets, function(w) {
|
_.each(this.openWallets, function(w) {
|
||||||
ret.wallets[w.getId()] = w.toEncryptedObj();
|
ret.wallets[w.getId()] = w.toEncryptedObj();
|
||||||
});
|
});
|
||||||
|
|
||||||
return ret;
|
var r = JSON.stringify(ret);
|
||||||
|
return r;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @desc This method prepares options for a new Wallet
|
* @desc This method prepares options for a new Wallet
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,25 @@ Profile.prototype.toObj = function() {
|
||||||
return _.clone(_.pick(this, 'hash', 'email', 'extra', 'walletInfos'));
|
return _.clone(_.pick(this, 'hash', 'email', 'extra', 'walletInfos'));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @desc Return a base64 encrypted version of the wallet
|
||||||
|
* @return {string} base64 encoded string
|
||||||
|
*/
|
||||||
|
Profile.prototype.export = function() {
|
||||||
|
var profObj = this.toObj();
|
||||||
|
return this.storage.encrypt(profObj);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @desc Return a base64 encrypted version of the wallet
|
||||||
|
* @return {string} base64 encoded string
|
||||||
|
*/
|
||||||
|
Profile.import = function(str, password, storage) {
|
||||||
|
var obj = storage.decrypt(str,password)
|
||||||
|
return new Profile(obj, storage);
|
||||||
|
};
|
||||||
|
|
||||||
Profile.prototype.getWallet = function(walletId, cb) {
|
Profile.prototype.getWallet = function(walletId, cb) {
|
||||||
return this.walletInfos[walletId];
|
return this.walletInfos[walletId];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -230,11 +230,22 @@ Storage.prototype.clearAll = function(cb) {
|
||||||
this.db.clear(cb);
|
this.db.clear(cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
Storage.prototype.decrypt = function(base64, password) {
|
Storage.prototype.decrypt = function(base64, password, iterations) {
|
||||||
// password
|
|
||||||
|
if (password) {
|
||||||
|
this.storage.savePassphrase();
|
||||||
|
var opts = iterations ? {iterations: iterations} : {};
|
||||||
|
|
||||||
|
this.storage.setPassword(password, opts);
|
||||||
|
}
|
||||||
|
|
||||||
var decryptedStr = this._decrypt(base64);
|
var decryptedStr = this._decrypt(base64);
|
||||||
return JSON.parse(decryptedStr);
|
var ret = JSON.parse(decryptedStr);
|
||||||
|
|
||||||
|
if (password)
|
||||||
|
this.storage.restorePassphrase();
|
||||||
|
|
||||||
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
Storage.prototype.encrypt = function(obj) {
|
Storage.prototype.encrypt = function(obj) {
|
||||||
|
|
|
||||||
|
|
@ -1169,7 +1169,7 @@ Wallet.fromObj = function(o, readOpts) {
|
||||||
* @desc Return a base64 encrypted version of the wallet
|
* @desc Return a base64 encrypted version of the wallet
|
||||||
* @return {string} base64 encoded string
|
* @return {string} base64 encoded string
|
||||||
*/
|
*/
|
||||||
Wallet.prototype.toEncryptedObj = function() {
|
Wallet.prototype.export = function() {
|
||||||
var walletObj = this.toObj();
|
var walletObj = this.toObj();
|
||||||
return this.storage.encrypt(walletObj);
|
return this.storage.encrypt(walletObj);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -304,35 +304,12 @@ describe('Identity model', function() {
|
||||||
|
|
||||||
iden.importWallet("encrypted object", "xxx", [], function(err) {
|
iden.importWallet("encrypted object", "xxx", [], function(err) {
|
||||||
iden.openWallet('ID123', function(err, w) {
|
iden.openWallet('ID123', function(err, w) {
|
||||||
iden.storage.savePassphrase.calledOnce.should.equal(true);
|
|
||||||
iden.storage.restorePassphrase.calledOnce.should.equal(true);
|
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(w);
|
should.exist(w);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should import and update indexes', function() {
|
|
||||||
var wallet = {
|
|
||||||
id: "fake wallet",
|
|
||||||
updateIndexes: function(cb) {
|
|
||||||
cb();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
iden.fromEncryptedObj = sinon.stub().returns(wallet);
|
|
||||||
|
|
||||||
var w = iden.fromEncryptedObj("encrypted", "password");
|
|
||||||
|
|
||||||
should.exist(w);
|
|
||||||
wallet.should.equal(w);
|
|
||||||
});
|
|
||||||
it('should import with a wrong password', function() {
|
|
||||||
iden.fromEncryptedObj = sinon.stub().returns(null);
|
|
||||||
var w = iden.fromEncryptedObj("encrypted", "passwordasdfasdf");
|
|
||||||
should.not.exist(w);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#listWallets', function() {
|
describe('#listWallets', function() {
|
||||||
|
|
@ -356,29 +333,61 @@ describe('Identity model', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('#toEncryptedObj', function() {
|
describe('#export', function() {
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
var ws = [];
|
var ws = [];
|
||||||
_.each([0, 1, 2, 3, 4], function(i) {
|
_.each([0, 1, 2, 3, 4], function(i) {
|
||||||
var w = sinon.stub();
|
var w = sinon.stub();
|
||||||
w.toEncryptedObj = sinon.stub().returns('enc' + i);
|
w.export = sinon.stub().returns('enc' + i);
|
||||||
w.getId = sinon.stub().returns('wid' + i);
|
w.getId = sinon.stub().returns('wid' + i);
|
||||||
ws.push(w);
|
ws.push(w);
|
||||||
});
|
});
|
||||||
iden.openWallets = ws;
|
iden.openWallets = ws;
|
||||||
|
iden.profile.export = sinon.stub().returns('penc');
|
||||||
iden.storage.iterations = 13;
|
iden.storage.iterations = 13;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create an encrypted object', function() {
|
it('should create an encrypted object', function() {
|
||||||
var ret = iden.toEncryptedObj();
|
var ret = JSON.parse(iden.export());
|
||||||
ret.iterations.should.equal(13);
|
ret.iterations.should.equal(13);
|
||||||
|
ret.profile.should.equal('penc');
|
||||||
_.each([0, 1, 2, 3, 4], function(i) {
|
_.each([0, 1, 2, 3, 4], function(i) {
|
||||||
ret.wallets['wid' + i].should.equal('enc' + i);
|
ret.wallets['wid' + i].should.equal('enc' + i);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe.only('#import', function() {
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
var ws = [];
|
||||||
|
_.each([0, 1, 2, 3, 4], function(i) {
|
||||||
|
var w = sinon.stub();
|
||||||
|
w.export = sinon.stub().returns('enc' + i);
|
||||||
|
w.getId = sinon.stub().returns('wid' + i);
|
||||||
|
ws.push(w);
|
||||||
|
});
|
||||||
|
iden.openWallets = ws;
|
||||||
|
iden.profile.export = sinon.stub().returns('penc');
|
||||||
|
iden.storage.iterations = 13;
|
||||||
|
iden.storage.decrypt = sinon.stub().returns({
|
||||||
|
email: '1@1.com',
|
||||||
|
hash: 'hash1234'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an encrypted object', function(done) {
|
||||||
|
Identity.import(JSON.stringify({
|
||||||
|
iterations: 10
|
||||||
|
}), '1234', config, function(err, ret) {
|
||||||
|
should.not.exist(err);
|
||||||
|
should.exist(ret);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('#joinWallet', function() {
|
describe('#joinWallet', function() {
|
||||||
var opts = {
|
var opts = {
|
||||||
secret: '8WtTuiFTkhP5ao7AF2QErSwV39Cbur6pdMebKzQXFqL59RscXM',
|
secret: '8WtTuiFTkhP5ao7AF2QErSwV39Cbur6pdMebKzQXFqL59RscXM',
|
||||||
|
|
|
||||||
|
|
@ -419,6 +419,15 @@ describe('Storage model', function() {
|
||||||
var wo = s.decrypt(encryptedLegacy1);
|
var wo = s.decrypt(encryptedLegacy1);
|
||||||
should.not.exist(wo);
|
should.not.exist(wo);
|
||||||
});
|
});
|
||||||
|
it('should call save / restorePassphrase', function() {
|
||||||
|
var wo = s.decrypt(encryptedLegacy1, 'xxx');
|
||||||
|
s.savePassphrase.calledOnce.should.equal(true);
|
||||||
|
s.restorePassphrase.calledOnce.should.equal(true);
|
||||||
|
should.not.exist(wo);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
it('should be able to decrypt an old backup', function() {
|
it('should be able to decrypt an old backup', function() {
|
||||||
s._setPassphrase(legacyPassword1);
|
s._setPassphrase(legacyPassword1);
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ FakeWallet.prototype.setEnc = function(enc) {
|
||||||
this.enc = enc;
|
this.enc = enc;
|
||||||
};
|
};
|
||||||
|
|
||||||
FakeWallet.prototype.toEncryptedObj = function() {
|
FakeWallet.prototype.export = function() {
|
||||||
return this.enc;
|
return this.enc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue