Switch to fetcher

This commit is contained in:
Yarmo Mackenbach 2021-03-25 16:43:21 +01:00
parent 0bc97bd902
commit 28582999eb
No known key found for this signature in database
GPG key ID: 37367F4AF4087AD1

View file

@ -14,14 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
const router = require('express').Router() const router = require('express').Router()
const dns = require('dns') const fetcher = require('../../../fetcher')
const bent = require('bent')
const bentReq = bent('GET')
const validUrl = require('valid-url')
const jsdom = require('jsdom')
const { client, xml } = require('@xmpp/client')
const debug = require('@xmpp/debug')
const irc = require("irc-upd")
require('dotenv').config() require('dotenv').config()
const xmpp_service = process.env.XMPP_SERVICE || null const xmpp_service = process.env.XMPP_SERVICE || null
@ -32,9 +25,7 @@ const matrix_instance = process.env.MATRIX_INSTANCE || null
const matrix_access_token = process.env.MATRIX_ACCESS_TOKEN || null const matrix_access_token = process.env.MATRIX_ACCESS_TOKEN || null
const irc_nick = process.env.IRC_NICK || null const irc_nick = process.env.IRC_NICK || null
let xmpp = null, let xmpp_enabled = true,
iqCaller = null,
xmpp_enabled = true,
twitter_enabled = false, twitter_enabled = false,
matrix_enabled = false, matrix_enabled = false,
irc_enabled = false irc_enabled = false
@ -52,31 +43,12 @@ if (irc_nick) {
irc_enabled = true irc_enabled = true
} }
const xmppStart = async (xmpp_service, xmpp_username, xmpp_password) => {
return new Promise((resolve, reject) => {
const xmpp = client({
service: xmpp_service,
username: xmpp_username,
password: xmpp_password,
})
if (process.env.NODE_ENV !== 'production') {
debug(xmpp, true)
}
const { iqCaller } = xmpp
xmpp.start()
xmpp.on('online', (address) => {
console.log('online', address.toString())
resolve({ xmpp: xmpp, iqCaller: iqCaller })
})
xmpp.on('error', (error) => {
reject(error)
})
})
}
router.get('/', async (req, res) => { router.get('/', async (req, res) => {
res.status(200).json({ return res
message: .status(400)
.json({
data: [],
error:
'Available endpoints: /json/:url, /text/:url, /dns/:hostname, /xmpp/:xmppid, /twitter/:tweetid, /matrix/:roomid/:eventid, /irc/:ircserver/:ircnick', 'Available endpoints: /json/:url, /text/:url, /dns/:hostname, /xmpp/:xmppid, /twitter/:tweetid, /matrix/:roomid/:eventid, /irc/:ircserver/:ircnick',
}) })
}) })
@ -85,7 +57,9 @@ router.param('url', async (req, res, next, url) => {
req.params.url = decodeURI(url) req.params.url = decodeURI(url)
if (!validUrl.isUri(req.params.url)) { if (!validUrl.isUri(req.params.url)) {
return res.status(400).send({ message: 'URL provided was not valid' }) return res
.status(400)
.json({ data: [], error: 'URL provided was not valid' })
} }
next() next()
@ -97,7 +71,7 @@ router.param('xmppid', async (req, res, next, xmppid) => {
if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,})+$/.test(req.params.xmppid)) { if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,})+$/.test(req.params.xmppid)) {
next() next()
} else { } else {
return res.status(400).json({ message: 'XMPP_ID was not valid' }) return res.status(400).json({ data: [], error: 'XMPP_ID was not valid' })
} }
}) })
@ -116,8 +90,11 @@ router.param('xmppdata', async (req, res, next, xmppdata) => {
] ]
if (!allowedData.includes(req.params.xmppdata)) { if (!allowedData.includes(req.params.xmppdata)) {
return res.status(400).json({ return res
message: .status(400)
.send({
data: [],
error:
'Allowed data are: FN, NUMBER, USERID, URL, BDAY, NICKNAME, NOTE, DESC', 'Allowed data are: FN, NUMBER, USERID, URL, BDAY, NICKNAME, NOTE, DESC',
}) })
} }
@ -133,10 +110,10 @@ router.get('/get/json/:url', (req, res) => {
return await result.json() return await result.json()
}) })
.then(async (result) => { .then(async (result) => {
return res.status(200).json({ url: req.params.url, content: result }) return res.status(200).json({ data: result, error: [] })
}) })
.catch((e) => { .catch((err) => {
return res.status(400).send({ error: e }) return res.status(400).send({ data: [], error: err })
}) })
}) })
@ -146,159 +123,113 @@ router.get('/get/text/:url', (req, res) => {
return await result.text() return await result.text()
}) })
.then(async (result) => { .then(async (result) => {
return res.status(200).json({ url: req.params.url, content: result }) return res.status(200).json({ data: result, error: [] })
}) })
.catch((e) => { .catch((err) => {
return res.status(400).send({ error: e }) return res.status(400).send({ data: [], error: err })
}) })
}) })
router.get('/get/dns/:hostname', async (req, res) => { router.get('/get/dns/:hostname', (req, res) => {
dns.resolveTxt(req.params.hostname, (err, records) => { fetcher
const out = { .dns(req.params.hostname)
hostname: req.params.hostname, .then((data) => {
records: { return res.status(200).json({ data: data, error: [] })
txt: records, })
}, .catch((err) => {
} return res.status(400).json({ data: [], error: err })
return res.status(200).json(out)
}) })
}) })
router.get('/get/xmpp/:xmppid', async (req, res) => { router.get('/get/xmpp/:xmppid', async (req, res) => {
return res return res
.status(400) .status(400)
.json( .send({
'Data request parameter missing (FN, NUMBER, USERID, URL, BDAY, NICKNAME, NOTE, DESC)' data: [],
) error:
'Data request parameter missing (FN, NUMBER, USERID, URL, BDAY, NICKNAME, NOTE, DESC)',
})
}) })
router.get('/get/xmpp/:xmppid/:xmppdata', async (req, res) => { router.get('/get/xmpp/:xmppid/:xmppdata', async (req, res) => {
if (!xmpp_enabled) { if (!xmpp_enabled) {
return res.status(500).json('XMPP not enabled on server') return res
} .status(501)
if (!xmpp) { .json({ data: [], error: 'XMPP not enabled on server' })
const xmppStartRes = await xmppStart(
xmpp_service,
xmpp_username,
xmpp_password
)
xmpp = xmppStartRes.xmpp
iqCaller = xmppStartRes.iqCaller
} }
const response = await iqCaller.request( fetcher
xml( .xmpp(req.params.xmppid, req.params.xmppdata, {
'iq', service: xmpp_service,
{ type: 'get', to: req.params.xmppid }, username: xmpp_username,
xml('vCard', 'vcard-temp') password: xmpp_password,
), })
30 * 1000 .then((data) => {
) return res.status(200).json({ data: data, error: [] })
})
const vcardRow = response.getChild('vCard', 'vcard-temp').toString() .catch((err) => {
return res
const dom = new jsdom.JSDOM(vcardRow) .status(400)
.json({ data: [], error: err.message ? err.message : err })
try { })
let vcard
switch (req.params.xmppdata.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(req.params.xmppdata).textContent
break
}
return res.status(200).json(vcard)
} catch (error) {
return res.status(400).json({ message: 'Request could not be fulfilled', error: error })
}
}) })
router.get('/get/twitter/:tweetid', async (req, res) => { router.get('/get/twitter/:tweetid', async (req, res) => {
if (!twitter_enabled) { if (!twitter_enabled) {
return res.status(500).json('Twitter not enabled on server') return res
.status(501)
.json({ data: [], error: 'Twitter not enabled on server' })
} }
bentReq(`https://api.twitter.com/1.1/statuses/show.json?id=${req.params.tweetid}`, null, { fetcher
Accept: 'application/json', .twitter(req.params.tweetid, {
Authorization: `Bearer ${twitter_bearer_token}` bearerToken: twitter_bearer_token,
})
.then(async (data) => {
return await data.json()
}) })
.then((data) => { .then((data) => {
return res.status(200).json({ data: data, message: 'Success', error: {} }) return res.status(200).json({ data: data, error: [] })
}) })
.catch((error) => { .catch((err) => {
return res.status(error.statusCode || 400).json({ data: [], message: 'Request could not be fulfilled', error: error }) return res.status(400).json({ data: [], error: err })
}) })
}) })
router.get('/get/matrix/:matrixroomid/:matrixeventid', async (req, res) => { router.get('/get/matrix/:matrixroomid/:matrixeventid', async (req, res) => {
if (!matrix_enabled) { if (!matrix_enabled) {
return res.status(500).json('Matrix not enabled on server') return res
.status(501)
.json({ data: [], error: 'Matrix not enabled on server' })
} }
const url = `https://${matrix_instance}/_matrix/client/r0/rooms/${req.params.matrixroomid}/event/${req.params.matrixeventid}?access_token=${matrix_access_token}` fetcher
.matrix(req.params.matrixroomid, req.params.matrixeventid, {
bentReq(url, null, { instance: process.env.MATRIX_INSTANCE,
Accept: 'application/json' accessToken: process.env.MATRIX_ACCESS_TOKEN,
})
.then(async (data) => {
return await data.json()
}) })
.then((data) => { .then((data) => {
return res.status(200).json({ data: data, message: 'Success', error: {} }) return res.status(200).json({ data: data, error: [] })
}) })
.catch((error) => { .catch((err) => {
return res.status(error.statusCode || 400).json({ data: [], message: 'Request could not be fulfilled', error: error }) return res.status(400).json({ data: [], error: err })
}) })
}) })
router.get('/get/irc/:ircserver/:ircnick', async (req, res) => { router.get('/get/irc/:ircserver/:ircnick', async (req, res) => {
if (!irc_enabled) { if (!irc_enabled) {
return res.status(500).json('IRC not enabled on server') return res
.status(501)
.json({ data: [], error: 'IRC not enabled on server' })
} }
try { fetcher
const client = new irc.Client(req.params.ircserver, irc_nick, { .irc(req.params.ircserver, req.params.ircnick, {
port: 6697, nick: 'doipver148927',
secure: true,
channels: [],
}) })
const reKey = /[a-zA-Z0-9\-\_]+\s+:\s(openpgp4fpr\:.*)/ .then((data) => {
const reEnd = /End\sof\s.*\staxonomy./ return res.status(200).json({ data: data, error: [] })
let keys = []
client.addListener('registered', (message) => {
client.send(`PRIVMSG NickServ :TAXONOMY ${req.params.ircnick}`)
}) })
client.addListener('notice', (nick, to, text, message) => { .catch((err) => {
if (reKey.test(text)) { return res.status(400).json({ data: [], error: err })
const match = text.match(reKey)
keys.push(match[1]);
}
if (reEnd.test(text)) {
client.disconnect()
return res.status(200).json({ data: keys, message: 'Success', error: {} })
}
}) })
} catch (error) {
return res.status(400).json({ data: [], message: 'Request could not be fulfilled', error: error })
}
}) })
module.exports = router module.exports = router