privateburn/server.js
2026-01-15 13:38:02 +02:00

69 lines
2.3 KiB
JavaScript

const http = require('node:http');
const fs = require('node:fs');
const path = require('node:path');
const crypto = require('node:crypto');
const PORT = process.env.PORT || 3000;
const DATA_DIR = path.join(__dirname, 'data');
const MAX_SIZE_BYTES = 10 * 1024 * 1024; // 10MB
if (!fs.existsSync(DATA_DIR)) fs.mkdirSync(DATA_DIR);
const sendJSON = (res, status, data) => {
res.writeHead(status, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(data));
};
const server = http.createServer((req, res) => {
const { method, url } = req;
// Serve Frontend
if (method === 'GET' && (url === '/' || url.startsWith('/view'))) {
res.writeHead(200, { 'Content-Type': 'text/html' });
fs.createReadStream(path.join(__dirname, 'index.html')).pipe(res);
return;
}
// CREATE Secret (Public POST)
if (method === 'POST' && url === '/api/secret') {
const contentLength = parseInt(req.headers['content-length'], 10);
if (contentLength > MAX_SIZE_BYTES) {
res.writeHead(413); return res.end('Too large');
}
const id = crypto.randomUUID(); // Unique and Random URL component
const filePath = path.join(DATA_DIR, id);
const writeStream = fs.createWriteStream(filePath);
req.pipe(writeStream);
req.on('end', () => sendJSON(res, 201, { id }));
writeStream.on('error', () => { res.writeHead(500); res.end(); });
return;
}
// READ & BURN Secret
if (method === 'GET' && url.startsWith('/api/secret/')) {
const id = url.split('/').pop();
if (!/^[a-z0-9-]+$/i.test(id)) { res.writeHead(400); return res.end(); }
const filePath = path.join(DATA_DIR, id);
if (!fs.existsSync(filePath)) {
res.writeHead(404); return res.end('Burned or Not Found');
}
const readStream = fs.createReadStream(filePath);
res.writeHead(200, { 'Content-Type': 'application/octet-stream' });
readStream.pipe(res);
// Delete immediately after stream ends
readStream.on('end', () => {
fs.unlink(filePath, (err) => { if (err) console.error("Burn failed", err); });
});
return;
}
res.writeHead(404); res.end();
});
server.listen(PORT, () => console.log(`Public Burn Server: http://localhost:${PORT}`));