const express = require('express') const app = express() const helmet = require('helmet') const bp = require('body-parser') const cookieParser = require('cookie-parser') const createDOMPurify = require('dompurify') const { JSDOM } = require('jsdom') const Controller = require('./source/controller') const readfile = require('./source/readfile') const session = require('./source/session') const logger = require('./source/logger')() const blog = require('./source/blog') const mime = { html: 'text/html', txt: 'text/plain', css: 'text/css', gif: 'image/gif', jpg: 'image/jpeg', png: 'image/png', webp: 'image/webp', avif: 'image/avif', ico: 'image/ico', svg: 'image/svg+xml', js: 'application/javascript' } require('dotenv').config() // Handles the routes class App { constructor() { this.readfile = new readfile({baseUrl: process.env.baseUrl, mime: mime}) this.controller = new Controller() } App() { app.use(bp.json()) app.use(cookieParser()) if (process.env.NODE_ENV === 'prod') {app.use(helmet())} app.get('/js/*', this.#Logger, (req, res) => { const data = this.readfile.GetFile(req.path) data.mime.then(output => this.#FileOpen({data: data, mime: output, res: res})) }) app.get('/css/*', this.#Logger, (req, res) => { const data = this.readfile.GetFile(req.path) data.mime.then(output => this.#FileOpen({data: data, mime: output, res: res})) }) app.get('/img/*', this.#Logger, (req, res) => { const data = this.readfile.GetFile(req.path) data.mime.then(output => this.#FileOpen({data: data, mime: output, res: res})) }) app.route('*') .get(this.#ValidateCookie, this.#Logger, (req, res) => { this.controller.Main().then(output => { this.path = { split: req.path.split('/'), string: req.path } switch (this.path.split[1]) { case 'favicon.ico': this.data = this.readfile.GetFavicon() this.data.mime.then(output => this.#FileOpen({data: this.data, mime: output, res: res})) break case 'robots.txt': console.log('hit') this.data = this.readfile.GetRobots() this.data.mime.then(output => this.#FileOpen({data: this.data, mime: output, res: res})) break default: if (this.path.string.endsWith('/') && this.path.string.length > 1) this.path.string = this.path.string.substring(0, this.path.string.length - 1) if (output.has(this.path.string)) {res.send(this.readfile.GetMain())} else {res.sendStatus(404)} break } }) }) .post(this.#Logger, (req, res) => { this.path = { split: req.path.split('/'), string: this.#RemoveBaseUrl(req.body.url) } if (this.path.string.endsWith('/') && this.path.string.length > 1) this.path.string = this.path.string.substring(0, this.path.string.length - 1) this.controller.Main(req.body.value).then(output => { if (output.has(this.path.string)) { const data = this.readfile.Create(output.get(this.path.string)) data.then(output => { try { const window = new JSDOM('').window const DOMPurify = createDOMPurify(window) const clean = DOMPurify.sanitize(output.layouts.header + output.layouts.data + output.layouts.footer) res.send(clean) //res.send(output.layouts.header + output.layouts.data + output.layouts.footer) } catch (err) { logger.Error(err) res.send('Not Found') } }) } else { res.send('Not Found') } }) }) app.listen(3000) } #Logger(req, res, next) { const { cookies } = req try { logger.Info(`${req.method} ${req.path} from ${req.ip}:${cookies.session_id.replace('session_id', '')}`) } catch (err) { logger.Info(`${req.method} ${req.path} from ${req.ip}:n/a`) } next() } #FileOpen(x) { x.res.set('Content-Type', x.mime) x.data.file.on('open', () => x.data.file.pipe(x.res)).on('error', () => x.res.sendStatus(404)) } #ValidateCookie(req, res, next) { const { cookies } = req session().Expired() if ('session_id' in cookies) { if (session().Exists(cookies.session_id.replace('session_id', ''))) { res.clearCookie('session_id') res.cookie('session_id', session().Create()) } } else res.cookie('session_id', session().Create()) next() } #RemoveBaseUrl(x) { const object = { baseUrlPattern: /^https?:\/\/[a-z\:0-9.]+/, result: '', url: '' } const match = object.baseUrlPattern.exec(x) if (match !== null) object.result = match[0] if (object.result.length > 0) object.result = match[0] if (object.result.length > 0) object.url = x.replace(object.result, '') return object.url } } new App().App()