/* ----------------------------------------------- * Authors: QuiteAFancyEmerald, BinBashBanana (OlyB), YÖCTDÖNALD'S * Additional help from Divide and SexyDuceDuce * MIT license: http://opensource.org/licenses/MIT * ----------------------------------------------- */ const alloy = require('./src/alloyproxy'), path = require('path'), config = require('./config.json'), fs = require('fs'), http = require('http'), express = require('express'), app = express(), port = process.env.PORT || config.port, server = http.createServer(app); btoa = (str) => { return new Buffer.from(str).toString('base64'); } atob = (str) => { return new Buffer.from(str, 'base64').toString('utf-8'); } const text404 = fs.readFileSync(path.normalize(__dirname + '/views/404.html'), 'utf8'), siteIndex = 'index.html', pages = { /* Main */ 'in': 'info.html', 'faq': 'faq.html', 'j': 'hidden.html', 's': 'pages/frame.html', 'z': 'pages/surf.html', 'c': 'pages/nav/credits.html', 'x': 'pages/nav/bookmarklets.html', 'i': 'pages/nav/icons.html', 't': 'pages/nav/terms.html', /* Games */ 'g': 'pages/nav/gtools.html', 'h': 'pages/nav/games5.html', 'el': 'pages/nav/emulators.html', 'f': 'pages/nav/flash.html', 'm': 'pages/nav/emulibrary.html', /* Proxies */ 'q': 'pages/proxnav/corrosion.html', 'a': 'pages/proxnav/alloy.html', 'w': 'pages/proxnav/womginx.html', 'p': 'pages/proxnav/pmprox.html', 'e': 'pages/proxnav/pyb.html', 'o': 'pages/proxnav/pydodge.html', 'y': 'pages/proxnav/youtube.html', 'd': 'pages/proxnav/discordhub.html', /* Ruffle and Webretro */ 'fg': 'archive/gfiles/flash/index.html', 'eg': 'archive/gfiles/rarch/index.html' }, fileMod = [ "/views/assets/css/styles.min.css", ], cookingInserts = [ "Random sentence one filled with certain keywords.", "Random sentence two filled with certain keywords." ], splashtext = [ 'This is simply a public demo for Holy Unblocker. Certain functions may not work properly. Join the TN Discord for official site links' ], vegetables = ['Cooking1', 'Cooking2'], charRandom = ['­', '​']; function randomListItem(lis) { return lis[Math.floor(Math.random() * lis.length)]; } // The inline function returns are necessary to prevent all replaced things from being the same function insertCharset(str) { return str.replace(/­|​|/g, function() { return randomListItem(charRandom); }); } function insertSplash(str) { return str.replace(/️/g, function() { return splashtext; }); } function insertCooking(str) { return str.replace(//g, function() { return '' + randomListItem(cookingInserts) + ''; }); } function cacheBusting(str) { return str.replace(/styles.min.css/g, 'styles-368357.min.css'); } function insertAll(str) { return insertCharset(insertCooking(insertSplash(cacheBusting(str)))); } /* Cache Busting const stats = fs.statSync(path.normalize(__dirname + fileMod), 'utf8'), seconds = (new Date().getTime() - stats.mtime); fs.renameSync(path.normalize(__dirname + fileMod), 'links-' + seconds + '.js'); function cacheBusting(str) { return str.replace(/links.js/g, "links" + '-' + seconds + '.js'); } */ function tryReadFile(file) { return fs.existsSync(file) ? fs.readFileSync(file, 'utf8') : text404; } // Local alloy proxy const localAlloy = new alloy({ prefix: '/fetch/', error: (proxy) => { proxy.res.send(tryReadFile(path.normalize(__dirname + '/views/error.html')).replace('%ERR%', proxy.error.info.message.replace(/<|>/g, ''))); }, // Doing replace functions on "<" and ">" to prevent XSS. request: [], response: [], injection: true }); app.use(localAlloy.app); localAlloy.ws(server); /* Querystring Navigation */ app.get('/', async(req, res) => res.send(insertAll(tryReadFile(path.normalize(__dirname + '/views/' + (['/', '/?'].includes(req.url) ? siteIndex : pages[Object.keys(req.query)[0]])))))); /* Static Files Served */ app.use(express.static(path.normalize(__dirname + '/views'))); app.use((req, res) => res.status(404, res.send(insertAll(text404)))); server.listen(port); console.log('Holy Unblocker is listening on port ' + port + '. This is simply a public for Holy Unblocker. Certain functions may not work properly.');