mirror of
https://github.com/amark/gun.git
synced 2025-03-30 15:08:33 +00:00
63 lines
2.6 KiB
JavaScript
63 lines
2.6 KiB
JavaScript
|
|
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;
|
|
|