console
This commit is contained in:
parent
7f1a57d1a6
commit
23eb8b16b6
2 changed files with 89 additions and 94 deletions
102
index.js
102
index.js
|
@ -1,37 +1,24 @@
|
||||||
require('dotenv').config()
|
|
||||||
|
|
||||||
const express = require('express')
|
const express = require('express')
|
||||||
|
const cookie = require('cookie-parser')
|
||||||
const app = express()
|
const app = express()
|
||||||
const port = 8080
|
const port = 8080
|
||||||
|
|
||||||
app.set('trust proxy', true)
|
app.set('trust proxy', true)
|
||||||
|
app.use(cookie())
|
||||||
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.json());
|
||||||
app.use(express.static('public'))
|
app.use(express.static('public'))
|
||||||
|
|
||||||
|
const database = require('./src/database.js')
|
||||||
|
const con = require('./src/console.js')
|
||||||
|
const api = require('./src/api.js')
|
||||||
|
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
const public = { ... req.body }
|
const public = { ... req.body }
|
||||||
if (public.password !== undefined) {
|
if (public.password !== undefined) {
|
||||||
public.password = '********'
|
public.password = '********'
|
||||||
}
|
}
|
||||||
console.log(req.ip, req.method, req.path, public)
|
console.log(req.ip, req.method, req.path, public)
|
||||||
update(req.ip, req.method, req.path, public)
|
con.update(req.ip, req.method, req.path, public)
|
||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -85,81 +72,8 @@ app.get('/profile', (req, res) => {
|
||||||
res.sendFile('profile.html', { root: './public' })
|
res.sendFile('profile.html', { root: './public' })
|
||||||
})
|
})
|
||||||
|
|
||||||
const api = require('./src/api.js')
|
|
||||||
app.use('/api', api);
|
app.use('/api', api);
|
||||||
|
app.use('/console', con.router);
|
||||||
const connections = []
|
|
||||||
app.get('/console', (req, res) => {
|
|
||||||
res.write(`
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<link rel="stylesheet" href="css/console.css">
|
|
||||||
<title>XSSBook - Console</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
`)
|
|
||||||
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, '<').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 '<span class="' + cls + '">' + match + '</span>';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function update(ip, method, path, json) {
|
|
||||||
connections.forEach(con => {
|
|
||||||
con.write(`
|
|
||||||
<div>
|
|
||||||
<span class="ip">${ip}</span>
|
|
||||||
<span class="method" style="color: #${color(method)}">${method}</span>
|
|
||||||
<span class="path">${path}</span>
|
|
||||||
<span class="json">${highlight(json)}</span>
|
|
||||||
</div>
|
|
||||||
`)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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) => {
|
app.use((req, res, next) => {
|
||||||
res.status(404).sendFile('404.html', { root: './public' })
|
res.status(404).sendFile('404.html', { root: './public' })
|
||||||
|
|
81
src/console.js
Normal file
81
src/console.js
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
const express = require('express')
|
||||||
|
const router = express.Router()
|
||||||
|
const sleep = ms => new Promise(r => setTimeout(r, ms));
|
||||||
|
|
||||||
|
const connections = []
|
||||||
|
|
||||||
|
router.get('/', async (req, res) => {
|
||||||
|
res.write(`
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link rel="stylesheet" href="css/console.css">
|
||||||
|
<title>XSSBook - Console</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
`)
|
||||||
|
res.write(new Array(2048).join(" "))
|
||||||
|
await sleep(500)
|
||||||
|
connections.push(res)
|
||||||
|
while (true) {
|
||||||
|
res.write(" ")
|
||||||
|
await sleep(100)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
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, '<').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 '<span class="' + cls + '">' + match + '</span>';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function update(ip, method, path, json) {
|
||||||
|
connections.forEach(con => {
|
||||||
|
con.write(`
|
||||||
|
<div>
|
||||||
|
<span class="ip">${ip}</span>
|
||||||
|
<span class="method" style="color: #${color(method)}">${method}</span>
|
||||||
|
<span class="path">${path}</span>
|
||||||
|
<span class="json">${highlight(json)}</span>
|
||||||
|
</div>
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { router, update };
|
Loading…
Reference in a new issue