summaryrefslogtreecommitdiff
path: root/app.js
diff options
context:
space:
mode:
authorMhykol <mchaeldonald62@pm.me>2026-01-08 07:23:16 -0500
committerMhykol <mchaeldonald62@pm.me>2026-01-08 07:23:16 -0500
commitf4f49cd244d2f840cbb79a9286973b5c98d4f534 (patch)
tree2d7b7111d0f998ee72a8cd0106d4609a254a125c /app.js
Initial Commit
Diffstat (limited to 'app.js')
-rw-r--r--app.js234
1 files changed, 234 insertions, 0 deletions
diff --git a/app.js b/app.js
new file mode 100644
index 0000000..f6a6122
--- /dev/null
+++ b/app.js
@@ -0,0 +1,234 @@
+const express = require('express')
+const app = express()
+const rateLimit = require('express-rate-limit')
+const helmet = require('helmet')
+const bp = require('body-parser')
+const cookieParser = require('cookie-parser')
+const fs = require('fs')
+const path = require('path')
+const { readdirSync } = require('fs')
+const session = require('./src/session')()
+const routesConfig = require('./config/routes')
+const mime = {
+ html: 'text/html',
+ txt: 'text/plain',
+ css: 'text/css',
+ xml: 'text/xml',
+ 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',
+ mp4: 'video/mp4',
+ webm: 'video/webm',
+ ttf: 'application/x-font-truetype',
+ ttc: 'application/x-font-truetype',
+ otf: 'application/x-font-otf',
+ ots: 'application/x-font-otf',
+ woff: 'application/font-woff',
+ woff2: 'application/font-woff',
+ pfb: 'application/vnd.ms-fontbook',
+ pfm: 'application/vnd.ms-fontbook',
+ gsf: 'application/vnd.ms-fontbook',
+ swf: 'application/vnd.ms-fontbook'
+}
+const assetDir = () => {
+ return readdirSync(`${__dirname}/assets`, { withFileTypes: true })
+ .filter(dir => dir.isDirectory())
+ .map(dir => dir.name)
+}
+
+/*
+const limiter = rateLimit({
+ windowMS: 30 * 1000,
+ max: 100,
+ message: '<h1>Rate Limit Exceeded</h1><p>You have exceeded the allowed number of requests. Please try again later.</p>'
+})
+*/
+
+require('dotenv').config()
+const sitemap = require('./src/sitemap')
+const logger = require('./src/logger')({
+ baseURL: process.env.baseURL
+})
+const controller = require('./src/controller')({
+ baseURL: process.env.baseURL
+})
+
+const createLog = (req, res, next) => {
+ const { cookies } = req
+ const object = {
+ queryString: '',
+ exists: false
+ }
+
+ Object.entries(req.query).forEach(([key, value]) => {
+ if (object.exists === false) {
+ object.queryString += '?'
+ }
+ object.queryString += `${key}=${value}&`
+ object.exists = true
+ })
+
+ if (object.exists) object.queryString = object.queryString.slice(0, -1)
+
+ logger.Info(`${req.method} ${req.path}${object.queryString} from ${req.ip}:${cookies.session_id ? cookies.session_id.replace('session_id', '') : 'n/a'}`)
+ next()
+}
+const validateCookie = (req, res, next) => {
+ const { cookies } = req
+ if (cookies === undefined) {
+ res.cookie('session_id', session.Create())
+ } else {
+ if ('session_id' in cookies) {
+ if (session.Exists(cookies.session_id.replace('session_id', ''))) {
+ session.Expired()
+ } else {
+ res.clearCookie('session_id')
+ res.cookie('session_id', session.Create())
+ }
+ } else res.cookie('session_id', session.Create())
+ }
+ next()
+}
+
+const openFile = x => {
+ const data = {
+ path: x.filePath.split('/'),
+ exists: false,
+ data: {}
+ }
+
+ if (assetDir().includes(data.path[1])) {
+ this.path = `${__dirname}/assets/${data.path[1]}/${data.path[2]}`
+ data.exists = fs.existsSync(this.path)
+ data.data.mime = mime[path.extname(this.path).slice(1)] || 'text/plain'
+ data.data.file = fs.createReadStream(this.path)
+ .on('error', (err) => {
+ return
+ })
+ } else if (data.path[1] === 'favicon.ico' && (data.path.length === 2 || (data.path.length === 3 && data.path[2] === ''))) {
+ data.data.file = fs.createReadStream(`${__dirname}/config/favicon.ico`)
+ .on('error', (err) => {
+ logger.Error(`'favicon.ico' does not exist. Please add it to the config.`)
+ })
+ }
+
+ if (data.exists) {
+ x.res.set('Content-Type', data.data.mime)
+ data.data.file
+ .on('open', () => {
+ data.data.file.pipe(x.res)
+ })
+ .on('error', err => {
+ logger.Error(err)
+ })
+ } else {
+ x.res.set('Content-Type', mime.html)
+ x.res.status(404).send('File not found.')
+ }
+}
+
+app.use(bp.json())
+app.use(cookieParser())
+
+app.use((req, res, next) => {
+ let err = null
+ try {
+ decodeURIComponent(req.path)
+ } catch (e) {
+ err = e
+ }
+
+ if (err) {
+ return res.redirect(['http://', req.get('Host'), '/404'].join(''))
+ }
+ next()
+})
+
+const handleRoutes = (req, res, next) => {
+ this.path = {
+ split: req.path.split('/'),
+ string: req.path
+ }
+ if(routes.has(this.path.string)) {
+ const route = routes.get(this.path.string)
+ if (route.req === req.method) {
+ res.send(route.method())
+ } else {
+ next()
+ }
+ } else {
+ next()
+ }
+}
+
+const routes = routesConfig({
+ app: app,
+ validateCookie: validateCookie,
+ log: createLog,
+ mime: mime,
+ session: session
+})
+app.route(/(.*)/)
+ .get(validateCookie, createLog, (req, res) => {
+ this.path = {
+ split: req.path.split('/'),
+ string: req.path
+ }
+
+ if (assetDir().includes(this.path.split[1])) {
+ openFile({
+ filePath: this.path.string,
+ res: res
+ })
+ } else {
+ switch (this.path.split[1]) {
+ case 'favicon.ico':
+ openFile({
+ filePath: this.path.string,
+ res: res
+ })
+ break
+ case 'sitemap.xml':
+ const data = sitemap({baseURL: process.env.baseURL})
+ data.Sitemap().then(output => {
+ res.send(output)
+ })
+ break
+ case 'rss':
+ rss({
+ baseURL: process.env.baseURL
+ })
+ break
+ case 'deverror':
+ break
+ default:
+ const response = controller.Init({
+ req: req,
+ res: res,
+ path: this.path.string,
+ baseURL: process.env.baseURL
+ })
+
+ res.send(response)
+ break
+ }
+ }
+ })
+ .post(createLog, (req, res) => {})
+ .put(createLog, (req, res) => {})
+ .delete(createLog, (req, res) => {})
+ .patch(createLog, (req, res) => {})
+ .all(createLog, (req, res) => {
+ res.set('Content-Type', mime.html)
+ res.status(404).send('You are not allowed to access this resource')
+ })
+
+app.listen(process.env.PORT, () => {
+ logger.Info(`Listening on: ${process.env.baseURL}`)
+})
+