/* ---------------------------------------------------------------------------- Question Server GitLab: This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ------------------------------------------------------------------------- */ // package requires import express, { RequestHandler } from 'express' import type { Database } from 'better-sqlite3' const app = express() // other requires import utils from '../../utils/utils' import logger from '../../utils/logger' import auth from '../../middlewares/auth.middleware' import { SetupData } from '../../server' import { ModuleType, Request } from '../../types/basicTypes' import { LinksSchema, validateJSON } from '../../types/typeSchemas' // stuff gotten from server.js let publicdirs: string[] = [] let userDB: Database let nextdir = '' function GetApp(): ModuleType { app.use( express.urlencoded({ limit: '5mb', extended: true, }) as RequestHandler ) app.use( express.json({ limit: '5mb', }) as RequestHandler ) app.set('view engine', 'ejs') app.set('views', ['./src/modules/qmining/views', './src/sharedViews']) app.use( auth({ userDB: userDB, exceptions: [ '/favicon.ico', '/img/frylabs-logo_large_transparent.png', '/api/register', '/api/login', '/api/postfeedback', '/api/fosuploader', '/api/badtestsender', ], }) ) app.use((req: Request, _res, next) => { const url = req.url.split('?')[0] if (url.includes('.html') || url === '/') { logger.LogReq(req) } next() }) publicdirs.forEach((pdir) => { app.use(express.static(pdir)) }) app.use(express.static(nextdir)) const linksFile = 'data/links.json' let links: { [key: string]: string } = {} function loadDonateURL() { try { if (utils.FileExists(linksFile)) { links = utils.ReadJSON(linksFile) const { isValid, errorMsg } = validateJSON(links, LinksSchema) if (!isValid) { logger.Log( `Peers file (${linksFile}) has invalid contents!`, 'redbg' ) errorMsg.forEach((x) => logger.Log(x, 'red')) } } } catch (err) { logger.Log('Couldnt read donate URL file!', logger.GetColor('red')) console.error(err) } } loadDonateURL() if (utils.FileExists(linksFile)) { utils.WatchFile(linksFile, (newData: string) => { logger.Log(`Donate URL changed: ${newData.replace(/\/n/g, '')}`) loadDonateURL() }) } else { logger.Log( `Couldnt read links file! (${linksFile})`, logger.GetColor('redbg') ) } // -------------------------------------------------------------- // REDIRECTS // -------------------------------------------------------------- // to be backwards compatible app.get('/ask', function (req: Request, res) { logger.DebugLog(`Qmining module ask redirect`, 'ask', 1) res.redirect( `http://api.frylabs.net/ask?q=${req.query.q}&subj=${req.query.subj}&data=${req.query.data}` ) }) const simpleRedirects = [ { from: '/dataeditor', to: 'https://dataeditor.frylabs.net', }, { from: '/install', to: 'https://qmining.frylabs.net/moodle-test-userscript/stable.user.js', }, { from: '/servergit', to: 'https://gitlab.com/MrFry/mrfrys-node-server', }, { from: '/scriptgit', to: 'https://gitlab.com/MrFry/moodle-test-userscript', }, { from: '/qminingSite', to: 'https://gitlab.com/MrFry/qmining-page', }, { from: '/classesgit', to: 'https://gitlab.com/MrFry/question-classes', }, { from: '/addQuestion', to: 'https://dataeditor.frylabs.net', }, { from: '/donate', to: links.donate, }, { from: '/menuClick', to: '/', }, { from: '/legacy', to: '/allQuestions.html', }, { from: '/subjectBrowser', to: '/allQuestions.html', }, { from: '/lred', to: '/allQuestions', }, { from: '/allqr', to: 'https://api.frylabs.net/allqr.txt', }, { from: '/allqr.txt', to: 'https://api.frylabs.net/allqr.txt', }, { from: '/infos', to: 'https://api.frylabs.net/infos?version=true&motd=true&subjinfo=true', nolog: true, }, { from: '/irc', to: '/chat', }, { from: '/patreon', to: links.patreon, }, ] simpleRedirects.forEach((redirect) => { app.get(redirect.from, function (req: Request, res) { if (!redirect.nolog) { logger.LogReq(req) } logger.DebugLog( `Qmining module ${redirect.from} redirect`, 'infos', 1 ) let target = redirect.to if (!redirect.to.includes('https://')) { target += utils.formatUrl({ query: req.query }) } res.redirect(target) }) }) // -------------------------------------------------------------- function AddHtmlRoutes(files: string[]) { const routes = files.reduce((acc, file) => { if (file.includes('html')) { acc.push(file.split('.')[0]) return acc } return acc }, []) routes.forEach((route: string) => { logger.DebugLog(`Added route /${route}`, 'Qmining routes', 1) app.get(`/${route}`, function (req: Request, res) { res.redirect( utils.formatUrl({ pathname: `${route}.html`, query: req.query, }) ) }) }) } AddHtmlRoutes(utils.ReadDir(nextdir)) // -------------------------------------------------------------- app.get('/', function (req: Request, res) { res.end('hai') logger.LogReq(req) }) return { app: app, } } export default { name: 'Qmining', getApp: GetApp, setup: (data: SetupData): void => { userDB = data.userDB publicdirs = data.publicdirs nextdir = data.nextdir }, }