From 008277633d501e5a32cd17b37e67e982130c0b3a Mon Sep 17 00:00:00 2001 From: a2937 Date: Fri, 17 Nov 2023 04:59:45 -0500 Subject: [PATCH] feat: add a live check for the twitch proxy (#522) --- apps/twitch-proxy/server.js | 156 ++++++++++++++++++------------------ 1 file changed, 78 insertions(+), 78 deletions(-) diff --git a/apps/twitch-proxy/server.js b/apps/twitch-proxy/server.js index 8159ef44..15eef7d7 100644 --- a/apps/twitch-proxy/server.js +++ b/apps/twitch-proxy/server.js @@ -1,16 +1,16 @@ -const express = require("express"); +const express = require('express'); const app = express(); -const cors = require("cors")(); +const cors = require('cors')(); -const log = require("./utilities/logger"); -const config = require("./config"); +const log = require('./utilities/logger'); +const config = require('./config'); -const outReqLimiter = require("./utilities/outbound-reqs-limiter"); -const blacklist = require("./utilities/blacklist"); -const { validate, validateLegacy } = require("./utilities/req-validate"); +const outReqLimiter = require('./utilities/outbound-reqs-limiter'); +const blacklist = require('./utilities/blacklist'); +const { validate, validateLegacy } = require('./utilities/req-validate'); if (!config.serveStaticData) { - var Datastore = require("@seald-io/nedb"); + var Datastore = require('@seald-io/nedb'); var db = new Datastore({ filename: config.db.dbPath }); db.loadDatabase(); @@ -18,21 +18,21 @@ if (!config.serveStaticData) { db.persistence.setAutocompactionInterval(config.db.compactionMillisecs); } - db.ensureIndex({ fieldName: "query" }, function(err) { - if (err) log.error(err, "unable to set db index"); + db.ensureIndex({ fieldName: 'query' }, function (err) { + if (err) log.error(err, 'unable to set db index'); }); - var dbMware = function(db) { - return function(req, res, next) { + var dbMware = function (db) { + return function (req, res, next) { req.db = db; next(); }; }; - var cacheCheck = function() { + var cacheCheck = function () { var d = Date.now(); var ets = config.db.dataExpirationSecs; - log.info("cache expiration check"); + log.info('cache expiration check'); db.remove( { createdAt: { @@ -48,29 +48,33 @@ if (!config.serveStaticData) { app.use(dbMware(db)); - var request = require("request"); + var request = require('request'); var reqOptions = { - method: "GET", + method: 'GET', headers: { - "Client-ID": config.twitchCID, - "Authorization": `Bearer ${config.accessTOKEN}` + 'Client-ID': config.twitchCID, + Authorization: `Bearer ${config.accessTOKEN}` } }; } -app.enable("trust proxy"); +app.enable('trust proxy'); -app.get("/", function(req, res) { - res.sendFile(__dirname + "/views/index.html"); +app.get('/', function (req, res) { + res.sendFile(__dirname + '/views/index.html'); }); -app.get("/helix/:route", cors, blacklist, validate, function(req, res, next) { - if (config.serveStaticData) return next("route"); +app.get('/status/ping', (req, res) => { + res.status(200).send({ msg: 'pong' }); +}); + +app.get('/helix/:route', cors, blacklist, validate, function (req, res, next) { + if (config.serveStaticData) return next('route'); var route = req.params.route; var qs = req.query; const query = - route + Object.keys(qs).reduce((a, q) => `${a}:${q}=${qs[q]}`, ""); - req.db.findOne({ query }, function(err, dbCache) { + route + Object.keys(qs).reduce((a, q) => `${a}:${q}=${qs[q]}`, ''); + req.db.findOne({ query }, function (err, dbCache) { // if data is cached return it if (err) return next(err); if (dbCache) { @@ -79,11 +83,11 @@ app.get("/helix/:route", cors, blacklist, validate, function(req, res, next) { } else { // get data from twitch api, store and serve it if (outReqLimiter(req)) - return next({ status: 429, message: "outbound rate limiter" }); + return next({ status: 429, message: 'outbound rate limiter' }); reqOptions.url = `${config.baseApiUrl}/helix/${route}`; reqOptions.qs = qs; - request(reqOptions, function(err, response, body) { + request(reqOptions, function (err, response, body) { if (err) return next(err); log.info(`${query} - new - "${req.headers.referer}" - ${req.ip}`); var cacheItem = { @@ -94,7 +98,7 @@ app.get("/helix/:route", cors, blacklist, validate, function(req, res, next) { createdAt: Date.now() }; - req.db.insert(cacheItem, function(err) { + req.db.insert(cacheItem, function (err) { if (err) return next(err); res.json(cacheItem.data); }); @@ -103,8 +107,8 @@ app.get("/helix/:route", cors, blacklist, validate, function(req, res, next) { }); }); -const staticHandler = require("./utilities/static-data-handler"); -app.get("/helix/:route", cors, blacklist, validate, function(req, res, next) { +const staticHandler = require('./utilities/static-data-handler'); +app.get('/helix/:route', cors, blacklist, validate, function (req, res, next) { const { params: { route }, query, @@ -112,7 +116,7 @@ app.get("/helix/:route", cors, blacklist, validate, function(req, res, next) { ip } = req; const _q = - route + Object.keys(query).reduce((a, q) => `${a}:${q}=${query[q]}`, ""); + route + Object.keys(query).reduce((a, q) => `${a}:${q}=${query[q]}`, ''); log.info(`${_q} - static - "${referer}" - ${ip}`); const data = staticHandler(route, query); if (data) { @@ -131,84 +135,80 @@ const sendData = (req, res, data, err) => { res.status(stat).json(err || data); } }; -const getLegacyAPIDAta = require("./utilities/legacy-data-handler"); -app.get("/twitch-api/:type/:name", blacklist, cors, validateLegacy, function( - req, - res, - next -) { - const { - params: { type, name }, - headers: { referer }, - ip - } = req; - log.info(`${type}/${name} - static (kraken) - "${referer}" - ${ip}`); - - var data = getLegacyAPIDAta(req.params.type, req.params.name); - - if (data) { - setTimeout(() => sendData(req, res, data), 1000); - } else { - log.warn( - `${type}/${name} - static (kraken) not found - "${referer}" - ${ip}` - ); - next(); +const getLegacyAPIDAta = require('./utilities/legacy-data-handler'); +app.get( + '/twitch-api/:type/:name', + blacklist, + cors, + validateLegacy, + function (req, res, next) { + const { + params: { type, name }, + headers: { referer }, + ip + } = req; + log.info(`${type}/${name} - static (kraken) - "${referer}" - ${ip}`); + + var data = getLegacyAPIDAta(req.params.type, req.params.name); + + if (data) { + setTimeout(() => sendData(req, res, data), 1000); + } else { + log.warn( + `${type}/${name} - static (kraken) not found - "${referer}" - ${ip}` + ); + next(); + } } -}); +); -var fs = require("fs"); -app.get("/reset-db", function(req, res, next) { +var fs = require('fs'); +app.get('/reset-db', function (req, res, next) { if (process.env.ADMIN_PWD && req.query.pwd === process.env.ADMIN_PWD) { try { - fs.unlinkSync(__dirname + "/.data/db"); + fs.unlinkSync(__dirname + '/.data/db'); } catch (e) { return next(e); } - res.type("txt").send("OK"); + res.type('txt').send('OK'); } else { - res - .type("txt") - .status(401) - .send("Unauthorized"); + res.type('txt').status(401).send('Unauthorized'); } }); const { updateStaticData, updateLegacyStaticData -} = require("./static-data/update"); -app.get("/update-static", async (req, res, next) => { +} = require('./static-data/update'); +app.get('/update-static', async (req, res, next) => { const { pwd, type } = req.query; if (process.env.ADMIN_PWD && pwd === process.env.ADMIN_PWD) { - const isLegacy = type === "legacy"; + const isLegacy = type === 'legacy'; let _update = isLegacy ? updateLegacyStaticData : updateStaticData; - log.info(`updating static data${isLegacy ? " (legacy)" : ""}...`); + log.info(`updating static data${isLegacy ? ' (legacy)' : ''}...`); try { await _update(); - log.info(`update static data${isLegacy ? " (legacy)" : ""} OK`); - res.type("text").send("OK"); + log.info(`update static data${isLegacy ? ' (legacy)' : ''} OK`); + res.type('text').send('OK'); } catch (err) { return next(err); } } else { - res - .type("txt") - .status(401) - .send("Unauthorized"); + res.type('txt').status(401).send('Unauthorized'); } }); -app.use(function(req, res) { - sendData(req, res, null, { status: 404, error: "not found" }); +app.use(function (req, res) { + sendData(req, res, null, { status: 404, error: 'not found' }); }); -app.use(function(err, req, res) { +app.use(function (err, req, res) { log.error(`!! ${err.message || err.msg || err.error}`); err.status = err.status || 500; - err.error = err.error || "internal server error"; + err.error = err.error || 'internal server error'; sendData(req, res, null, err); }); -app.listen(config.port, function() { - log.info("fcc twitch proxy listening on port " + config.port); +app.listen(config.port, function () { + log.info('fcc twitch proxy listening on port ' + config.port); });