From 4212ea4612438a0a9fad3418da5d97a0599f5500 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 25 Feb 2020 17:42:40 -0400 Subject: [PATCH] better handling of gun instances --- services/gunDB/Mediator/index.js | 123 ++++++++++++++++++------------- 1 file changed, 72 insertions(+), 51 deletions(-) diff --git a/services/gunDB/Mediator/index.js b/services/gunDB/Mediator/index.js index 2037ecf6..34b3612b 100644 --- a/services/gunDB/Mediator/index.js +++ b/services/gunDB/Mediator/index.js @@ -216,13 +216,16 @@ let user /* eslint-enable init-declarations */ -let _currentAlias = '' -let _currentPass = '' +/** @type {string|null} */ +let _currentAlias = null +/** @type {string|null} */ +let _currentPass = null -let mySec = '' +/** @type {string|null} */ +let mySec = null /** @returns {string} */ -const getMySecret = () => mySec +const getMySecret = () => /** @type {string} */ (mySec) let _isAuthenticating = false let _isRegistering = false @@ -231,18 +234,46 @@ const isAuthenticated = () => typeof user.is === 'object' && user.is !== null const isAuthenticating = () => _isAuthenticating const isRegistering = () => _isRegistering +const getGun = () => { + return gun +} + +const getUser = () => { + return user +} + /** * Returns a promise containing the public key of the newly created user. * @param {string} alias * @param {string} pass + * @param {UserGUNNode=} user * @returns {Promise} */ -const authenticate = async (alias, pass) => { +const authenticate = async (alias, pass, user = getUser()) => { + const isFreshGun = user !== getUser() + if (isFreshGun) { + const ack = await new Promise(res => { + user.auth(alias, pass, _ack => { + res(_ack) + }) + }) + + if (typeof ack.err === 'string') { + throw new Error(ack.err) + } else if (typeof ack.sea === 'object') { + API.Jobs.onAcceptedRequests(user, mySEA) + API.Jobs.onOrders(user, gun, mySEA) + + return ack.sea.pub + } else { + throw new Error('Unknown error.') + } + } + if (isAuthenticated()) { - const currAlias = user.is && user.is.alias - if (alias !== currAlias) { + if (alias !== _currentAlias) { throw new Error( - `Tried to re-authenticate with an alias different to that of stored one, tried: ${alias} - stored: ${currAlias}, logoff first if need to change aliases.` + `Tried to re-authenticate with an alias different to that of stored one, tried: ${alias} - stored: ${_currentAlias}, logoff first if need to change aliases.` ) } // move this to a subscription; implement off() ? todo @@ -272,7 +303,7 @@ const authenticate = async (alias, pass) => { } else if (typeof ack.sea === 'object') { mySec = await mySEA.secret(user._.sea.epub, user._.sea) - _currentAlias = user.is ? user.is.alias : '' + _currentAlias = alias _currentPass = await mySEA.encrypt(pass, mySec) await new Promise(res => setTimeout(res, 5000)) @@ -290,44 +321,44 @@ const logoff = () => { user.leave() } -const instantiateGun = async () => { - let mySecret = '' - - if (user && user.is) { - mySecret = /** @type {string} */ (await mySEA.secret( - user._.sea.epub, - user._.sea - )) - } - - const _gun = new Gun({ +const instantiateGun = () => { + const _gun = /** @type {unknown} */ (new Gun({ axe: false, peers: Config.PEERS - }) + })) - // please typescript - const __gun = /** @type {unknown} */ (_gun) + gun = /** @type {GUNNode} */ (_gun) - gun = /** @type {GUNNode} */ (__gun) - - // eslint-disable-next-line require-atomic-updates user = gun.user() - - if (_currentAlias && _currentPass) { - const pass = await mySEA.decrypt(_currentPass, mySecret) - - if (typeof pass !== 'string') { - throw new Error('could not decrypt stored in memory current pass') - } - - user.leave() - - await authenticate(_currentAlias, pass) - } } instantiateGun() +const freshGun = async () => { + const _gun = /** @type {unknown} */ (new Gun({ + axe: false, + peers: Config.PEERS + })) + + const gun = /** @type {GUNNode} */ (_gun) + + const user = gun.user() + + if (!_currentAlias || !_currentPass || !mySec) { + throw new Error('Called freshGun() without alias, pass and secret cached') + } + + const pass = await mySEA.decrypt(_currentPass, mySec) + + if (typeof pass !== 'string') { + throw new Error('could not decrypt stored in memory current pass') + } + + await authenticate(_currentAlias, pass, user) + + return { gun, user } +} + /** * @param {string} token * @returns {Promise} @@ -363,14 +394,6 @@ const throwOnInvalidToken = async token => { } } -const getGun = () => { - return gun -} - -const getUser = () => { - return user -} - class Mediator { /** * @param {Readonly} socket @@ -1211,9 +1234,7 @@ const register = async (alias, pass) => { // restart instances so write to user graph work, there's an issue with gun // (at least on node) where after initial user creation, writes to user graph // don't work - await instantiateGun() - - user.leave() + instantiateGun() return authenticate(alias, pass).then(async pub => { await API.Actions.setDisplayName('anon' + pub.slice(0, 8), user) @@ -1246,9 +1267,9 @@ module.exports = { isAuthenticating, isRegistering, register, - instantiateGun, getGun, getUser, mySEA, - getMySecret + getMySecret, + freshGun }