require('dotenv').config() const express = require('express') const app = express() const port = 8080 app.set('trust proxy', true) const database = require('./src/database.js') const rateLimiter = require('express-rate-limit') const limiter = (min, count) => { return rateLimiter({ windowMs: min * 60 * 1000, max: count, message: 'Too many requests, please try again later.', standardHeaders: true, legacyHeaders: false, }) } const cookieParser = require('cookie-parser') app.use(cookieParser()) app.use(express.json()); app.use(express.static('public')) app.use((req, res, next) => { const public = { ... req.body } if (public.password !== undefined) { public.password = '********' } console.log(req.ip, req.method, req.path, public) update(req.ip, req.method, req.path, public) next() }) app.get('/', (req, res) => { const cookies = req.cookies; if (cookies === undefined || cookies.auth === undefined) { res.redirect('/login') return } const user = database.auth(req.cookies.auth) if (user === undefined) { res.redirect('/login') return } res.redirect('/home') }) app.get('/login', (req, res) => { const cookies = req.cookies; if (cookies === undefined || cookies.auth === undefined) { res.sendFile('login.html', { root: './public' }) return } const user = database.auth(req.cookies.auth) if (user === undefined) { res.sendFile('login.html', { root: './public' }) return } res.redirect('/home') }) app.get('/home', (req, res) => { const cookies = req.cookies; if (cookies === undefined || cookies.auth === undefined) { res.redirect('/login') return } const user = database.auth(req.cookies.auth) if (user === undefined) { res.redirect('/login') return } res.sendFile('home.html', { root: './public' }) }) app.get('/people', (req, res) => { res.sendFile('people.html', { root: './public' }) }) app.get('/profile', (req, res) => { res.sendFile('profile.html', { root: './public' }) }) const api = require('./src/api.js') app.use('/api', api); const connections = [] app.get('/console', (req, res) => { res.write(` XSSBook - Console `) connections.push(res) }) function color(method) { switch(method) { case 'GET': return '4ae04a' case 'POST': return 'b946db' case 'PUT': return 'ff9705' case 'PATCH': return `42caff` case 'DELETE': return `ff4a4a` case 'HEAD': return '424cff' case 'OPTIONS': return 'ff9757' } } function highlight(json) { if (typeof json != 'string') { json = JSON.stringify(json, undefined, 2); } json = json.replace(/&/g, '&').replace(//g, '>'); return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) { var cls = 'number'; if (/^"/.test(match)) { if (/:$/.test(match)) { cls = 'key'; } else { cls = 'string'; } } else if (/true|false/.test(match)) { cls = 'boolean'; } else if (/null/.test(match)) { cls = 'null'; } return '' + match + ''; }); } async function update(ip, method, path, json) { connections.forEach(con => { con.write(`
${ip} ${method} ${path} ${highlight(json)}
`) }) } // app.use('/api', limiter(1,60)) // app.use('/api/register', limiter(60, 5)) // app.use('/api/login', limiter(10, 5)) app.use((req, res, next) => { res.status(404).sendFile('404.html', { root: './public' }) }) app.use((err, req, res, next) => { if (err instanceof SyntaxError && err.status === 400 && 'body' in err) { res.status(400).send({msg: 'Invalid json body'}) return } console.error(err) res.status(500).send({msg: 'Internal server error'}) }) app.listen(port, () => { console.log(`App listening on port http://127.0.0.1:${port}`) })