From e0dc5f4b2159644071a288cc21c0bb62e2180816 Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Mon, 26 Apr 2021 12:28:43 +0200 Subject: [PATCH] Make jsenv detection conditional without return --- src/fetcher/dns.js | 75 ++++++++------- src/fetcher/irc.js | 131 +++++++++++++------------ src/fetcher/xmpp.js | 227 ++++++++++++++++++++++---------------------- 3 files changed, 215 insertions(+), 218 deletions(-) diff --git a/src/fetcher/dns.js b/src/fetcher/dns.js index 23f79de..be9fa6d 100644 --- a/src/fetcher/dns.js +++ b/src/fetcher/dns.js @@ -26,47 +26,46 @@ const jsEnv = require("browser-or-node") module.exports.timeout = 5000 if (!jsEnv.isNode) { - module.exports.fn = null - return -} + const dns = require('dns') -const dns = require('dns') + /** + * Execute a fetch request + * @function + * @async + * @param {object} data - Data used in the request + * @param {string} data.domain - The targeted domain + * @returns {object} + */ + module.exports.fn = async (data, opts) => { + let timeoutHandle + const timeoutPromise = new Promise((resolve, reject) => { + timeoutHandle = setTimeout( + () => reject(new Error('Request was timed out')), + data.fetcherTimeout ? data.fetcherTimeout : module.exports.timeout + ) + }) -/** - * Execute a fetch request - * @function - * @async - * @param {object} data - Data used in the request - * @param {string} data.domain - The targeted domain - * @returns {object} - */ -module.exports.fn = async (data, opts) => { - let timeoutHandle - const timeoutPromise = new Promise((resolve, reject) => { - timeoutHandle = setTimeout( - () => reject(new Error('Request was timed out')), - data.fetcherTimeout ? data.fetcherTimeout : module.exports.timeout - ) - }) + const fetchPromise = new Promise((resolve, reject) => { + dns.resolveTxt(data.domain, (err, records) => { + if (err) { + reject(err) + return + } - const fetchPromise = new Promise((resolve, reject) => { - dns.resolveTxt(data.domain, (err, records) => { - if (err) { - reject(err) - return - } - - resolve({ - domain: data.domain, - records: { - txt: records, - }, + resolve({ + domain: data.domain, + records: { + txt: records, + }, + }) }) }) - }) - return Promise.race([fetchPromise, timeoutPromise]).then((result) => { - clearTimeout(timeoutHandle) - return result - }) -} + return Promise.race([fetchPromise, timeoutPromise]).then((result) => { + clearTimeout(timeoutHandle) + return result + }) + } +} else { + module.exports.fn = null +} \ No newline at end of file diff --git a/src/fetcher/irc.js b/src/fetcher/irc.js index 7a1f863..49c4138 100644 --- a/src/fetcher/irc.js +++ b/src/fetcher/irc.js @@ -25,71 +25,70 @@ const jsEnv = require("browser-or-node") */ module.exports.timeout = 20000 -if (!jsEnv.isNode) { +if (jsEnv.isNode) { + const irc = require('irc-upd') + const validator = require('validator') + + /** + * Execute a fetch request + * @function + * @async + * @param {object} data - Data used in the request + * @param {string} data.nick - The nick of the targeted account + * @param {string} data.domain - The domain on which the targeted account is registered + * @param {object} opts - Options used to enable the request + * @param {string} opts.claims.irc.nick - The nick to be used by the library to log in + * @returns {object} + */ + module.exports.fn = async (data, opts) => { + let timeoutHandle + const timeoutPromise = new Promise((resolve, reject) => { + timeoutHandle = setTimeout( + () => reject(new Error('Request was timed out')), + data.fetcherTimeout ? data.fetcherTimeout : module.exports.timeout + ) + }) + + const fetchPromise = new Promise((resolve, reject) => { + try { + validator.isAscii(opts.claims.irc.nick) + } catch (err) { + throw new Error(`IRC fetcher was not set up properly (${err.message})`) + } + + try { + const client = new irc.Client(data.domain, opts.claims.irc.nick, { + port: 6697, + secure: true, + channels: [], + }) + const reKey = /[a-zA-Z0-9\-\_]+\s+:\s(openpgp4fpr\:.*)/ + const reEnd = /End\sof\s.*\staxonomy./ + let keys = [] + + client.addListener('registered', (message) => { + client.send(`PRIVMSG NickServ :TAXONOMY ${data.nick}`) + }) + client.addListener('notice', (nick, to, text, message) => { + if (reKey.test(text)) { + const match = text.match(reKey) + keys.push(match[1]) + } + if (reEnd.test(text)) { + client.disconnect() + resolve(keys) + } + }) + } catch (error) { + reject(error) + } + }) + + return Promise.race([fetchPromise, timeoutPromise]).then((result) => { + clearTimeout(timeoutHandle) + return result + }) + } +} else { module.exports.fn = null - return -} - -const irc = require('irc-upd') -const validator = require('validator') - -/** - * Execute a fetch request - * @function - * @async - * @param {object} data - Data used in the request - * @param {string} data.nick - The nick of the targeted account - * @param {string} data.domain - The domain on which the targeted account is registered - * @param {object} opts - Options used to enable the request - * @param {string} opts.claims.irc.nick - The nick to be used by the library to log in - * @returns {object} - */ -module.exports.fn = async (data, opts) => { - let timeoutHandle - const timeoutPromise = new Promise((resolve, reject) => { - timeoutHandle = setTimeout( - () => reject(new Error('Request was timed out')), - data.fetcherTimeout ? data.fetcherTimeout : module.exports.timeout - ) - }) - - const fetchPromise = new Promise((resolve, reject) => { - try { - validator.isAscii(opts.claims.irc.nick) - } catch (err) { - throw new Error(`IRC fetcher was not set up properly (${err.message})`) - } - - try { - const client = new irc.Client(data.domain, opts.claims.irc.nick, { - port: 6697, - secure: true, - channels: [], - }) - const reKey = /[a-zA-Z0-9\-\_]+\s+:\s(openpgp4fpr\:.*)/ - const reEnd = /End\sof\s.*\staxonomy./ - let keys = [] - - client.addListener('registered', (message) => { - client.send(`PRIVMSG NickServ :TAXONOMY ${data.nick}`) - }) - client.addListener('notice', (nick, to, text, message) => { - if (reKey.test(text)) { - const match = text.match(reKey) - keys.push(match[1]) - } - if (reEnd.test(text)) { - client.disconnect() - resolve(keys) - } - }) - } catch (error) { - reject(error) - } - }) - - return Promise.race([fetchPromise, timeoutPromise]).then((result) => { - clearTimeout(timeoutHandle) - return result - }) } diff --git a/src/fetcher/xmpp.js b/src/fetcher/xmpp.js index f75c075..c35e981 100644 --- a/src/fetcher/xmpp.js +++ b/src/fetcher/xmpp.js @@ -25,119 +25,118 @@ const jsEnv = require("browser-or-node") */ module.exports.timeout = 5000 -if (!jsEnv.isNode) { - module.exports.fn = null - return -} - -const jsdom = require('jsdom') -const { client, xml } = require('@xmpp/client') -const debug = require('@xmpp/debug') -const validator = require('validator') - -let xmpp = null, - iqCaller = null - -const xmppStart = async (service, username, password) => { - return new Promise((resolve, reject) => { - const xmpp = client({ - service: service, - username: username, - password: password, - }) - if (process.env.NODE_ENV !== 'production') { - debug(xmpp, true) - } - const { iqCaller } = xmpp - xmpp.start() - xmpp.on('online', (address) => { - resolve({ xmpp: xmpp, iqCaller: iqCaller }) - }) - xmpp.on('error', (error) => { - reject(error) - }) - }) -} - -/** - * Execute a fetch request - * @function - * @async - * @param {object} data - Data used in the request - * @param {string} data.id - The identifier of the targeted account - * @param {string} data.field - The vCard field to return (should be "note") - * @param {object} opts - Options used to enable the request - * @param {string} opts.claims.xmpp.service - The server hostname on which the library can log in - * @param {string} opts.claims.xmpp.username - The username used to log in - * @param {string} opts.claims.xmpp.password - The password used to log in - * @returns {object} - */ -module.exports.fn = async (data, opts) => { - let timeoutHandle - const timeoutPromise = new Promise((resolve, reject) => { - timeoutHandle = setTimeout( - () => reject(new Error('Request was timed out')), - data.fetcherTimeout ? data.fetcherTimeout : module.exports.timeout - ) - }) - - const fetchPromise = new Promise(async (resolve, reject) => { - try { - validator.isFQDN(opts.claims.xmpp.service) - validator.isAscii(opts.claims.xmpp.username) - validator.isAscii(opts.claims.xmpp.password) - } catch (err) { - throw new Error(`XMPP fetcher was not set up properly (${err.message})`) - } - - if (!xmpp || xmpp.status !== 'online') { - const xmppStartRes = await xmppStart( - opts.claims.xmpp.service, - opts.claims.xmpp.username, - opts.claims.xmpp.password - ) - xmpp = xmppStartRes.xmpp - iqCaller = xmppStartRes.iqCaller - } - - const response = await iqCaller.request( - xml('iq', { type: 'get', to: data.id }, xml('vCard', 'vcard-temp')), - 30 * 1000 - ) - - const vcardRow = response.getChild('vCard', 'vcard-temp').toString() - const dom = new jsdom.JSDOM(vcardRow) - - try { - let vcard - - switch (data.field.toLowerCase()) { - case 'desc': - case 'note': - vcard = dom.window.document.querySelector('note text') - if (!vcard) { - vcard = dom.window.document.querySelector('DESC') - } - if (vcard) { - vcard = vcard.textContent - } else { - throw new Error('No DESC or NOTE field found in vCard') - } - break - - default: - vcard = dom.window.document.querySelector(data).textContent - break +if (jsEnv.isNode) { + const jsdom = require('jsdom') + const { client, xml } = require('@xmpp/client') + const debug = require('@xmpp/debug') + const validator = require('validator') + + let xmpp = null, + iqCaller = null + + const xmppStart = async (service, username, password) => { + return new Promise((resolve, reject) => { + const xmpp = client({ + service: service, + username: username, + password: password, + }) + if (process.env.NODE_ENV !== 'production') { + debug(xmpp, true) } - xmpp.stop() - resolve(vcard) - } catch (error) { - reject(error) - } - }) - - return Promise.race([fetchPromise, timeoutPromise]).then((result) => { - clearTimeout(timeoutHandle) - return result - }) + const { iqCaller } = xmpp + xmpp.start() + xmpp.on('online', (address) => { + resolve({ xmpp: xmpp, iqCaller: iqCaller }) + }) + xmpp.on('error', (error) => { + reject(error) + }) + }) + } + + /** + * Execute a fetch request + * @function + * @async + * @param {object} data - Data used in the request + * @param {string} data.id - The identifier of the targeted account + * @param {string} data.field - The vCard field to return (should be "note") + * @param {object} opts - Options used to enable the request + * @param {string} opts.claims.xmpp.service - The server hostname on which the library can log in + * @param {string} opts.claims.xmpp.username - The username used to log in + * @param {string} opts.claims.xmpp.password - The password used to log in + * @returns {object} + */ + module.exports.fn = async (data, opts) => { + let timeoutHandle + const timeoutPromise = new Promise((resolve, reject) => { + timeoutHandle = setTimeout( + () => reject(new Error('Request was timed out')), + data.fetcherTimeout ? data.fetcherTimeout : module.exports.timeout + ) + }) + + const fetchPromise = new Promise(async (resolve, reject) => { + try { + validator.isFQDN(opts.claims.xmpp.service) + validator.isAscii(opts.claims.xmpp.username) + validator.isAscii(opts.claims.xmpp.password) + } catch (err) { + throw new Error(`XMPP fetcher was not set up properly (${err.message})`) + } + + if (!xmpp || xmpp.status !== 'online') { + const xmppStartRes = await xmppStart( + opts.claims.xmpp.service, + opts.claims.xmpp.username, + opts.claims.xmpp.password + ) + xmpp = xmppStartRes.xmpp + iqCaller = xmppStartRes.iqCaller + } + + const response = await iqCaller.request( + xml('iq', { type: 'get', to: data.id }, xml('vCard', 'vcard-temp')), + 30 * 1000 + ) + + const vcardRow = response.getChild('vCard', 'vcard-temp').toString() + const dom = new jsdom.JSDOM(vcardRow) + + try { + let vcard + + switch (data.field.toLowerCase()) { + case 'desc': + case 'note': + vcard = dom.window.document.querySelector('note text') + if (!vcard) { + vcard = dom.window.document.querySelector('DESC') + } + if (vcard) { + vcard = vcard.textContent + } else { + throw new Error('No DESC or NOTE field found in vCard') + } + break + + default: + vcard = dom.window.document.querySelector(data).textContent + break + } + xmpp.stop() + resolve(vcard) + } catch (error) { + reject(error) + } + }) + + return Promise.race([fetchPromise, timeoutPromise]).then((result) => { + clearTimeout(timeoutHandle) + return result + }) + } +} else { + module.exports.fn = null }