basic filtering prototype

This commit is contained in:
Russell2259
2024-01-29 07:38:52 -07:00
parent 5ccb6fd915
commit ece1502813
9 changed files with 171 additions and 36 deletions
+23
View File
@@ -0,0 +1,23 @@
-> URL Filter
-> Any proxied url with these words will be blocked
porn
pornography
sex
ass
dick
cock
bitch
busty
boob
cum
fuck
xx
nude
tit
vagina
semen
penis
masturbate
anal
anus
+2 -1
View File
@@ -8,7 +8,8 @@ var config = {
},
minify: false,
assetScrambling: false,
allowDangerousTemplateInsert: true
allowDangerousTemplateInsert: true,
filtering: true
}
};
+6 -22
View File
@@ -9,12 +9,12 @@
"version": "1.2.1",
"license": "GNU-3.0-or-later",
"dependencies": {
"@Skoolgq/bare-server-node-modified": "github:Skoolgq/bare-server-node-modified",
"@tomphttp/bare-server-node": "^2.0.1",
"cors": "*",
"easyviolet": "github:Russell2259/Easyviolet",
"express": "*",
"html-minifier": "^4.0.0",
"is-word": "^1.0.4",
"javascript-obfuscator": "^4.1.0",
"jsdom": "^23.0.1",
"mime": "*",
@@ -46,27 +46,6 @@
"node": ">=4.0"
}
},
"node_modules/@Skoolgq/bare-server-node-modified": {
"name": "@tomphttp/bare-server-node",
"version": "2.0.1",
"resolved": "git+ssh://git@github.com/Skoolgq/bare-server-node-modified.git#1e1a1cd12e8487156f859de4a1d2d10a7c71c11c",
"license": "GPL-3.0",
"dependencies": {
"async-exit-hook": "^2.0.1",
"commander": "^10.0.1",
"dotenv": "^16.0.3",
"http-errors": "^2.0.0",
"ipaddr.js": "^2.0.1",
"source-map-support": "^0.5.21",
"ws": "^8.13.0"
},
"bin": {
"bare-server-node": "bin.js"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@titaniumnetwork-dev/ultraviolet": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@titaniumnetwork-dev/ultraviolet/-/ultraviolet-2.0.0.tgz",
@@ -1180,6 +1159,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-word": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-word/-/is-word-1.0.4.tgz",
"integrity": "sha512-AKiRceZqb0c8o028B72FoF2/HesPHsMxFQu/pDRaKGTBU/rCF/CnSd9D55H2nvJkPab+xs98iPexI/PwiFerlw=="
},
"node_modules/javascript-obfuscator": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/javascript-obfuscator/-/javascript-obfuscator-4.1.0.tgz",
+1
View File
@@ -17,6 +17,7 @@
"easyviolet": "github:Russell2259/Easyviolet",
"express": "*",
"html-minifier": "^4.0.0",
"is-word": "^1.0.4",
"javascript-obfuscator": "^4.1.0",
"jsdom": "^23.0.1",
"mime": "*",
+2 -1
View File
@@ -12,6 +12,7 @@ export default useConfig({
api: {
domain: 'api.polarislearning.org',
secure: true
}
},
filtering: true
}
});
+32 -7
View File
@@ -3,7 +3,7 @@ import express from 'express';
import mime from 'mime';
import cors from 'cors';
import { pathToFile, TokenManager, rewriter } from './utils.js';
import { pathToFile, TokenManager, rewriter, filter } from './utils.js';
import config from '../polaris.config.js';
import api from './api.js';
@@ -103,7 +103,10 @@ app.get('/asset/:token', async (req, res, next) => {
}
});
app.get('/uv/service/*', async (req, res) => res.end(await rewriter.html(fs.readFileSync(path.join(__dirname, '../pages/proxy_404.html')))));
app.get('/uv/service/*', async (req, res) => {
console.log(req.url);
res.end(await rewriter.html(fs.readFileSync(path.join(__dirname, '../pages/proxy_404.html'))));
});
app.get('/dynamic/service/*', async (req, res) => res.end(await rewriter.html(fs.readFileSync(path.join(__dirname, '../pages/proxy_404.html')))));
app.use(async (req, res, next) => {
@@ -131,18 +134,40 @@ app.use(async (req, res, next) => {
}
});
server.on('request', (req, res) => {
server.on('request', async (req, res) => {
if (bareServer.shouldRoute(req)) {
//console.log('request', req.headers['x-bare-url']);
try {
const results = await filter(req.headers['x-bare-url'].replace(req.headers['x-bare-url'].split('://')[0] + '://', ''));
console.log(results);
//console.log(req.headers.host);
if (results.flagged) {
return;
}
} catch (e) { }
bareServer.routeRequest(req, res);
} else app(req, res);
});
server.on('upgrade', (req, socket, head) => {
server.on('upgrade', async (req, socket, head) => {
if (bareServer.shouldRoute(req)) {
//console.log('upgrade', req.headers['x-bare-url']);
try {
const results = await filter(req.headers['x-bare-url'].replace(req.headers['x-bare-url'].split('://')[0] + '://', ''));
console.log(results);
//console.log(req.headers.host);
if (results.flagged) {
return;
}
} catch (e) { }
bareServer.routeUpgrade(req, socket, head);
} else socket.end();
});
server.listen(config.port, () => console.log(`Polaris running\n\nPort: ${server.address().port}\nVersion: ${packageFile.version + (Number(packageFile.version.split('.')[0]) <= 1 ? ' Beta' : '') || 'Unknown'} ${childProcess.execSync('git rev-parse HEAD').toString().trim().slice(0, 7) || 'Unknown'}\nMode: ${config.mode === 'dev' ? 'development' : 'production'}\nAPI Server: ${config.options.api.domain}\nNode.js: ${process.version}`));
server.listen(config.port, () => console.log(`Polaris running\n\nPort: ${server.address().port}\nVersion: ${packageFile.version + (Number(packageFile.version.split('.')[0]) <= 1 ? ' Beta' : '') || 'Unknown'} ${childProcess.execSync('git rev-parse HEAD').toString().trim().slice(0, 7) || 'Unknown'}\nMode: ${config.mode === 'dev' ? 'development' : 'production'}\nProxy Filter: ${config.options.filtering ? 'enabled' : 'disabled'}\nAPI Server: ${config.options.api.domain}\nNode.js: ${process.version}`));
+102 -2
View File
@@ -1,15 +1,31 @@
import isWord from 'is-word';
import * as rewriter from './utils/rewriter.js';
import TokenManager from './utils/token.js';
import config from '../polaris.config.js';
import path from 'node:path';
import url from 'node:url';
import fs from 'node:fs';
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
const dictionary = fs.readFileSync(path.join(__dirname, '../node_modules/is-word/dictionary/american-english.txt'))
.toString()
.split('\n')
.map(word => word.trim());
const englishWords = isWord('american-english');
const parsedFilter = config.options.filtering ? fs.readFileSync(path.join(__dirname, '../filter.txt'))
.toString()
.split('\n')
.map(query => query.trim())
.filter(query => query && !query.startsWith('->')) : [];
/**
* @param {string} url
* @param {string} folderPath
* @returns {{ exists: boolean, path: string }}
*/
const pathToFile = (url = '', folderPath) => {
export const pathToFile = (url = '', folderPath) => {
if (url.endsWith('/')) url = url + 'index.html';
else if (url.split(/[#?]/)[0].split('.').pop().trim() === url) {
if (!fs.existsSync(path.join(folderPath, url))) url = url + '.html';
@@ -21,14 +37,98 @@ const pathToFile = (url = '', folderPath) => {
};
};
/**
* Get words from a string
* @param {string} input
* @param {Array.<string>} words
* @returns {Promise.<Array.<string>>}
*/
export const getWords = (input, words) => new Promise(async (resolve, reject) => {
let output = [];
for (let i = 0; i < words.length; i++) {
output.push(...Array((input.match(RegExp(words[i], 'gi')) || []).length).fill(words[i]));
if (i + 1 === words.length) resolve(output);
}
});
/**
* @param {string} query
* @returns {Promise.<{ flagged: true, query: string }>}
*/
export const filter = (query) => new Promise(async (resolve, reject) => {
if (parsedFilter.length === 0) {
resolve({
flagged: false,
query: ''
});
return;
}
const parsedQuery = query.replaceAll('/', ' ').replaceAll('-', ' ').replaceAll('_', ' ').split(' ');
for (let i = 0; i < parsedQuery.length; i++) {
/**
* @type {string}
*/
const query = parsedQuery[i];
const validWord = englishWords.check(query);
if (validWord && parsedFilter.includes(query)) {
resolve({
flagged: true,
query
});
return;
}
if (!validWord) {
const results = await (new Promise((resolve, reject) => {
for (let i = 0; i < parsedFilter.length; i++) {
const hasFiltered = query.includes(parsedFilter[i]);
if (hasFiltered) {
resolve({
flagged: true,
query: parsedFilter[i]
});
return;
}
if (i + 1 === parsedFilter.length) resolve({
flagged: false,
query: ''
});
}
}));
console.log(query);
if (results.flagged) {
resolve({
flagged: true,
query: results.query
});
return;
}
}
if (i + 1 === parsedQuery.length) resolve({
flagged: false,
query: ''
});
}
});
export default {
pathToFile,
filter,
TokenManager,
rewriter
};
export {
pathToFile,
TokenManager,
rewriter
};
+1 -1
View File
@@ -12,7 +12,7 @@
top: 0;
margin-left: 50px;
margin-right: 50px;
margin-top: 35px;
margin-top: 50px;
color: rgb(255, 255, 255);
z-index: 100;
display: flex;
+2 -2
View File
@@ -16,7 +16,7 @@ body[data-theme='dark'] {
}
body[data-theme='light'] {
--background-color: rgba(255, 255, 255, 0.8);
--background-color: #ffffffcc;
--background-darker: rgba(235, 235, 235, 0.8);
--text: #000;
--hover: #757575;
@@ -214,7 +214,7 @@ body[data-theme='violet'] {
}
@media screen and (prefers-color-scheme: light) {
body[data-theme='light'] {
body[data-theme='system-default'] {
--background-color: #fff;
--background-darker: var(--background-color);
--text: #000;