Refactored back with twist User.auth, added User.leave & test cases

This commit is contained in:
mhelander 2017-08-31 12:28:19 +03:00
parent 68f5725899
commit 95a35547cf
2 changed files with 92 additions and 31 deletions

25
sea.js
View File

@ -44,7 +44,8 @@
var user = root._.user || (root._.user = root.chain()); // create a user context.
user.create = User.create; // attach a factory method to it.
user.auth = User.auth; // and a login method.
user.remember = User.remember; // and a credentials persisting method.
user.leave = User.leave; // and a logout method.
// TODO: definitely needed this: user.delete = User.delete;
return user; // return the user!
}
@ -120,9 +121,10 @@
if (cb){doCreate(cb, cb)} else {return new Promise(doCreate)}
};
// now that we have created a user, we want to authenticate them!
User.auth = function(props, cb){
var alias = props.alias, pass = props.pass, newpass = props.newpass;
User.auth = function(alias, pass, cb, opt){
var opts = opt || (typeof cb !== 'function' && cb) || {};
var root = this.back(-1);
cb = typeof cb === 'function' && cb;
var doAuth = function(resolve, reject){
// load all public keys associated with the username alias we want to log in with.
root.get('alias/'+alias).get(function(at, ev){
@ -168,10 +170,10 @@
// emit an auth event, useful for page redirects and stuff.
Gun.on('auth', user._);
}
if(newpass) {
if(opts.newpass) {
// password update so encrypt private key using new pwd + salt
var newsalt = Gun.text.random(64);
SEA.proof(newpass, newsalt).then(function(proof){
SEA.proof(opts.newpass, newsalt).then(function(proof){
SEA.en(priv, proof).then(function(encVal){
return SEA.write(encVal, priv).then(function(sAuth){
return { pub: key, auth: sAuth };
@ -211,13 +213,14 @@
};
if (cb){doAuth(cb, cb)} else {return new Promise(doAuth)}
};
// now that we have created a user, we want to authenticate them!
User.remember = function(props, cb){
var doRemember = function(resolve, reject){
Gun.log('User.remember is TODO: still');
reject({ err: 'Not implemented.' });
// now that we authenticated a user, we want to support logout too!
User.leave = function(cb){
var root = this.back(-1);
var doLogout = function(resolve, reject){
root._.user = root.chain();
resolve({ok: 0});
}
if (cb){doRemember(cb, cb)} else {return new Promise(doRemember)}
if (cb){doLogout(cb, cb)} else {return new Promise(doLogout)}
};
// After we have a GUN extension to make user registration/login easy, we then need to handle everything else.

View File

@ -7843,7 +7843,7 @@ describe('Gun', function(){
var encKeys = ['ct', 'iv', 's'];
['callback', 'Promise'].forEach(function(type){
describe(type, function(){
describe(type+':', function(){
it('proof', function(done){
var check = function(proof){
expect(proof).to.not.be(undefined);
@ -8037,11 +8037,12 @@ describe('Gun', function(){
console.log('TODO: User! THIS IS AN EARLY ALPHA!!!');
var alias = 'dude';
var pass = 'my secret password';
var user = Gun().user();
var gun = Gun();
var user = gun.user();
Gun.log.off = true; // Supress all console logging
['callback', 'Promise'].forEach(function(type){
describe(type, function(){
describe(type+':', function(){
describe('create', function(){
it('new', function(done){
var check = function(ack){
@ -8086,12 +8087,11 @@ describe('Gun', function(){
expect(ack).to.not.have.key('err');
done();
};
var props = {alias: alias+type, pass: pass};
// Gun.user.auth - authenticates existing user
if(type === 'callback'){
user.auth(props, check);
user.auth(alias+type, pass, check);
} else {
user.auth(props).then(check).catch(done);
user.auth(alias+type, pass).then(check).catch(done);
}
});
@ -8104,11 +8104,10 @@ describe('Gun', function(){
expect(ack.err).to.not.be('');
done();
};
var props = {alias: alias+type, pass: pass+'not'};
if(type === 'callback'){
user.auth(props, check);
user.auth(alias+type, pass+'not', check);
} else {
user.auth(props).then(function(ack){
user.auth(alias+type, pass+'not').then(function(ack){
done('Unexpected login success!');
}).catch(check);
}
@ -8123,11 +8122,10 @@ describe('Gun', function(){
expect(ack.err).to.not.be('');
done();
};
var props = {alias: alias+type+'not', pass: pass};
if(type === 'callback'){
user.auth(props, check);
user.auth(alias+type+'not', pass, check);
} else {
user.auth(props).then(function(ack){
user.auth(alias+type+'not', pass).then(function(ack){
done('Unexpected login success!');
}).catch(check);
}
@ -8140,12 +8138,12 @@ describe('Gun', function(){
expect(ack).to.not.have.key('err');
done();
};
var props = {alias: alias+type, pass: pass, newpass: pass+' new'};
// Gun.user.auth - with newpass props sets new password
if(type === 'callback'){
user.auth(props, check);
user.auth(alias+type, pass, check, {newpass: pass+' new'});
} else {
user.auth(props).then(check).catch(done);
user.auth(alias+type, pass, {newpass: pass+' new'}).then(check)
.catch(done);
}
});
@ -8160,19 +8158,79 @@ describe('Gun', function(){
};
var props = {alias: alias+type, pass: pass+'not', newpass: pass+' new'};
if(type === 'callback'){
user.auth(props, check);
user.auth(alias+type, pass+'not', check, {newpass: pass+' new'});
} else {
user.auth(props).then(function(ack){
user.auth(alias+type, pass+'not', {newpass: pass+' new'})
.then(function(ack){
done('Unexpected password change success!');
}).catch(check);
}
});
it.skip('no recall no session storing');
});
describe('remember', function(){
it.skip('TBD', function(done){
done();
describe('leave', function(){
it('valid session', function(done){
var check = function(ack){
expect(ack).to.not.be(undefined);
expect(ack).to.not.be('');
expect(ack).to.not.have.key('err');
expect(ack).to.have.key('ok');
expect(gun.back(-1)._.user).to.not.have.keys(['sea', 'pub']);
done();
};
user.auth(alias+type, pass+' new').then(function(usr){
expect(usr).to.not.be(undefined);
expect(usr).to.not.be('');
expect(usr).to.not.have.key('err');
expect(usr).to.have.key('put');
// Gun.user.leave - performs logout for authenticated user
if(type === 'callback'){
user.leave(check);
} else {
user.leave().then(check).catch(done);
}
}).catch(done);
});
it('no session', function(done){
var check = function(ack){
expect(ack).to.not.be(undefined);
expect(ack).to.not.be('');
expect(ack).to.not.have.key('err');
expect(ack).to.have.key('ok');
done();
};
user.leave().then(function(ack){
expect(gun.back(-1)._.user).to.not.have.keys(['sea', 'pub']);
if(type === 'callback'){
user.leave(check);
} else {
user.leave().then(check).catch(done);
}
});
});
});
describe('delete - TODO: how?', function(){
it.skip('existing authenticated user');
it.skip('unauthenticated user');
});
describe('recall', function(){
it.skip('with zero validity auth skips storing');
it.skip('with validity auth stores session');
it.skip('valid session');
it.skip('expired session');
it.skip('changed password');
it.skip('no session');
});
describe('alive', function(){
it.skip('valid session');
it.skip('expired session');
it.skip('recall hook session manipulation');
});
});
});