| 
					
				 | 
			
			
				@@ -2,257 +2,270 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // TODO: This needs to be split into all separate functions. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // Not just everything thrown into 'create'. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const SEA = require('./sea') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const User = require('./user') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const authRecall = require('./recall') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const authsettings = require('./settings') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const authenticate = require('./authenticate') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const finalizeLogin = require('./login') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const authLeave = require('./leave') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const _initial_authsettings = require('./settings').recall 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const Gun = SEA.Gun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var SEA = require('./sea'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var User = require('./user'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var authsettings = require('./settings'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var Gun = SEA.Gun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var noop = function(){}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var u; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // Well first we have to actually create a user. That is what this function does. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    User.prototype.create = function(username, pass, cb, opt){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // TODO: Needs to be cleaned up!!! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const gunRoot = this.back(-1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var gun = this, cat = (gun._); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      cb = cb || function(){}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    User.prototype.create = function(alias, pass, cb, opt){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var gun = this, cat = (gun._), root = gun.back(-1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      cb = cb || noop; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       if(cat.ing){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cb({err: Gun.log("User is already being created or authenticated!"), wait: true}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return gun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       cat.ing = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       opt = opt || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var resolve = function(){}, reject = resolve; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Because more than 1 user might have the same username, we treat the alias as a list of those users. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if(cb){ resolve = reject = cb } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      gunRoot.get('~@'+username).get(async (at, ev) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ev.off() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (at.put && !opt.already) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      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. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          const err = 'User already created!' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          Gun.log(err) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var ack = {err: Gun.log('User already created!')}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           cat.ing = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          cb(ack); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           gun.leave(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return reject({ err: err }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const salt = Gun.text.random(64) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // pseudo-randomly create a salt, then use CryptoJS's PBKDF2 function to extend the password with it. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          const proof = await SEA.work(pass, salt) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // this will take some short amount of time to produce a proof, which slows brute force attacks. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          const pairs = await SEA.pair() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // now we have generated a brand new ECDSA key pair for the user account. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          const pub = pairs.pub 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          const priv = pairs.priv 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          const epriv = pairs.epriv 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // the user's public key doesn't need to be signed. But everything else needs to be signed with it! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          const alias = await SEA.sign(username, pairs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if(u === alias){ throw SEA.err } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          const epub = await SEA.sign(pairs.epub, pairs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if(u === epub){ throw SEA.err } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // to keep the private key safe, we AES encrypt it with the proof of work! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          const auth = await SEA.encrypt({ priv: priv, epriv: epriv }, proof) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          .then((auth) => // TODO: So signedsalt isn't needed? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // SEA.sign(salt, pairs).then((signedsalt) => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            SEA.sign({ek: auth, s: salt}, pairs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ).catch((e) => { Gun.log('SEA.en or SEA.write calls failed!'); cat.ing = false; gun.leave(); reject(e) }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          const user = { alias: alias, pub: pub, epub: epub, auth: auth } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          const tmp = '~'+pairs.pub; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // awesome, now we can actually save the user with their public key as their ID. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          try{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          gunRoot.get(tmp).put(user) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }catch(e){console.log(e)} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // next up, we want to associate the alias with the public key. So we add it to the alias list. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          gunRoot.get('~@'+username).put(Gun.obj.put({}, tmp, Gun.val.link.ify(tmp))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // callback that the user has been created. (Note: ok = 0 because we didn't wait for disk to ack) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          setTimeout(() => { cat.ing = false; resolve({ ok: 0, pub: pairs.pub}) }, 10) // TODO: BUG! If `.auth` happens synchronously after `create` finishes, auth won't work. This setTimeout is a temporary hack until we can properly fix it. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } catch (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          Gun.log('SEA.create failed!') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          cat.ing = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          gun.leave(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          reject(e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        act.salt = Gun.text.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; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SEA.pair(act.c); // now we have generated a brand new ECDSA key pair for the user account. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      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}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return gun;  // gun chain commands must return gun chains! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 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}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SEA.sign(alias, pair, act.d);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      act.d = function(sig){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        act.data.alias = alias || sig; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SEA.sign(act.pair.epub, act.pair, act.e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      act.e = function(epub){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        act.data.epub = act.pair.epub || epub;  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SEA.encrypt({priv: act.pair.priv, epriv: act.pair.epriv}, act.proof, act.f); // 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});  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SEA.sign({ek: auth, s: act.salt}, act.pair, act.g); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      act.g = function(auth){ var tmp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        act.data.auth = act.data.auth || auth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        root.get(tmp = '~'+act.pair.pub).put(act.data); // awesome, now we can actually save the user with their public key as their ID. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        root.get('~@'+alias).put(Gun.obj.put({}, tmp, Gun.val.link.ify(tmp))); // next up, we want to associate the alias with the public key. So we add it to the alias list. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        setTimeout(function(){ // we should be able to delete this now, right? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        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){ gun.auth(alias, pass) } // if no callback is passed, auto-login after signing up. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        },10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      root.get('~@'+alias).once(act.a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return gun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // now that we have created a user, we want to authenticate them! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     User.prototype.auth = function(alias, pass, cb, opt){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // TODO: Needs to be cleaned up!!!! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const opts = opt || (typeof cb !== 'function' && cb) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      let pin = opts && opts.pin 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      let newpass = opts && opts.newpass 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const gunRoot = this.back(-1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      cb = typeof cb === 'function' ? cb : () => {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      newpass = newpass || (opts||{}).change; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var gun = this, cat = (gun._); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var gun = this, cat = (gun._), root = gun.back(-1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      cb = cb || function(){}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       if(cat.ing){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cb({err: "User is already being created or authenticated!", wait: true}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cb({err: Gun.log("User is already being created or authenticated!"), wait: true}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return gun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       cat.ing = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!pass && pin) { (async function(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var r = await authRecall(gunRoot, { alias: alias, pin: pin }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return cat.ing = false, cb(r), gun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } catch (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var err = { err: 'Auth attempt failed! Reason: No session data for alias & PIN' } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return cat.ing = false, gun.leave(), cb(err), gun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }}()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return gun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      opt = opt || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var pair = (alias && (alias.pub || alias.epub))? alias : (pass && (pass.pub || pass.epub))? pass : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var act = {}, u; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      act.a = function(data){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(!data){ return act.b() } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(!data.pub){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var tmp = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Gun.node.is(data, function(v){ tmp.push(v) }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return act.b(tmp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(act.name){ return act.f(data) } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        act.c((act.data = data).auth); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const putErr = (msg) => (e) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const { message, err = message || '' } = e 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Gun.log(msg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var error = { err: msg+' Reason: '+err } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return cat.ing = false, gun.leave(), cb(error), gun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      act.b = function(list){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var get = (act.list = (act.list||[]).concat(list||[])).shift(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(u === get){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if(act.name){ return act.err('Your user account is not published for dApps to access, please consider syncing it online, or allowing local access by adding your device as a peer.') } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return act.err('Wrong user or password.')  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        root.get(get).once(act.a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      (async function(){ try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const keys = await authenticate(alias, pass, gunRoot) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!keys) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return putErr('Auth attempt failed!')({ message: 'No keys' }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      act.c = function(auth){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(u === auth){ return act.b() } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(Gun.text.is(auth)){ return act.c(Gun.obj.ify(auth)) } // new format 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SEA.work(pass, (act.auth = auth).s, act.d, act.enc); // the proof of work is evidence that we've spent some time/effort trying to log in, this slows brute force. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      act.d = function(proof){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SEA.decrypt(act.auth.ek, proof, act.e, act.enc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      act.e = function(half){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(u === half){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if(!act.enc){ // try old format 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            act.enc = {encode: 'utf8'}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return act.c(act.auth); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } act.enc = null; // end backwards 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return act.b(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const pub = keys.pub 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const priv = keys.priv 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const epub = keys.epub 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const epriv = keys.epriv 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // we're logged in! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (newpass) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // password update so encrypt private key using new pwd + salt 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            const salt = Gun.text.random(64); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            const encSigAuth = await SEA.work(newpass, salt) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .then((key) => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              SEA.encrypt({ priv: priv, epriv: epriv }, key) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              .then((auth) => SEA.sign({ek: auth, s: salt}, keys)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            const signedEpub = await SEA.sign(epub, keys) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            const signedAlias = await SEA.sign(alias, keys) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            const user = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              pub: pub, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              alias: signedAlias, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              auth: encSigAuth, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              epub: signedEpub 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // awesome, now we can update the user using public key ID. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            gunRoot.get('~'+user.pub).put(user) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // then we're done 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            const login = finalizeLogin(alias, keys, gunRoot, { pin }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            login.catch(putErr('Failed to finalize login with new password!')) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return cat.ing = false, cb(await login), gun 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } catch (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return putErr('Password set attempt failed!')(e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          const login = finalizeLogin(alias, keys, gunRoot, { pin: pin }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          login.catch(putErr('Finalizing login failed!')) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return cat.ing = false, cb(await login), gun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        act.half = half; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        act.f(act.data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      act.f = function(data){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(!data || !data.pub){ return act.b() } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var tmp = act.half || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        act.g({pub: data.pub, epub: data.epub, priv: tmp.priv, epriv: tmp.epriv}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      act.g = function(pair){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        act.pair = pair; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var user = (root._).user, at = (user._); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var tmp = at.tag; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var upt = at.opt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        at = user._ = root.get('~'+pair.pub)._; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        at.opt = upt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // add our credentials in-memory only to our root user instance 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        user.is = {pub: pair.pub, epub: pair.epub, alias: alias}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        at.sea = act.pair; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cat.ing = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(pass && !Gun.text.is(act.data.auth)){ opt.shuffle = opt.change = pass; } // migrate UTF8 + Shuffle! Test against NAB alias test_sea_shuffle + passw0rd 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        opt.change? act.z() : cb(at); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(SEA.window && ((gun.back('user')._).opt||opt).remember){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // TODO: this needs to be modular. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          try{var sS = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          sS = window.sessionStorage; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          sS.recall = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          sS.alias = alias; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          sS.tmp = pass; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }catch(e){} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } catch (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return putErr('Auth attempt failed!')(e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } }()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (root._).on('auth', at) // TODO: Deprecate this, emit on user instead! Update docs when you do. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          //at.on('auth', at) // Arrgh, this doesn't work without event "merge" code, but "merge" code causes stack overflow and crashes after logging in & trying to write data. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }catch(e){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Gun.log("Your 'auth' callback crashed with:", e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      act.z = function(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // password update so encrypt private key using new pwd + salt 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        act.salt = Gun.text.random(64); // pseudo-random 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SEA.work(opt.change, act.salt, act.y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      act.y = function(proof){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SEA.encrypt({priv: act.pair.priv, epriv: act.pair.epriv}, proof, act.x); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      act.x = function(auth){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        act.w(JSON.stringify({ek: auth, s: act.salt})); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //SEA.sign({ek: auth, s: act.salt}, act.pair, act.w); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      act.w = function(auth){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(opt.shuffle){ // delete in future! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var tmp = Gun.obj.to(act.data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Gun.obj.del(tmp, '_'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          tmp.auth = auth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          console.log('migrate core account from UTF8 & shuffle', tmp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          root.get('~'+act.pair.pub).put(tmp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } // end delete 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        root.get('~'+act.pair.pub).get('auth').put(auth, cb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      act.err = function(e){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var ack = {err: Gun.log(e || 'User cannot be found!')}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cat.ing = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cb(ack); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      act.plugin = function(name){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(!(act.name = name)){ return act.err() } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var tmp = [name]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if('~' !== name[0]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          tmp[1] = '~'+name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          tmp[2] = '~@'+name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        act.b(tmp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(pair){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        act.g(pair); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(alias){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        root.get('~@'+alias).once(act.a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(!alias && !pass){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SEA.name(act.plugin); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       return gun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     User.prototype.pair = function(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      console.log("user.pair() IS DEPRECATED AND WILL BE DELETED!!!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       var user = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       if(!user.is){ return false } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       return user._.sea; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    User.prototype.leave = async function(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    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(typeof window !== 'undefined'){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var tmp = window.sessionStorage; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        delete tmp.alias; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        delete tmp.tmp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(SEA.window){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try{var sS = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sS = window.sessionStorage; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete sS.alias; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete sS.tmp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete sS.recall; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }catch(e){}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return await authLeave(this.back(-1)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return gun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // If authenticated user wants to delete his/her account, let's support it! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    User.prototype.delete = async function(alias, pass){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const gunRoot = this.back(-1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    User.prototype.delete = async function(alias, pass, cb){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var gun = this, root = gun.back(-1), user = gun.back('user'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const __gky40 = await authenticate(alias, pass, gunRoot) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const pub = __gky40.pub 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        await authLeave(gunRoot, alias) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Delete user data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        gunRoot.get('~'+pub).put(null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Wipe user data from memory 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const { user = { _: {} } } = gunRoot._; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // TODO: is this correct way to 'logout' user from Gun.User ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        [ 'alias', 'sea', 'pub' ].map((key) => delete user._[key]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        user._.is = user.is = {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        gunRoot.user() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return { ok: 0 }  // TODO: proper return codes??? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        user.auth(alias, pass, function(ack){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var pub = (user.is||{}).pub; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Delete user data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          user.map().once(function(){ this.put(null) }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Wipe user data from memory 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          user.leave(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (cb || noop)({ok: 0}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } catch (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Gun.log('User.delete failed! Error:', e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        throw e // TODO: proper error codes??? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Gun.log('User.delete failed! Error:', e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return gun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // If authentication is to be remembered over reloads or browser closing, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // set validity time in minutes. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    User.prototype.recall = function(setvalidity, options){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var gun = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const gunRoot = this.back(-1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      let validity 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      let opts 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-       
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var o = setvalidity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if(o && o.sessionStorage){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if(typeof window !== 'undefined'){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var tmp = window.sessionStorage; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if(tmp){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            gunRoot._.opt.remember = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if(tmp.alias && tmp.tmp){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              gunRoot.user().auth(tmp.alias, tmp.tmp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    User.prototype.recall = function(opt, cb){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var gun = this, root = gun.back(-1), tmp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      opt = opt || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(opt && opt.sessionStorage){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(SEA.window){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          try{var sS = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          sS = window.sessionStorage; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if(sS){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (root._).opt.remember = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ((gun.back('user')._).opt||opt).remember = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(sS.recall || (sS.alias && sS.tmp)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              root.user().auth(sS.alias, sS.tmp, cb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }catch(e){} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return gun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!Gun.val.is(setvalidity)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        opts = setvalidity 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        validity = _initial_authsettings.validity 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        opts = options 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        validity = setvalidity * 60 // minutes to seconds 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // opts = { hook: function({ iat, exp, alias, proof }) } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // iat == Date.now() when issued, exp == seconds to expire from iat 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // How this works: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // called when app bootstraps, with wanted options 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // IF authsettings.validity === 0 THEN no remember-me, ever 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // IF PIN then signed 'remember' to window.sessionStorage and 'auth' to IndexedDB 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        authsettings.validity = typeof validity !== 'undefined' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ? validity : _initial_authsettings.validity 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        authsettings.hook = (Gun.obj.has(opts, 'hook') && typeof opts.hook === 'function') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ? opts.hook : _initial_authsettings.hook 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // All is good. Should we do something more with actual recalled data? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        (async function(){ await authRecall(gunRoot) }()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return gun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } catch (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const err = 'No session!' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Gun.log(err) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // NOTE! It's fine to resolve recall with reason why not successful 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // instead of rejecting... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        //return { err: (e && e.err) || err } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return gun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        TODO: copy mhelander's expiry code back in. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Although, we should check with community, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        should expiry be core or a plugin? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return gun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     User.prototype.alive = async function(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       const gunRoot = this.back(-1) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -278,7 +291,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     User.prototype.grant = function(to, cb){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       console.log("`.grant` API MAY BE DELETED OR CHANGED OR RENAMED, DO NOT USE!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       var gun = this, user = gun.back(-1).user(), pair = user.pair(), path = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      gun.back(function(at){ if(at.pub){ return } path += (at.get||'') }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gun.back(function(at){ if(at.is){ return } path += (at.get||'') }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       (async function(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       var enc, sec = await user.get('trust').get(pair.pub).get(path).then(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       sec = await SEA.decrypt(sec, pair); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -299,7 +312,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     User.prototype.secret = function(data, cb){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       console.log("`.secret` API MAY BE DELETED OR CHANGED OR RENAMED, DO NOT USE!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       var gun = this, user = gun.back(-1).user(), pair = user.pair(), path = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      gun.back(function(at){ if(at.pub){ return } path += (at.get||'') }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gun.back(function(at){ if(at.is){ return } path += (at.get||'') }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       (async function(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       var enc, sec = await user.get('trust').get(pair.pub).get(path).then(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       sec = await SEA.decrypt(sec, pair); 
			 |