diff --git a/.env.example b/.env.example index 4ea11d88..65c31d1c 100644 --- a/.env.example +++ b/.env.example @@ -3,4 +3,4 @@ PEERS=["http://gun.shock.network:8765/gun"] MS_TO_TOKEN_EXPIRATION=4500000 DISABLE_SHOCK_ENCRYPTION=false CACHE_HEADERS_MANDATORY=true -SHOCK_CACHE=true \ No newline at end of file +SHOCK_CACHE=true diff --git a/config/defaults.js b/config/defaults.js index d30c9ad4..37cae17a 100644 --- a/config/defaults.js +++ b/config/defaults.js @@ -25,6 +25,8 @@ const parsePath = (filePath = "") => { const lndDirectory = getLndDirectory(); +const SHOCK_SUPER_PEER = "http://gun.shock.network:8765/gun" + module.exports = (mainnet = false) => { const network = mainnet ? "mainnet" : "testnet"; @@ -48,7 +50,7 @@ module.exports = (mainnet = false) => { logfile: "shockapi.log", lndLogFile: parsePath(`${lndDirectory}/logs/bitcoin/${network}/lnd.log`), lndDirPath: lndDirectory, - peers: ["http://gun.shock.network:8765/gun"], + peers: [SHOCK_SUPER_PEER], useTLS: false, tokenExpirationMS: 4500000 }; diff --git a/services/gunDB/Mediator/index.js b/services/gunDB/Mediator/index.js index f8fc73ec..bfd8764b 100644 --- a/services/gunDB/Mediator/index.js +++ b/services/gunDB/Mediator/index.js @@ -12,8 +12,8 @@ require('gun/lib/open') // @ts-ignore require('gun/lib/load') const debounce = require('lodash/debounce') -const Encryption = require('../../../utils/encryptionStore') +const Encryption = require('../../../utils/encryptionStore') const Key = require('../contact-api/key') /** @type {import('../contact-api/SimpleGUN').ISEA} */ @@ -1275,6 +1275,56 @@ const register = async (alias, pass) => { ) } + /** + * Peers provided to gun. + */ + const peers = Object.values(gun._.opt.peers) + + const theresPeers = peers.length > 0 + const atLeastOneIsConnected = peers.some( + p => p.wire && p.wire.readyState === 1 + ) + + if (theresPeers && !atLeastOneIsConnected) { + throw new Error( + 'No connected to any peers for checking of duplicate aliases' + ) + } + + if (theresPeers && atLeastOneIsConnected) { + // this import is done here to avoid circular dependency hell + const { timeout5 } = require('../contact-api/utils') + + let userData = await timeout5( + new Promise(res => { + gun.get(`~@${alias}`).once(ud => res(ud)) + }) + ) + + if (userData) { + throw new Error( + 'The given alias has been used before, use an unique alias instead.' + ) + } + + await new Promise(res => setTimeout(res, 300)) + + userData = await timeout5( + new Promise(res => { + gun.get(`~@${alias}`).once(ud => res(ud), { + // https://github.com/amark/gun/pull/971#issue-438630761 + wait: 1500 + }) + }) + ) + + if (userData) { + throw new Error( + 'The given alias has been used before, use an unique alias instead. (Caught at 2nd try)' + ) + } + } + _isRegistering = true /** @type {import('../contact-api/SimpleGUN').CreateAck} */ @@ -1282,6 +1332,13 @@ const register = async (alias, pass) => { user.create(alias, pass, ack => res(ack)) ) + // An empty ack object seems to be caused by a duplicate alias sign up + if ('{}' === JSON.stringify(ack)) { + throw new Error( + 'The given alias has been used before, use an unique alias instead. (Empty ack)' + ) + } + _isRegistering = false if (typeof ack.err === 'string') { diff --git a/services/gunDB/config.js b/services/gunDB/config.js index 355581a1..44dab137 100644 --- a/services/gunDB/config.js +++ b/services/gunDB/config.js @@ -11,7 +11,9 @@ dotenv.config() // @ts-ignore Let it crash if undefined exports.DATA_FILE_NAME = process.env.DATA_FILE_NAME || defaults.dataFileName -// @ts-ignore Let it crash if undefined +/** + * @type {string[]} + */ exports.PEERS = process.env.PEERS ? JSON.parse(process.env.PEERS) : defaults.peers diff --git a/services/gunDB/contact-api/SimpleGUN.ts b/services/gunDB/contact-api/SimpleGUN.ts index d7e54313..3a9cd77b 100644 --- a/services/gunDB/contact-api/SimpleGUN.ts +++ b/services/gunDB/contact-api/SimpleGUN.ts @@ -30,9 +30,20 @@ interface OpenListenerDataObj { export type Listener = (data: ListenerData, key: string) => void export type Callback = (ack: Ack) => void +export interface Peer { + url: string + id: string + wire?: { + readyState: number + } +} + export interface Soul { get: string put: Primitive | null | object | undefined + opt: { + peers: Record + } } export type OpenListenerData = Primitive | null | OpenListenerDataObj diff --git a/src/routes.js b/src/routes.js index 73222778..032cf5c3 100644 --- a/src/routes.js +++ b/src/routes.js @@ -713,7 +713,7 @@ module.exports = async ( logger.error(err); return res.status(500).json({ field: "unknown", - errorMessage: err + errorMessage: err.message || err }) } });