123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- var SEA = require('./sea');
- var Gun = SEA.Gun;
- const queryGunAliases = require('./query')
- const parseProps = require('./parse')
- // This is internal User authentication func.
- const authenticate = async (alias, pass, gunRoot) => {
- // load all public keys associated with the username alias we want to log in with.
- const aliases = (await queryGunAliases(alias, gunRoot))
- .filter(a => !!a.pub && !!a.put)
- // Got any?
- if (!aliases.length) {
- throw { err: 'Public key does not exist!' }
- }
- let err
- // then attempt to log into each one until we find ours!
- // (if two users have the same username AND the same password... that would be bad)
- const users = await Promise.all(aliases.map(async (a, i) => {
- // attempt to PBKDF2 extend the password with the salt. (Verifying the signature gives us the plain text salt.)
- const auth = parseProps(a.put.auth)
- // NOTE: aliasquery uses `gun.get` which internally SEA.read verifies the data for us, so we do not need to re-verify it here.
- // SEA.verify(at.put.auth, pub).then(function(auth){
- try {
- const proof = await SEA.work(pass, auth.s)
- //const props = { pub: pub, proof: proof, at: at }
- // the proof of work is evidence that we've spent some time/effort trying to log in, this slows brute force.
- /*
- MARK TO @mhelander : pub vs epub!???
- */
- const salt = auth.salt
- const sea = await SEA.decrypt(auth.ek, proof)
- if (!sea) {
- err = 'Failed to decrypt secret! ' + (i+1) +'/'+aliases.length;
- return
- }
- // now we have AES decrypted the private key, from when we encrypted it with the proof at registration.
- // if we were successful, then that meanswe're logged in!
- const priv = sea.priv
- const epriv = sea.epriv
- const epub = a.put.epub
- // TODO: 'salt' needed?
- err = null
- if(SEA.window){
- var tmp = SEA.window.sessionStorage;
- if(tmp && gunRoot._.opt.remember){
- SEA.window.sessionStorage.alias = alias;
- SEA.window.sessionStorage.tmp = pass;
- }
- }
- return {priv: priv, pub: a.put.pub, salt: salt, epub: epub, epriv: epriv };
- } catch (e) {
- err = 'Failed to decrypt secret!'
- throw { err }
- }
- }))
- var user = Gun.list.map(users, function(acc){ if(acc){ return acc } })
- if (!user) {
- throw { err: err || 'Public key does not exist!' }
- }
- return user
- }
- module.exports = authenticate;
-
|