Published code to public

This commit is contained in:
root 2025-09-30 15:52:54 +02:00
commit 766dcdec3a
11 changed files with 2342 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules/
files/

0
README.md Normal file
View File

69
app.js Normal file
View File

@ -0,0 +1,69 @@
const express = require('express');
const path = require('path');
const fs = require('fs');
const app = express();
const { logger, initializeLogging } = require('./logger');
const { setupSecurity } = require('./security');
const FILES_DIR = path.join(__dirname, 'files');
// Initialize the logging system
initializeLogging();
// Setup security middlewares
setupSecurity(app);
app.use(express.static(path.join(__dirname, 'public')));
// List directory contents
app.get('/api/list', (req, res) => {
const subpath = req.query.path || '';
const dirPath = path.join(FILES_DIR, subpath);
if (!dirPath.startsWith(FILES_DIR)) return res.status(400).send('Invalid path.');
fs.readdir(dirPath, { withFileTypes: true }, (err, items) => {
if (err) return res.status(500).send('Error reading directory.');
const result = items.map(item => ({
name: item.name,
isDirectory: item.isDirectory()
}));
res.json(result);
});
});
// Search for files recursively
function searchFiles(dir, term, basePath = '') {
let results = [];
const items = fs.readdirSync(dir, { withFileTypes: true });
for (const item of items) {
const fullPath = path.join(dir, item.name);
const relPath = path.join(basePath, item.name);
if (item.isDirectory()) {
results = results.concat(searchFiles(fullPath, term, relPath));
} else if (item.name.toLowerCase().includes(term.toLowerCase())) {
results.push(relPath);
}
}
return results;
}
app.get('/api/search', (req, res) => {
const term = req.query.q || '';
const results = searchFiles(FILES_DIR, term);
res.json(results);
});
// Download endpoint
app.get('/api/download', (req, res) => {
const filePath = path.join(FILES_DIR, req.query.path);
if (!filePath.startsWith(FILES_DIR)) return res.status(400).send('Invalid file path.');
res.download(filePath);
});
const PORT = 3300;
app.listen(PORT, () => console.log(`Server running at http://localhost:${PORT}`));

46
logger.js Normal file
View File

@ -0,0 +1,46 @@
const fs = require('fs');
const winston = require('winston');
// Create a logs directory if it doesn't exist
if (!fs.existsSync('logs')) {
fs.mkdirSync('logs');
}
// Define custom log levels
const customLevels = {
levels: {
error: 0,
warn: 1,
info: 2
},
colors: {
error: 'bold white redBG',
warn: 'bold red',
info: 'yellow'
},
};
// Add colors to winston
winston.addColors(customLevels.colors);
// Configure winston logger
const logger = winston.createLogger({
levels: customLevels.levels,
format: winston.format.combine(
winston.format.colorize(),
winston.format.timestamp(),
winston.format.printf(({ timestamp, level, message }) => {
return `${timestamp} ${level}: ${message}`;
})
),
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'logs/app.log' })
]
});
const initializeLogging = () => {
logger.info('Logging system initialized');
};
module.exports = { logger, initializeLogging };

220
logs/app.log Normal file
View File

@ -0,0 +1,220 @@
2025-05-14T13:48:37.911Z info: DDoS protection initialized with burst: 10, limit: 15
2025-05-14T13:48:37.914Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-05-14T13:48:37.914Z info: Logging system initialized
2025-05-14T13:48:37.915Z warn: HTTPS redirect is disabled for testing purposes
2025-05-14T13:48:37.915Z warn: Helmet security is disabled for testing purposes
2025-05-14T13:48:37.916Z info: CORS configured with specific settings
2025-05-14T13:48:37.917Z info: Cookie security applied
2025-05-14T13:48:37.917Z info: Rate limiting middleware applied to all routes
2025-05-14T13:48:37.917Z info: DDoS protection middleware applied
2025-05-14T13:48:37.918Z info: Slow down protection applied
2025-05-14T13:49:15.725Z info: DDoS protection initialized with burst: 10, limit: 15
2025-05-14T13:49:15.728Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-05-14T13:49:15.729Z info: Logging system initialized
2025-05-14T13:49:15.729Z warn: HTTPS redirect is disabled for testing purposes
2025-05-14T13:49:15.729Z warn: Helmet security is disabled for testing purposes
2025-05-14T13:49:15.730Z info: CORS configured with specific settings
2025-05-14T13:49:15.731Z info: Cookie security applied
2025-05-14T13:49:15.731Z info: Rate limiting middleware applied to all routes
2025-05-14T13:49:15.731Z info: DDoS protection middleware applied
2025-05-14T13:49:15.733Z info: Slow down protection applied
2025-05-14T13:51:18.900Z info: DDoS protection initialized with burst: 10, limit: 15
2025-05-14T13:51:18.904Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-05-14T13:51:18.904Z info: Logging system initialized
2025-05-14T13:51:18.905Z warn: HTTPS redirect is disabled for testing purposes
2025-05-14T13:51:18.905Z warn: Helmet security is disabled for testing purposes
2025-05-14T13:51:18.906Z info: CORS configured with specific settings
2025-05-14T13:51:18.907Z info: Cookie security applied
2025-05-14T13:51:18.907Z info: Rate limiting middleware applied to all routes
2025-05-14T13:51:18.907Z info: DDoS protection middleware applied
2025-05-14T13:51:18.908Z info: Slow down protection applied
2025-05-14T13:52:04.019Z info: DDoS protection initialized with burst: 10, limit: 15
2025-05-14T13:52:04.022Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-05-14T13:52:04.022Z info: Logging system initialized
2025-05-14T13:52:04.022Z warn: HTTPS redirect is disabled for testing purposes
2025-05-14T13:52:04.023Z warn: Helmet security is disabled for testing purposes
2025-05-14T13:52:04.024Z info: CORS configured with specific settings
2025-05-14T13:52:04.024Z info: Cookie security applied
2025-05-14T13:52:04.025Z info: Rate limiting middleware applied to all routes
2025-05-14T13:52:04.025Z info: DDoS protection middleware applied
2025-05-14T13:52:04.026Z info: Slow down protection applied
2025-05-14T13:57:33.023Z info: DDoS protection initialized with burst: 10, limit: 15
2025-05-14T13:57:33.026Z error: Failed to apply rate limiting middleware
2025-05-14T13:57:33.027Z info: Logging system initialized
2025-05-14T13:57:33.027Z warn: HTTPS redirect is disabled for testing purposes
2025-05-14T13:57:33.028Z warn: Helmet security is disabled for testing purposes
2025-05-14T13:57:33.029Z info: CORS configured with specific settings
2025-05-14T13:57:33.029Z info: Cookie security applied
2025-05-14T13:57:33.029Z error: Failed to apply rate limiting middleware
2025-05-14T13:57:33.030Z info: DDoS protection middleware applied
2025-05-14T13:57:33.031Z info: Slow down protection applied
2025-05-14T13:58:54.910Z info: Logging system initialized
2025-05-14T13:58:54.912Z info: DDoS protection initialized with burst: 10, limit: 15
2025-05-14T13:58:54.915Z info: Rate limiting middleware applied to all routes
2025-05-14T13:58:54.915Z warn: HTTPS redirect is disabled for testing purposes
2025-05-14T13:58:54.915Z warn: Helmet security is disabled for testing purposes
2025-05-14T13:58:54.916Z info: CORS configured with specific settings
2025-05-14T13:58:54.916Z info: Cookie security applied
2025-05-14T13:58:54.916Z error: Failed to apply rate limiting middleware
2025-05-14T13:58:54.917Z info: DDoS protection middleware applied
2025-05-14T13:58:54.918Z info: Slow down protection applied
2025-05-14T13:59:45.313Z info: Logging system initialized
2025-05-14T13:59:45.316Z info: DDoS protection initialized with burst: 10, limit: 15
2025-05-14T13:59:45.318Z info: Rate limiting middleware applied to all routes
2025-05-14T13:59:45.318Z warn: HTTPS redirect is disabled for testing purposes
2025-05-14T13:59:45.319Z warn: Helmet security is disabled for testing purposes
2025-05-14T13:59:45.319Z info: CORS configured with specific settings
2025-05-14T13:59:45.319Z info: Cookie security applied
2025-05-14T13:59:45.320Z error: Failed to apply rate limiting middleware
2025-05-14T13:59:45.320Z info: DDoS protection middleware applied
2025-05-14T13:59:45.321Z info: Slow down protection applied
2025-05-14T14:00:15.802Z info: DDoS protection initialized with burst: 10, limit: 15
2025-05-14T14:00:15.805Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-05-14T14:00:15.806Z info: Logging system initialized
2025-05-14T14:00:15.806Z warn: HTTPS redirect is disabled for testing purposes
2025-05-14T14:00:15.806Z warn: Helmet security is disabled for testing purposes
2025-05-14T14:00:15.808Z info: CORS configured with specific settings
2025-05-14T14:00:15.808Z info: Cookie security applied
2025-05-14T14:00:15.808Z info: Rate limiting middleware applied to all routes
2025-05-14T14:00:15.809Z info: DDoS protection middleware applied
2025-05-14T14:00:15.810Z info: Slow down protection applied
2025-05-14T14:01:36.502Z info: DDoS protection initialized with burst: 10, limit: 15
2025-05-14T14:01:36.504Z info: Logging system initialized
2025-05-14T14:01:36.506Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-05-14T14:01:36.506Z warn: HTTPS redirect is disabled for testing purposes
2025-05-14T14:01:36.506Z warn: Helmet security is disabled for testing purposes
2025-05-14T14:01:36.508Z info: CORS configured with specific settings
2025-05-14T14:01:36.508Z info: Cookie security applied
2025-05-14T14:01:36.508Z info: Rate limiting middleware applied to all routes
2025-05-14T14:01:36.508Z info: DDoS protection middleware applied
2025-05-14T14:01:36.509Z info: Slow down protection applied
2025-05-14T14:03:58.188Z info: DDoS protection initialized with burst: 10, limit: 15
2025-05-14T14:03:58.194Z info: Logging system initialized
2025-05-14T14:03:58.198Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-05-14T14:03:58.199Z warn: HTTPS redirect is disabled for testing purposes
2025-05-14T14:03:58.199Z warn: Helmet security is disabled for testing purposes
2025-05-14T14:03:58.201Z info: CORS configured with specific settings
2025-05-14T14:03:58.201Z info: Cookie security applied
2025-05-14T14:03:58.201Z info: Rate limiting middleware applied to all routes
2025-05-14T14:03:58.202Z info: DDoS protection middleware applied
2025-05-14T14:03:58.203Z info: Slow down protection applied
2025-05-14T14:04:27.919Z info: DDoS protection initialized with burst: 10, limit: 15
2025-05-14T14:04:27.922Z info: Logging system initialized
2025-05-14T14:04:27.925Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-05-14T14:04:27.926Z warn: HTTPS redirect is disabled for testing purposes
2025-05-14T14:04:27.927Z warn: Helmet security is disabled for testing purposes
2025-05-14T14:04:27.928Z info: CORS configured with specific settings
2025-05-14T14:04:27.929Z info: Cookie security applied
2025-05-14T14:04:27.929Z info: Rate limiting middleware applied to all routes
2025-05-14T14:04:27.930Z info: DDoS protection middleware applied
2025-05-14T14:04:27.931Z info: Slow down protection applied
2025-05-14T14:04:52.718Z info: DDoS protection initialized with burst: 10, limit: 15
2025-05-14T14:04:52.720Z info: Logging system initialized
2025-05-14T14:04:52.723Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-05-14T14:04:52.724Z warn: HTTPS redirect is disabled for testing purposes
2025-05-14T14:04:52.727Z info: Helmet middleware applied with custom settings
2025-05-14T14:04:52.727Z info: CORS configured with specific settings
2025-05-14T14:04:52.728Z info: Cookie security applied
2025-05-14T14:04:52.730Z info: Rate limiting middleware applied to all routes
2025-05-14T14:04:52.730Z info: DDoS protection middleware applied
2025-05-14T14:04:52.732Z info: Slow down protection applied
2025-06-04T02:25:57.385Z info: DDoS protection initialized with burst: 10, limit: 15
2025-06-04T02:25:57.398Z info: Logging system initialized
2025-06-04T02:25:57.409Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-06-04T02:25:57.410Z warn: HTTPS redirect is disabled for testing purposes
2025-06-04T02:25:57.414Z info: Helmet middleware applied with custom settings
2025-06-04T02:25:57.466Z info: CORS configured with specific settings
2025-06-04T02:25:57.467Z info: Cookie security applied
2025-06-04T02:25:57.468Z info: Rate limiting middleware applied to all routes
2025-06-04T02:25:57.468Z info: DDoS protection middleware applied
2025-06-04T02:25:57.472Z info: Slow down protection applied
2025-08-19T05:52:26.188Z info: DDoS protection initialized with burst: 10, limit: 15
2025-08-19T05:52:26.192Z info: Logging system initialized
2025-08-19T05:52:26.196Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-08-19T05:52:26.197Z warn: HTTPS redirect is disabled for testing purposes
2025-08-19T05:52:26.200Z info: Helmet middleware applied with custom settings
2025-08-19T05:52:26.201Z info: CORS configured with specific settings
2025-08-19T05:52:26.201Z info: Cookie security applied
2025-08-19T05:52:26.202Z info: Rate limiting middleware applied to all routes
2025-08-19T05:52:26.202Z info: DDoS protection middleware applied
2025-08-19T05:52:26.204Z info: Slow down protection applied
2025-09-04T19:42:43.365Z info: DDoS protection initialized with burst: 10, limit: 15
2025-09-04T19:42:43.372Z info: Logging system initialized
2025-09-04T19:42:43.383Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-09-04T19:42:43.388Z warn: HTTPS redirect is disabled for testing purposes
2025-09-04T19:42:43.770Z info: Helmet middleware applied with custom settings
2025-09-04T19:42:43.771Z info: CORS configured with specific settings
2025-09-04T19:42:43.774Z info: Cookie security applied
2025-09-04T19:42:43.775Z info: Rate limiting middleware applied to all routes
2025-09-04T19:42:43.776Z info: DDoS protection middleware applied
2025-09-04T19:42:43.780Z info: Slow down protection applied
2025-09-07T12:55:42.608Z info: DDoS protection initialized with burst: 10, limit: 15
2025-09-07T12:55:42.609Z info: Logging system initialized
2025-09-07T12:55:42.625Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-09-07T12:55:42.681Z warn: HTTPS redirect is disabled for testing purposes
2025-09-07T12:55:42.688Z info: Helmet middleware applied with custom settings
2025-09-07T12:55:42.693Z info: CORS configured with specific settings
2025-09-07T12:55:42.693Z info: Cookie security applied
2025-09-07T12:55:42.694Z info: Rate limiting middleware applied to all routes
2025-09-07T12:55:42.698Z info: DDoS protection middleware applied
2025-09-07T12:55:42.699Z info: Slow down protection applied
2025-09-09T06:59:08.924Z info: DDoS protection initialized with burst: 10, limit: 15
2025-09-09T06:59:08.926Z info: Logging system initialized
2025-09-09T06:59:08.930Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-09-09T06:59:08.930Z warn: HTTPS redirect is disabled for testing purposes
2025-09-09T06:59:08.994Z info: Helmet middleware applied with custom settings
2025-09-09T06:59:08.996Z info: CORS configured with specific settings
2025-09-09T06:59:08.997Z info: Cookie security applied
2025-09-09T06:59:08.997Z info: Rate limiting middleware applied to all routes
2025-09-09T06:59:09.002Z info: DDoS protection middleware applied
2025-09-09T06:59:09.004Z info: Slow down protection applied
2025-09-09T06:59:12.597Z info: DDoS protection initialized with burst: 10, limit: 15
2025-09-09T06:59:12.600Z info: Logging system initialized
2025-09-09T06:59:12.604Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-09-09T06:59:12.605Z warn: HTTPS redirect is disabled for testing purposes
2025-09-09T06:59:12.608Z info: Helmet middleware applied with custom settings
2025-09-09T06:59:12.608Z info: CORS configured with specific settings
2025-09-09T06:59:12.609Z info: Cookie security applied
2025-09-09T06:59:12.609Z info: Rate limiting middleware applied to all routes
2025-09-09T06:59:12.610Z info: DDoS protection middleware applied
2025-09-09T06:59:12.611Z info: Slow down protection applied
2025-09-09T07:00:40.009Z info: DDoS protection initialized with burst: 10, limit: 15
2025-09-09T07:00:40.011Z info: Logging system initialized
2025-09-09T07:00:40.015Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-09-09T07:00:40.015Z warn: HTTPS redirect is disabled for testing purposes
2025-09-09T07:00:40.018Z info: Helmet middleware applied with custom settings
2025-09-09T07:00:40.018Z info: CORS configured with specific settings
2025-09-09T07:00:40.019Z info: Cookie security applied
2025-09-09T07:00:40.019Z info: Rate limiting middleware applied to all routes
2025-09-09T07:00:40.020Z info: DDoS protection middleware applied
2025-09-09T07:00:40.021Z info: Slow down protection applied
2025-09-09T07:12:38.021Z info: DDoS protection initialized with burst: 10, limit: 15
2025-09-09T07:12:38.023Z info: Logging system initialized
2025-09-09T07:12:38.027Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-09-09T07:12:38.027Z warn: HTTPS redirect is disabled for testing purposes
2025-09-09T07:12:38.030Z info: Helmet middleware applied with custom settings
2025-09-09T07:12:38.031Z info: CORS configured with specific settings
2025-09-09T07:12:38.031Z info: Cookie security applied
2025-09-09T07:12:38.083Z info: Rate limiting middleware applied to all routes
2025-09-09T07:12:38.083Z info: DDoS protection middleware applied
2025-09-09T07:12:38.088Z info: Slow down protection applied
2025-09-09T07:14:15.687Z info: DDoS protection initialized with burst: 10, limit: 15
2025-09-09T07:14:15.691Z info: Logging system initialized
2025-09-09T07:14:15.696Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-09-09T07:14:15.696Z warn: HTTPS redirect is disabled for testing purposes
2025-09-09T07:14:15.701Z info: Helmet middleware applied with custom settings
2025-09-09T07:14:15.701Z info: CORS configured with specific settings
2025-09-09T07:14:15.702Z info: Cookie security applied
2025-09-09T07:14:15.703Z info: Rate limiting middleware applied to all routes
2025-09-09T07:14:15.703Z info: DDoS protection middleware applied
2025-09-09T07:14:15.706Z info: Slow down protection applied
2025-09-09T07:14:43.210Z info: DDoS protection initialized with burst: 10, limit: 15
2025-09-09T07:14:43.212Z info: Logging system initialized
2025-09-09T07:14:43.215Z info: Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs
2025-09-09T07:14:43.216Z warn: HTTPS redirect is disabled for testing purposes
2025-09-09T07:14:43.218Z info: Helmet middleware applied with custom settings
2025-09-09T07:14:43.218Z info: CORS configured with specific settings
2025-09-09T07:14:43.219Z info: Cookie security applied
2025-09-09T07:14:43.219Z info: Rate limiting middleware applied to all routes
2025-09-09T07:14:43.219Z info: DDoS protection middleware applied
2025-09-09T07:14:43.220Z info: Slow down protection applied

1558
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

29
package.json Normal file
View File

@ -0,0 +1,29 @@
{
"name": "edubooks",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"body-parser": "^1.20.3",
"cookie-parser": "^1.4.7",
"cors": "^2.8.5",
"ddos": "^0.2.1",
"dotenv": "^16.4.7",
"express": "^4.21.2",
"express-rate-limit": "^7.5.0",
"express-slow-down": "^2.0.3",
"express-sslify": "^1.2.0",
"helmet": "^8.1.0",
"megajs": "^1.3.5",
"mysql2": "^3.12.0",
"mysql2-promise": "^0.1.4",
"validator": "^13.15.0",
"winston": "^3.17.0"
}
}

26
public/index.html Normal file
View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Eduvos Books</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>Eduvos Books</h1>
<h2 style="font-size: 16px; color: gray;">
Please note. These books are cracked copies and NOT official retail copies.
I am not liable for any incorrect or unofficial pdf files. Also note that if
something was to go wrong, the site will be shut down WITHOUT notice.
</h2>
<input type="text" id="search" placeholder="Search files..." />
<nav id="breadcrumb" class="breadcrumb"></nav>
<ul id="file-list" class="file-list"></ul>
</div>
<script src="script.js"></script>
</body>
</html>

105
public/script.js Normal file
View File

@ -0,0 +1,105 @@
const fileList = document.getElementById('file-list');
const searchBox = document.getElementById('search');
const breadcrumb = document.getElementById('breadcrumb');
let currentPath = '';
function pathJoin(...parts) {
return parts.filter(Boolean).join('/');
}
function fetchDirectory(path = '') {
fetch(`/api/list?path=${encodeURIComponent(path)}`)
.then(res => res.json())
.then(data => {
currentPath = path;
renderBreadcrumb(path);
renderList(data);
});
}
function renderBreadcrumb(path) {
breadcrumb.innerHTML = '';
const parts = path.split('/').filter(Boolean);
let accum = '';
const root = document.createElement('span');
root.textContent = 'Home';
root.onclick = () => fetchDirectory('');
breadcrumb.appendChild(root);
parts.forEach((part, index) => {
accum = pathJoin(accum, part);
const sep = document.createElement('span');
sep.className = 'separator';
sep.textContent = ' / ';
breadcrumb.appendChild(sep);
const crumb = document.createElement('span');
crumb.textContent = part;
crumb.onclick = () => fetchDirectory(parts.slice(0, index + 1).join('/'));
breadcrumb.appendChild(crumb);
});
}
function renderList(items) {
fileList.innerHTML = '';
const folders = items.filter(i => i.isDirectory);
const files = items.filter(i => !i.isDirectory);
folders.forEach(item => {
const li = document.createElement('li');
li.className = 'folder';
li.textContent = `📁 ${item.name}`;
li.onclick = () => fetchDirectory(pathJoin(currentPath, item.name));
fileList.appendChild(li);
});
files.forEach(item => {
const li = document.createElement('li');
li.textContent = item.name;
const link = document.createElement('a');
link.href = `/api/download?path=${encodeURIComponent(pathJoin(currentPath, item.name))}`;
link.textContent = 'Download';
link.className = 'download-link';
link.onclick = e => e.stopPropagation();
li.appendChild(link);
fileList.appendChild(li);
});
}
function searchFiles(term) {
fetch(`/api/search?q=${encodeURIComponent(term)}`)
.then(res => res.json())
.then(results => {
breadcrumb.innerHTML = '';
fileList.innerHTML = '';
results.forEach(relPath => {
const li = document.createElement('li');
li.textContent = relPath;
const link = document.createElement('a');
link.href = `/api/download?path=${encodeURIComponent(relPath)}`;
link.textContent = 'Download';
link.className = 'download-link';
link.onclick = e => e.stopPropagation();
li.appendChild(link);
fileList.appendChild(li);
});
});
}
searchBox.addEventListener('input', e => {
const term = e.target.value.trim();
if (term.length === 0) {
fetchDirectory();
} else {
searchFiles(term);
}
});
fetchDirectory();

121
public/style.css Normal file
View File

@ -0,0 +1,121 @@
:root {
--bg: #2c2c2d;
--card-bg: #232222;
--primary: #007aff;
--border: #1a1919;
--text: #c2c2c9;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: var(--bg);
color: var(--text);
}
.container {
max-width: 900px;
margin: 0 auto;
padding: 20px;
background: var(--card-bg);
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.1);
border-radius: 12px;
margin-top: 40px;
}
h1 {
font-size: 24px;
margin-bottom: 20px;
}
input[type="text"] {
width: 96%;
padding: 14px;
font-size: 16px;
border: 1px solid var(--border);
border-radius: 10px;
margin-bottom: 16px;
background-color: #1e1e1e; /* dark background */
color: #f5f5f5; /* light text */
border: 1px solid #444; /* subtle border */
}
.breadcrumb {
display: flex;
flex-wrap: wrap;
margin-bottom: 16px;
gap: 4px;
font-size: 15px;
}
.breadcrumb span {
color: var(--primary);
cursor: pointer;
}
.breadcrumb .separator {
color: #999;
}
.file-list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
}
.file-list li {
display: flex;
justify-content: space-between;
align-items: center;
padding: 14px;
border-bottom: 1px solid var(--border);
font-size: 16px;
transition: background 0.2s ease;
}
.file-list li.folder {
color: var(--primary);
font-weight: 500;
cursor: pointer;
}
.file-list li.folder:hover {
background: #262626;
}
a.download-link {
color: var(--primary);
text-decoration: none;
font-size: 14px;
}
a.download-link:hover {
text-decoration: underline;
}
@media (max-width: 600px) {
h1 {
font-size: 20px;
}
input[type="text"] {
font-size: 14px;
padding: 12px;
background-color: #1e1e1e; /* dark background */
color: #f5f5f5; /* light text */
border: 1px solid #444; /* subtle border */
}
.file-list li {
font-size: 15px;
padding: 12px;
}
a.download-link {
font-size: 13px;
}
}

166
security.js Normal file
View File

@ -0,0 +1,166 @@
const rateLimit = require('express-rate-limit');
const helmet = require('helmet');
const cors = require('cors');
const express = require('express');
const Ddos = require('ddos');
const sslify = require('express-sslify');
const cookieParser = require('cookie-parser');
const slowDown = require('express-slow-down');
const { logger } = require('./logger');
const validator = require('validator');
// Feature Toggle Booleans
const enableDdosProtection = true;
const enableRateLimiting = true;
const enableHelmet = true;
const enableCORS = true;
const enableHttpsRedirect = false;
const enableCookieSecurity = true;
const enableSlowDown = true;
// Initialize DDoS protection with default configuration
let ddos;
if (enableDdosProtection) {
try {
ddos = new Ddos({ burst: 10, limit: 15 });
logger.info({ message: 'DDoS protection initialized with burst: 10, limit: 15' });
} catch (error) {
logger.error({ message: 'Failed to initialize DDoS protection', error });
}
}
// Function to apply security middlewares to the app
const setupSecurity = (app) => {
app.set('trust proxy', 'loopback');
// Configure rate limiting
let limiter;
if (enableRateLimiting) {
try {
limiter = rateLimit({
windowMs: 5 * 60 * 1000, // 15 minutes
max: 300, // Limit each IP to 100 requests per windowMs
standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
legacyHeaders: false, // Disable the `X-RateLimit-*` headers
});
logger.info({ message: 'Rate limiting configured with windowMs: 15 minutes, max: 100 requests per windowMs' });
} catch (error) {
logger.error({ message: 'Failed to configure rate limiting', error });
}
}
// Apply HTTPS redirect if enabled
if (enableHttpsRedirect) {
try {
app.use(sslify.HTTPS({ trustProtoHeader: true }));
logger.info({ message: 'HTTPS redirect middleware applied' });
} catch (error) {
logger.error({ message: 'Failed to apply HTTPS redirect middleware', error });
}
} else {
logger.warn({ message: 'HTTPS redirect is disabled for testing purposes' });
}
// Apply Helmet to secure HTTP headers
if (enableHelmet) {
try {
app.use(helmet());
app.use(helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
connectSrc: ["'self'"],
fontSrc: ["'self'"],
objectSrc: ["'none'"],
upgradeInsecureRequests: []
}
}));
app.use(helmet.frameguard({ action: 'deny' }));
app.use(helmet.xssFilter());
app.use(helmet.hsts({ maxAge: 31536000, includeSubDomains: true, preload: true }));
logger.info({ message: 'Helmet middleware applied with custom settings' });
} catch (error) {
logger.error({ message: 'Failed to apply Helmet middleware', error });
}
} else {
logger.warn({ message: 'Helmet security is disabled for testing purposes' });
}
// Apply CORS if enabled
if (enableCORS) {
try {
app.use(cors({
origin: ['https://ourdomain.co.za'],
methods: ['GET', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization']
}));
logger.info({ message: 'CORS configured with specific settings' });
} catch (error) {
logger.error({ message: 'Failed to apply CORS settings', error });
}
} else {
logger.warn({ message: 'CORS is disabled for testing purposes' });
}
// Apply Cookie security if enabled
if (enableCookieSecurity) {
try {
app.use(cookieParser());
app.use((req, res, next) => {
res.cookie('name', 'value', { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'Strict' });
next();
});
logger.info({ message: 'Cookie security applied' });
} catch (error) {
logger.error({ message: 'Failed to apply cookie security', error });
}
} else {
logger.warn({ message: 'Cookie security is disabled for testing purposes' });
}
// Apply rate limiting if enabled
if (enableRateLimiting) {
try {
app.use(limiter);
logger.info({ message: 'Rate limiting middleware applied to all routes' });
} catch (error) {
logger.error({ message: 'Failed to apply rate limiting middleware', error });
}
} else {
logger.warn({ message: 'Rate limiting is disabled for testing purposes' });
}
// Apply DDoS protection if enabled
if (enableDdosProtection) {
try {
app.use(ddos.express);
logger.info({ message: 'DDoS protection middleware applied' });
} catch (error) {
logger.error({ message: 'Failed to apply DDoS protection middleware', error });
}
} else {
logger.warn({ message: 'DDoS protection is disabled for testing purposes' });
}
// Apply slow down protection if enabled
if (enableSlowDown) {
try {
app.use(slowDown({
windowMs: 15 * 60 * 1000, // 15 minutes
delayAfter: 100, // Delay after 100 requests
delayMs: () => 500 // Apply a fixed 500ms delay after exceeding the threshold
}));
logger.info({ message: 'Slow down protection applied' });
} catch (error) {
logger.error({ message: 'Failed to apply slow down protection', error });
}
} else {
logger.warn({ message: 'Slow down protection is disabled for testing purposes' });
}
};
module.exports = { setupSecurity };