const express = require('express');
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
const cors = require('cors');
const xssClean = require('xss-clean');
const mongoSanitize = require('express-mongo-sanitize');
const cookieParser = require('cookie-parser');
const path = require('path');
const fs = require('fs');
const app = express();
const port = 8080; // Port 80 for HTTP
// Set security HTTP headers using Helmet
app.use(helmet());
// Rate limiting to prevent DoS attacks
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
message: 'Too many requests from this IP, please try again later',
});
app.use(limiter);
// Enable CORS for external API calls
app.use(cors());
// Sanitize data to prevent NoSQL injection and XSS attacks
app.use(mongoSanitize());
app.use(xssClean());
// Body parser to read data into req.body
app.use(express.json({ limit: '10kb' }));
// Cookie-parser middleware
app.use(cookieParser());
// Set EJS as the view engine
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views')); // Set the views directory
// Function to detect w3m requests
function isW3M(req) {
const userAgent = req.headers['user-agent'];
return userAgent && userAgent.toLowerCase().includes('w3m');
}
// Function to detect Lynx
function isLynx(req) {
const userAgent = req.headers['user-agent'];
return userAgent && userAgent.toLowerCase().includes('lynx');
}
// Serve static files from the 'public' directory
app.use(express.static(path.join(__dirname, 'public')));
// Function to detect curl requests
function isCurl(req) {
const userAgent = req.headers['user-agent'];
return userAgent && userAgent.includes('curl');
}
// Serve the install.sh script dynamically based on query parameter repo_id
app.get('/install.sh', (req, res) => {
const repoId = req.query.repo_id;
if (!repoId) {
return res.status(400).send('Error: No repo_id provided.');
}
// Path to the install.sh script
const scriptPath = path.join(__dirname, 'public/scripts/install.sh');
// Make sure the file exists
if (!fs.existsSync(scriptPath)) {
return res.status(404).send('Error: install.sh not found.');
}
// Read the install.sh script and send it as a response with the correct content type
res.setHeader('Content-Type', 'application/x-sh');
fs.createReadStream(scriptPath).pipe(res);
});
// In-house IP address retrieval API
app.get('/ip', (req, res) => {
//const userIp = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
const userIp = (req.headers['x-forwarded-for'] || req.connection.remoteAddress).split(',')[0].trim();
// If request is made using curl, send a plain text response
if (isCurl(req)) {
res.setHeader('Content-Type', 'text/plain');
res.send(`Public IP: ${userIp}\n`);
} else {
// request is made on browser, send simple HTML response
res.send(`