123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- const Buffer = require('./buffer')
- const authsettings = require('./settings')
-
- const queryGunAliases = require('./query')
- const parseProps = require('./parse')
- const updateStorage = require('./update')
- const SEA = require('./sea')
- const Gun = SEA.Gun;
- const finalizeLogin = require('./login')
-
- const authRecall = async (gunRoot, authprops) => {
-
- const remember = authprops || sessionStorage.getItem('remember')
- const { alias = sessionStorage.getItem('user'), pin: pIn } = authprops || {}
- const pin = pIn && Buffer.from(pIn, 'utf8').toString('base64')
-
- const checkRememberData = async ({ proof, alias: aLias, iat, exp, remember }) => {
- if (!!proof && alias === aLias) {
- const checkNotExpired = (args) => {
- if (Math.floor(Date.now() / 1000) < (iat + args.exp)) {
-
- return Object.assign(args, { iat: iat, proof: proof })
- } else {
- Gun.log('Authentication expired!')
- }
- }
-
- const hooked = authsettings.hook({ alias: alias, iat: iat, exp: exp, remember: remember })
- return ((hooked instanceof Promise)
- && await hooked.then(checkNotExpired)) || checkNotExpired(hooked)
- }
- }
- const readAndDecrypt = async (data, pub, key) =>
- parseProps(await SEA.decrypt(await SEA.verify(data, pub), key))
-
- if (gunRoot._.user
- && Gun.obj.has(gunRoot._.user._, 'pub')
- && Gun.obj.has(gunRoot._.user._, 'sea')) {
- return gunRoot._.user._
- }
-
- if (!alias) {
- throw { err: 'No authentication session found!' }
- }
-
- if (!remember) {
- throw {
- err: (await seaIndexedDb.get(alias, 'auth') && authsettings.validity
- && 'Missing PIN and alias!') || 'No authentication session found!'
- }
- }
-
- const aliases = (await queryGunAliases(alias, gunRoot))
- .filter(({ pub } = {}) => !!pub)
-
- if (!aliases.length) {
- throw { err: 'Public key does not exist!' }
- }
- let err
-
-
- const [ { key, at, proof, pin: newPin } = {} ] = await Promise
- .all(aliases.filter(({ at: { put } = {} }) => !!put)
- .map(async ({ at: at, pub: pub }) => {
- const readStorageData = async (args) => {
- const props = args || parseProps(await SEA.verify(remember, pub, true))
- let pin = props.pin
- let aLias = props.alias
- const data = (!pin && alias === aLias)
-
- ? await checkRememberData(props)
-
- : await checkRememberData(await readAndDecrypt(await seaIndexedDb.get(alias, 'auth'), pub, pin))
- pin = pin || data.pin
- delete data.pin
- return { pin: pin, data: data }
- }
-
- const __gky20 = await readStorageData(pin && { pin, alias })
- const data = __gky20.data
- const newPin = __gky20.pin
- const proof = data.proof
- if (!proof) {
- if (!data) {
- err = 'No valid authentication session found!'
- return
- }
- try {
- await updateStorage()(data)
- } catch (e) {}
- err = 'Expired session!'
- return
- }
- try {
- const auth= at.put.auth.auth
- const sea = await SEA.decrypt(auth, proof)
- if (!sea) {
- err = 'Failed to decrypt private key!'
- return
- }
- const priv = sea.priv
- const epriv = sea.epriv
- const epub = at.put.epub
-
- err = null
- return { proof: proof, at: at, pin: newPin, key: { pub: pub, priv: priv, epriv: epriv, epub: epub } }
- } catch (e) {
- err = 'Failed to decrypt private key!'
- return
- }
- }).filter((props) => !!props))
- if (!key) {
- throw { err: err || 'Public key does not exist!' }
- }
-
-
- try {
- await updateStorage(proof, key, newPin || pin)(key)
- const user = Object.assign(key, { at: at, proof: proof })
- const pIN = newPin || pin
- const pinProp = pIN && { pin: Buffer.from(pIN, 'base64').toString('utf8') }
- return await finalizeLogin(alias, user, gunRoot, pinProp)
- } catch (e) {
- Gun.log('Failed to finalize login with new password!')
- const { err = '' } = e || {}
- throw { err: 'Finalizing new password login failed! Reason: '+err }
- }
- }
- module.exports = authRecall
-
|