mirror of
https://github.com/amark/gun.git
synced 2025-03-30 15:08:33 +00:00
104 lines
4.5 KiB
JavaScript
104 lines
4.5 KiB
JavaScript
|
|
var User = require('./user'), SEA = User.SEA, Gun = User.GUN, noop = function(){};
|
|
|
|
// Well first we have to actually create a user. That is what this function does.
|
|
User.prototype.create = function(...args){
|
|
var pair = typeof args[0] === 'object' && (args[0].pub || args[0].epub) ? args[0] : typeof args[1] === 'object' && (args[1].pub || args[1].epub) ? args[1] : null;
|
|
var alias = pair && (pair.pub || pair.epub) ? pair.pub : typeof args[0] === 'string' ? args[0] : null;
|
|
var pass = pair && (pair.pub || pair.epub) ? pair : alias && typeof args[1] === 'string' ? args[1] : null;
|
|
var cb = args.filter(arg => typeof arg === 'function')[0] || null; // cb now can stand anywhere, after alias/pass or pair
|
|
var opt = args && args.length > 1 && typeof args[args.length-1] === 'object' ? args[args.length-1] : {}; // opt is always the last parameter which typeof === 'object' and stands after cb
|
|
|
|
var gun = this, cat = (gun._), root = gun.back(-1);
|
|
cb = cb || noop;
|
|
opt = opt || {};
|
|
if(false !== opt.check){
|
|
var err;
|
|
if(!alias){ err = "No user." }
|
|
if((pass||'').length < 8){ err = "Password too short!" }
|
|
if(err){
|
|
cb({err: Gun.log(err)});
|
|
return gun;
|
|
}
|
|
}
|
|
if(cat.ing){
|
|
(cb || noop)({err: Gun.log("User is already being created or authenticated!"), wait: true});
|
|
return gun;
|
|
}
|
|
cat.ing = true;
|
|
var act = {}, u;
|
|
act.a = function(pubs){
|
|
act.pubs = pubs;
|
|
if(pubs && !opt.already){
|
|
// If we can enforce that a user name is already taken, it might be nice to try, but this is not guaranteed.
|
|
var ack = {err: Gun.log('User already created!')};
|
|
cat.ing = false;
|
|
(cb || noop)(ack);
|
|
gun.leave();
|
|
return;
|
|
}
|
|
act.salt = String.random(64); // pseudo-randomly create a salt, then use PBKDF2 function to extend the password with it.
|
|
SEA.work(pass, act.salt, act.b); // this will take some short amount of time to produce a proof, which slows brute force attacks.
|
|
}
|
|
act.b = function(proof){
|
|
act.proof = proof;
|
|
pair ? act.c(pair) : SEA.pair(act.c) // generate a brand new key pair or use the existing.
|
|
}
|
|
act.c = function(pair){
|
|
var tmp
|
|
act.pair = pair || {};
|
|
if(tmp = cat.root.user){
|
|
tmp._.sea = pair;
|
|
tmp.is = {pub: pair.pub, epub: pair.epub, alias: alias};
|
|
}
|
|
// the user's public key doesn't need to be signed. But everything else needs to be signed with it! // we have now automated it! clean up these extra steps now!
|
|
act.data = {pub: pair.pub};
|
|
act.d();
|
|
}
|
|
act.d = function(){
|
|
act.data.alias = alias;
|
|
act.e();
|
|
}
|
|
act.e = function(){
|
|
act.data.epub = act.pair.epub;
|
|
SEA.encrypt({priv: act.pair.priv, epriv: act.pair.epriv}, act.proof, act.f, {raw:1}); // to keep the private key safe, we AES encrypt it with the proof of work!
|
|
}
|
|
act.f = function(auth){
|
|
act.data.auth = JSON.stringify({ek: auth, s: act.salt});
|
|
act.g(act.data.auth);
|
|
}
|
|
act.g = function(auth){ var tmp;
|
|
act.data.auth = act.data.auth || auth;
|
|
root.get(tmp = '~'+act.pair.pub).put(act.data).on(act.h); // awesome, now we can actually save the user with their public key as their ID.
|
|
var link = {}; link[tmp] = {'#': tmp}; root.get('~@'+alias).put(link).get(tmp).on(act.i); // next up, we want to associate the alias with the public key. So we add it to the alias list.
|
|
}
|
|
act.h = function(data, key, msg, eve){
|
|
eve.off(); act.h.ok = 1; act.i();
|
|
}
|
|
act.i = function(data, key, msg, eve){
|
|
if(eve){ act.i.ok = 1; eve.off() }
|
|
if(!act.h.ok || !act.i.ok){ return }
|
|
cat.ing = false;
|
|
cb({ok: 0, pub: act.pair.pub}); // callback that the user has been created. (Note: ok = 0 because we didn't wait for disk to ack)
|
|
if(noop === cb){ pair ? gun.auth(pair) : gun.auth(alias, pass) } // if no callback is passed, auto-login after signing up.
|
|
}
|
|
root.get('~@'+alias).once(act.a);
|
|
return gun;
|
|
}
|
|
User.prototype.leave = function(opt, cb){
|
|
var gun = this, user = (gun.back(-1)._).user;
|
|
if(user){
|
|
delete user.is;
|
|
delete user._.is;
|
|
delete user._.sea;
|
|
}
|
|
if(SEA.window){
|
|
try{var sS = {};
|
|
sS = window.sessionStorage;
|
|
delete sS.recall;
|
|
delete sS.pair;
|
|
}catch(e){};
|
|
}
|
|
return gun;
|
|
}
|
|
|