Purge Cyclone
This commit is contained in:
parent
ce625b6d3a
commit
5885af8ebf
15 changed files with 170 additions and 909 deletions
14
.devcontainer/Dockerfile
Normal file
14
.devcontainer/Dockerfile
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster
|
||||||
|
ARG VARIANT=16-bullseye
|
||||||
|
FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT}
|
||||||
|
|
||||||
|
# [Optional] Uncomment this section to install additional OS packages.
|
||||||
|
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||||
|
# && apt-get -y install --no-install-recommends <your-package-list-here>
|
||||||
|
|
||||||
|
# [Optional] Uncomment if you want to install an additional version of node using nvm
|
||||||
|
# ARG EXTRA_NODE_VERSION=10
|
||||||
|
# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"
|
||||||
|
|
||||||
|
# [Optional] Uncomment if you want to install more global node modules
|
||||||
|
# RUN su node -c "npm install -g <your-package-list-here>"
|
||||||
55
.devcontainer/base.Dockerfile
Normal file
55
.devcontainer/base.Dockerfile
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster
|
||||||
|
ARG VARIANT=16-bullseye
|
||||||
|
FROM node:${VARIANT}
|
||||||
|
|
||||||
|
# [Option] Install zsh
|
||||||
|
ARG INSTALL_ZSH="true"
|
||||||
|
# [Option] Upgrade OS packages to their latest versions
|
||||||
|
ARG UPGRADE_PACKAGES="true"
|
||||||
|
|
||||||
|
# Install needed packages, yarn, nvm and setup non-root user. Use a separate RUN statement to add your own dependencies.
|
||||||
|
ARG USERNAME=node
|
||||||
|
ARG USER_UID=1000
|
||||||
|
ARG USER_GID=$USER_UID
|
||||||
|
ARG NPM_GLOBAL=/usr/local/share/npm-global
|
||||||
|
ENV NVM_DIR=/usr/local/share/nvm
|
||||||
|
ENV NVM_SYMLINK_CURRENT=true \
|
||||||
|
PATH=${NPM_GLOBAL}/bin:${NVM_DIR}/current/bin:${PATH}
|
||||||
|
COPY library-scripts/*.sh library-scripts/*.env /tmp/library-scripts/
|
||||||
|
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||||
|
# Remove imagemagick due to https://security-tracker.debian.org/tracker/CVE-2019-10131
|
||||||
|
&& apt-get purge -y imagemagick imagemagick-6-common \
|
||||||
|
# Install common packages, non-root user, update yarn and install nvm
|
||||||
|
&& bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" "true" "true" \
|
||||||
|
# Install yarn, nvm
|
||||||
|
&& rm -rf /opt/yarn-* /usr/local/bin/yarn /usr/local/bin/yarnpkg \
|
||||||
|
&& bash /tmp/library-scripts/node-debian.sh "${NVM_DIR}" "none" "${USERNAME}" \
|
||||||
|
# Configure global npm install location, use group to adapt to UID/GID changes
|
||||||
|
&& if ! cat /etc/group | grep -e "^npm:" > /dev/null 2>&1; then groupadd -r npm; fi \
|
||||||
|
&& usermod -a -G npm ${USERNAME} \
|
||||||
|
&& umask 0002 \
|
||||||
|
&& mkdir -p ${NPM_GLOBAL} \
|
||||||
|
&& touch /usr/local/etc/npmrc \
|
||||||
|
&& chown ${USERNAME}:npm ${NPM_GLOBAL} /usr/local/etc/npmrc \
|
||||||
|
&& chmod g+s ${NPM_GLOBAL} \
|
||||||
|
&& npm config -g set prefix ${NPM_GLOBAL} \
|
||||||
|
&& sudo -u ${USERNAME} npm config -g set prefix ${NPM_GLOBAL} \
|
||||||
|
# Install eslint
|
||||||
|
&& su ${USERNAME} -c "umask 0002 && npm install -g eslint" \
|
||||||
|
&& npm cache clean --force > /dev/null 2>&1 \
|
||||||
|
# Install python-is-python3 on bullseye to prevent node-gyp regressions
|
||||||
|
&& . /etc/os-release \
|
||||||
|
&& if [ "${VERSION_CODENAME}" = "bullseye" ]; then apt-get -y install --no-install-recommends python-is-python3; fi \
|
||||||
|
# Clean up
|
||||||
|
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /root/.gnupg /tmp/library-scripts
|
||||||
|
|
||||||
|
# [Optional] Uncomment this section to install additional OS packages.
|
||||||
|
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||||
|
# && apt-get -y install --no-install-recommends <your-package-list-here>
|
||||||
|
|
||||||
|
# [Optional] Uncomment if you want to install an additional version of node using nvm
|
||||||
|
# ARG EXTRA_NODE_VERSION=10
|
||||||
|
# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"
|
||||||
|
|
||||||
|
# [Optional] Uncomment if you want to install more global node modules
|
||||||
|
# RUN su node -c "npm install -g <your-package-list-here>""
|
||||||
32
.devcontainer/devcontainer.json
Normal file
32
.devcontainer/devcontainer.json
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||||
|
// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/javascript-node
|
||||||
|
{
|
||||||
|
"name": "Node.js",
|
||||||
|
"build": {
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
// Update 'VARIANT' to pick a Node version: 18, 16, 14.
|
||||||
|
// Append -bullseye or -buster to pin to an OS version.
|
||||||
|
// Use -bullseye variants on local arm64/Apple Silicon.
|
||||||
|
"args": { "VARIANT": "16-bullseye" }
|
||||||
|
},
|
||||||
|
|
||||||
|
// Configure tool-specific properties.
|
||||||
|
"customizations": {
|
||||||
|
// Configure properties specific to VS Code.
|
||||||
|
"vscode": {
|
||||||
|
// Add the IDs of extensions you want installed when the container is created.
|
||||||
|
"extensions": [
|
||||||
|
"dbaeumer.vscode-eslint"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||||
|
// "forwardPorts": [],
|
||||||
|
|
||||||
|
// Use 'postCreateCommand' to run commands after the container is created.
|
||||||
|
"postCreateCommand": "npm install",
|
||||||
|
|
||||||
|
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
||||||
|
"remoteUser": "node"
|
||||||
|
}
|
||||||
|
|
@ -31,7 +31,6 @@ $ npm start
|
||||||
- Partical.JS
|
- Partical.JS
|
||||||
- UV Backend Proxy
|
- UV Backend Proxy
|
||||||
- Osana Backend Proxy
|
- Osana Backend Proxy
|
||||||
- Cyclone Backend Proxy
|
|
||||||
- **Server:** Bare server on Node
|
- **Server:** Bare server on Node
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -116,7 +115,6 @@ sudo nohup PORT=80 node . &
|
||||||
## Acknowledgements
|
## Acknowledgements
|
||||||
|
|
||||||
- [UV (one of the back-end proxy we use)](https://github.com/titaniumnetwork-dev/Ultraviolet)
|
- [UV (one of the back-end proxy we use)](https://github.com/titaniumnetwork-dev/Ultraviolet)
|
||||||
- [Cyclone (one of the back-end proxy we use)](https://github.com/NebulaServices/Cyclone)
|
|
||||||
- [Osana (one of the back-end proxy we use)](https://github.com/NebulaServices/Osana)
|
- [Osana (one of the back-end proxy we use)](https://github.com/NebulaServices/Osana)
|
||||||
- [Bare Server](https://github.com/tomphttp/bare-server-node)
|
- [Bare Server](https://github.com/tomphttp/bare-server-node)
|
||||||
- [Partical.JS (v4, 5, 6.1 &< only)](https://github.com/VincentGarreau/particles.js)
|
- [Partical.JS (v4, 5, 6.1 &< only)](https://github.com/VincentGarreau/particles.js)
|
||||||
|
|
|
||||||
2
app.js
2
app.js
|
|
@ -3,7 +3,6 @@ import http from 'http';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import { dirname, join } from 'path';
|
import { dirname, join } from 'path';
|
||||||
import serveStatic from 'serve-static';
|
import serveStatic from 'serve-static';
|
||||||
import * as custombare from './static/customBare.mjs';
|
|
||||||
|
|
||||||
const PORT = process.env.PORT || 3000;
|
const PORT = process.env.PORT || 3000;
|
||||||
const bareServer = createBareServer('/bare/', {
|
const bareServer = createBareServer('/bare/', {
|
||||||
|
|
@ -23,7 +22,6 @@ const server = http.createServer();
|
||||||
|
|
||||||
server.on('request', (request, response) => {
|
server.on('request', (request, response) => {
|
||||||
try {
|
try {
|
||||||
if (custombare.route(request, response)) return true;
|
|
||||||
|
|
||||||
if (bareServer.shouldRoute(request)) {
|
if (bareServer.shouldRoute(request)) {
|
||||||
bareServer.routeRequest(request, response);
|
bareServer.routeRequest(request, response);
|
||||||
|
|
|
||||||
109
package-lock.json
generated
109
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "nebula-web",
|
"name": "nebula-web",
|
||||||
"version": "7.10",
|
"version": "7.10.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "nebula-web",
|
"name": "nebula-web",
|
||||||
"version": "7.10",
|
"version": "7.10.0",
|
||||||
"license": "GNU AGPL V3",
|
"license": "GNU AGPL V3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tomphttp/bare-server-node": "^1.0.2-beta-readme5",
|
"@tomphttp/bare-server-node": "^1.0.2-beta-readme5",
|
||||||
|
|
@ -15,29 +15,29 @@
|
||||||
"node-fetch": "^3.2.6",
|
"node-fetch": "^3.2.6",
|
||||||
"serve-static": "^1.15.0",
|
"serve-static": "^1.15.0",
|
||||||
"ws": "^8.8.1"
|
"ws": "^8.8.1"
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@tomphttp/bare-server-node": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@tomphttp/bare-server-node/-/bare-server-node-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-mKMipi9qntDy3wcalWGuK3iKzM0XQT4sW3E6yRXeIU4BxFZVSLzSDejPxL6wWwniKGm0faSwZ4Pk0dQ04JEFNA==",
|
|
||||||
"dependencies": {
|
|
||||||
"commander": "^9.0.0",
|
|
||||||
"dotenv": "^16.0.1",
|
|
||||||
"headers-polyfill": "^3.0.10",
|
|
||||||
"http-errors": "^2.0.0"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"bare-server-node": "scripts/cli.js"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.0.0"
|
"node": ">=16.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@tomphttp/bare-server-node": {
|
||||||
|
"version": "1.0.2-beta-readme5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tomphttp/bare-server-node/-/bare-server-node-1.0.2-beta-readme5.tgz",
|
||||||
|
"integrity": "sha512-WOYNae3faSj9Yt4dKVqzjbh1ovpKRhsevnJaM2BgC6LkRULFN/GhtslXDXG6KLbqeokFFj0XqpZ8TTzdxKyhkw==",
|
||||||
|
"dependencies": {
|
||||||
|
"commander": "^9.0.0",
|
||||||
|
"dotenv": "^16.0.1",
|
||||||
|
"fetch-headers": "^3.0.1",
|
||||||
|
"http-errors": "^2.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"bare-server-node": "scripts/start.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/commander": {
|
"node_modules/commander": {
|
||||||
"version": "9.4.0",
|
"version": "9.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz",
|
||||||
"integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==",
|
"integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.20.0 || >=14"
|
"node": "^12.20.0 || >=14"
|
||||||
}
|
}
|
||||||
|
|
@ -99,9 +99,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dotenv": {
|
"node_modules/dotenv": {
|
||||||
"version": "16.0.2",
|
"version": "16.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
|
||||||
"integrity": "sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA==",
|
"integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
|
|
@ -154,6 +154,24 @@
|
||||||
"node": "^12.20 || >= 14.13"
|
"node": "^12.20 || >= 14.13"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fetch-headers": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fetch-headers/-/fetch-headers-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-Kq+NyED/wLgT29St7aW47gAWg8EmmE5QmhwQ5RmPRULYLqpglA7Kc/ZnbqXu2vhH6mw1koikew2g94WiHLPmpA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/jimmywarting"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://paypal.me/jimmywarting"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.20"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/formdata-polyfill": {
|
"node_modules/formdata-polyfill": {
|
||||||
"version": "4.0.10",
|
"version": "4.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
||||||
|
|
@ -173,11 +191,6 @@
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/headers-polyfill": {
|
|
||||||
"version": "3.0.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-3.0.10.tgz",
|
|
||||||
"integrity": "sha512-lOhQU7iG3AMcjmb8NIWCa+KwfJw5bY44BoWPtrj5A4iDbSD3ylGf5QcYr0ZyQnhkKQ2GgWNLdF2rfrXtXlF3nQ=="
|
|
||||||
},
|
|
||||||
"node_modules/http-errors": {
|
"node_modules/http-errors": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||||
|
|
@ -356,9 +369,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ws": {
|
"node_modules/ws": {
|
||||||
"version": "8.8.1",
|
"version": "8.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz",
|
||||||
"integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==",
|
"integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
},
|
},
|
||||||
|
|
@ -378,20 +391,20 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tomphttp/bare-server-node": {
|
"@tomphttp/bare-server-node": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.2-beta-readme5",
|
||||||
"resolved": "https://registry.npmjs.org/@tomphttp/bare-server-node/-/bare-server-node-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@tomphttp/bare-server-node/-/bare-server-node-1.0.2-beta-readme5.tgz",
|
||||||
"integrity": "sha512-mKMipi9qntDy3wcalWGuK3iKzM0XQT4sW3E6yRXeIU4BxFZVSLzSDejPxL6wWwniKGm0faSwZ4Pk0dQ04JEFNA==",
|
"integrity": "sha512-WOYNae3faSj9Yt4dKVqzjbh1ovpKRhsevnJaM2BgC6LkRULFN/GhtslXDXG6KLbqeokFFj0XqpZ8TTzdxKyhkw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"commander": "^9.0.0",
|
"commander": "^9.0.0",
|
||||||
"dotenv": "^16.0.1",
|
"dotenv": "^16.0.1",
|
||||||
"headers-polyfill": "^3.0.10",
|
"fetch-headers": "^3.0.1",
|
||||||
"http-errors": "^2.0.0"
|
"http-errors": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"commander": {
|
"commander": {
|
||||||
"version": "9.4.0",
|
"version": "9.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz",
|
||||||
"integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw=="
|
"integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw=="
|
||||||
},
|
},
|
||||||
"crypto-js": {
|
"crypto-js": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
|
|
@ -438,9 +451,9 @@
|
||||||
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
|
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
|
||||||
},
|
},
|
||||||
"dotenv": {
|
"dotenv": {
|
||||||
"version": "16.0.2",
|
"version": "16.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
|
||||||
"integrity": "sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA=="
|
"integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ=="
|
||||||
},
|
},
|
||||||
"ee-first": {
|
"ee-first": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
|
|
@ -471,6 +484,11 @@
|
||||||
"web-streams-polyfill": "^3.0.3"
|
"web-streams-polyfill": "^3.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fetch-headers": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fetch-headers/-/fetch-headers-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-Kq+NyED/wLgT29St7aW47gAWg8EmmE5QmhwQ5RmPRULYLqpglA7Kc/ZnbqXu2vhH6mw1koikew2g94WiHLPmpA=="
|
||||||
|
},
|
||||||
"formdata-polyfill": {
|
"formdata-polyfill": {
|
||||||
"version": "4.0.10",
|
"version": "4.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
||||||
|
|
@ -484,11 +502,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||||
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
|
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
|
||||||
},
|
},
|
||||||
"headers-polyfill": {
|
|
||||||
"version": "3.0.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-3.0.10.tgz",
|
|
||||||
"integrity": "sha512-lOhQU7iG3AMcjmb8NIWCa+KwfJw5bY44BoWPtrj5A4iDbSD3ylGf5QcYr0ZyQnhkKQ2GgWNLdF2rfrXtXlF3nQ=="
|
|
||||||
},
|
|
||||||
"http-errors": {
|
"http-errors": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||||
|
|
@ -611,9 +624,9 @@
|
||||||
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q=="
|
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q=="
|
||||||
},
|
},
|
||||||
"ws": {
|
"ws": {
|
||||||
"version": "8.8.1",
|
"version": "8.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz",
|
||||||
"integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==",
|
"integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==",
|
||||||
"requires": {}
|
"requires": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "nebula-web",
|
"name": "nebula-web",
|
||||||
"version": "7.10",
|
"version": "7.10.0",
|
||||||
"description": "Explore the web. Freely.",
|
"description": "Explore the web. Freely.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "app.js",
|
"main": "app.js",
|
||||||
|
|
@ -13,11 +13,14 @@
|
||||||
"author": "Nebula Services",
|
"author": "Nebula Services",
|
||||||
"license": "GNU AGPL V3",
|
"license": "GNU AGPL V3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tomphttp/bare-server-node": "1.0.2-beta-readme5",
|
"@tomphttp/bare-server-node": "^1.0.2-beta-readme5",
|
||||||
"crypto-js": "4.1.1",
|
"crypto-js": "4.1.1",
|
||||||
"css-tree": "^2.1.0",
|
"css-tree": "^2.1.0",
|
||||||
"node-fetch": "^3.2.6",
|
"node-fetch": "^3.2.6",
|
||||||
"serve-static": "^1.15.0",
|
"serve-static": "^1.15.0",
|
||||||
"ws": "^8.8.1"
|
"ws": "^8.8.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
import fetch from 'node-fetch';
|
|
||||||
import { URL } from 'url';
|
|
||||||
import fs from 'fs';
|
|
||||||
import * as csstree from 'css-tree';
|
|
||||||
import * as ws from 'ws';
|
|
||||||
import filter from './cyclone/filter.cyclone.mjs';
|
|
||||||
import * as security from './cyclone/security.cyclone.mjs';
|
|
||||||
|
|
||||||
const config = {
|
|
||||||
prefix: "/service/next",
|
|
||||||
requireSSL: true, // Requires SSL?
|
|
||||||
defaultHeaders: {
|
|
||||||
'X-Content-Type-Options': 'no-sniff',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.requireSSL) {
|
|
||||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "1";
|
|
||||||
} else {
|
|
||||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
||||||
}
|
|
||||||
|
|
||||||
function rewriteJavascript(js) {
|
|
||||||
var javascript = js.replace(/window\.location/g, 'window._dlocation')
|
|
||||||
javascript = javascript.replace(/document\.location/g, 'document._dlocation')
|
|
||||||
javascript = javascript.replace(/location\./g, '_location.')
|
|
||||||
return javascript
|
|
||||||
}
|
|
||||||
|
|
||||||
function insertScript(html) {
|
|
||||||
var res = `<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<script preload src="/cyclone/cyclone.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
${html}
|
|
||||||
</body>
|
|
||||||
</html>`
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchBare(url, res, req) {
|
|
||||||
try {
|
|
||||||
var options = {
|
|
||||||
method: req.method,
|
|
||||||
headers: {
|
|
||||||
"Referer": url.href,
|
|
||||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36",
|
|
||||||
"Cookie": req.headers.cookie,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var request = await fetch(url.href, options);
|
|
||||||
|
|
||||||
try {
|
|
||||||
var contentType = request.headers.get('content-type') || 'application/javascript'
|
|
||||||
} catch {
|
|
||||||
var contentType = 'application/javascript';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (url.href.endsWith('.js') || url.href.endsWith(".js")) contentType = "application/javascript";
|
|
||||||
if (url.href.endsWith('.css') || url.href.endsWith(".css")) contentType = "text/css";
|
|
||||||
|
|
||||||
var output = null;
|
|
||||||
|
|
||||||
if (contentType.includes('html') || contentType.includes('javascript')) {
|
|
||||||
var doc = await request.text();
|
|
||||||
}
|
|
||||||
|
|
||||||
res.setHeader('content-type', contentType);
|
|
||||||
|
|
||||||
if (contentType.includes('html')) {
|
|
||||||
output = insertScript(doc);
|
|
||||||
res.write(output);
|
|
||||||
res.end();
|
|
||||||
} else if (contentType.includes('javascript')) {
|
|
||||||
output = rewriteJavascript(doc)
|
|
||||||
res.write(output);
|
|
||||||
res.end()
|
|
||||||
} else {
|
|
||||||
request.body.pipe(res)
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
res.writeHead(500, 'Internal Server Error', {
|
|
||||||
'Content-Type': 'text/plain'
|
|
||||||
})
|
|
||||||
res.end(e.stack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function websocketIntercept(req, res) {
|
|
||||||
console.log(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
function route(req, res) {
|
|
||||||
var path = req.url;
|
|
||||||
|
|
||||||
if (path.startsWith(config.prefix + "/")) {
|
|
||||||
var decoded = path.split(config.prefix + "/")[1];
|
|
||||||
|
|
||||||
try {
|
|
||||||
var url = new URL(decoded);
|
|
||||||
} catch {
|
|
||||||
var url = new URL("https://" + decoded);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filter(req, res)) return;
|
|
||||||
|
|
||||||
return fetchBare(url, res, req);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function isBare(req, res) {
|
|
||||||
return (req.url.startsWith(config.prefix));
|
|
||||||
}
|
|
||||||
|
|
||||||
function routeSocket(req, socket) {
|
|
||||||
var path = req.url;
|
|
||||||
|
|
||||||
try {
|
|
||||||
var url = new URL(path(config.prefix + "/")[1])
|
|
||||||
} catch {
|
|
||||||
var url = new URL("wss://" + path(config.prefix + "/")[1])
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
route,
|
|
||||||
routeSocket,
|
|
||||||
isBare,
|
|
||||||
}
|
|
||||||
109
static/cySw.js
109
static/cySw.js
|
|
@ -1,109 +0,0 @@
|
||||||
class Cyclone {
|
|
||||||
constructor() {
|
|
||||||
tmp = location.pathname.split('/service')[1]
|
|
||||||
|
|
||||||
tmp = tmp.substring(1, tmp.length);
|
|
||||||
let re = /(http(s|):)/g
|
|
||||||
|
|
||||||
//if (tmp.match(re)) {
|
|
||||||
tmp = tmp.replace("http://", '')
|
|
||||||
tmp = tmp.replace("https://", '')
|
|
||||||
tmp = tmp.replace("http:/", '')
|
|
||||||
tmp = tmp.replace("https:/", '')
|
|
||||||
tmp = location.protocol + "//" + tmp
|
|
||||||
|
|
||||||
document._location = new URL(tmp);
|
|
||||||
|
|
||||||
this.url = new URL(document._location.href);
|
|
||||||
|
|
||||||
this.bareEndpoint = location.host + "/service";
|
|
||||||
|
|
||||||
if (this.url.pathname == "/") {
|
|
||||||
this.paths = ['/']
|
|
||||||
} else {
|
|
||||||
this.paths = this.url.pathname.split('/')
|
|
||||||
}
|
|
||||||
this.host = 'https://' + this.url.host
|
|
||||||
|
|
||||||
this.targetAttrs = ['href', 'src', 'action', 'srcdoc', 'srcset'];
|
|
||||||
|
|
||||||
console.log("Cyclone Injected with paths of:", this.paths, this.url.pathname)
|
|
||||||
|
|
||||||
/*const LocationHandler = {
|
|
||||||
get(target, prop, reciver) {
|
|
||||||
return loc[prop]
|
|
||||||
},
|
|
||||||
set(target, prop, val) {
|
|
||||||
return 'hi'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document._location = new Proxy(LocationHandler, loc)*/
|
|
||||||
}
|
|
||||||
|
|
||||||
rewriteUrl(link) {
|
|
||||||
var rewritten;
|
|
||||||
|
|
||||||
if (link.startsWith('https://') || link.startsWith('http://') || link.startsWith('//')) {
|
|
||||||
if (link.startsWith('//')) {
|
|
||||||
rewritten = 'https:' + link;
|
|
||||||
} else {
|
|
||||||
rewritten = link;
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
if (link.startsWith('.')) {
|
|
||||||
let offset = 1;
|
|
||||||
if (link.startsWith('..')) {
|
|
||||||
offset = 2;
|
|
||||||
}
|
|
||||||
let file = link.substr(link.indexOf('.') + 1 + offset, link.length)
|
|
||||||
|
|
||||||
rewritten = this.url.hostname + file
|
|
||||||
} else {
|
|
||||||
if (link.startsWith('/')) {
|
|
||||||
rewritten = this.host + link
|
|
||||||
} else {
|
|
||||||
rewritten = this.host + '/' + link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var exceptions = ['about:', 'mailto:', 'javascript:', 'data:']
|
|
||||||
let needstowrite = true;
|
|
||||||
for (let i = 0; i < exceptions.length; i++) {
|
|
||||||
if (link.startsWith(exceptions[i])) {
|
|
||||||
needstowrite = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needstowrite) {
|
|
||||||
rewritten = location.protocol + '//' + this.bareEndpoint + '/' + rewritten
|
|
||||||
return rewritten;
|
|
||||||
} else {
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rewriteSrcset(sample) {
|
|
||||||
return sample.split(',').map(e => {
|
|
||||||
return (e.split(' ').map(a => {
|
|
||||||
if (a.startsWith('http') || (a.startsWith('/') && !a.startsWith(this.prefix))) {
|
|
||||||
var url = this.rewriteUrl(a)
|
|
||||||
}
|
|
||||||
return a.replace(a, (url || a))
|
|
||||||
}).join(' '))
|
|
||||||
}).join(',')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.addEventListener('fetch', function(event) {
|
|
||||||
var uri = new URL(event.request.url);
|
|
||||||
|
|
||||||
if (!uri.pathname.startsWith('/service') && uri.pathname == "/facicon.ico") {
|
|
||||||
var tmp = uri.href;
|
|
||||||
|
|
||||||
event.respondWith(
|
|
||||||
fetch("https://Cyclone2.jimmynuetron.repl.co/service/" + tmp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,476 +0,0 @@
|
||||||
const config = {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const encryptWithAES = (text) => {
|
|
||||||
const passphrase = '123';
|
|
||||||
return CryptoJS.AES.encrypt(text, passphrase).toString();
|
|
||||||
};
|
|
||||||
|
|
||||||
const decryptWithAES = (ciphertext) => {
|
|
||||||
const passphrase = '123';
|
|
||||||
const bytes = CryptoJS.AES.decrypt(ciphertext, passphrase);
|
|
||||||
const originalText = bytes.toString(CryptoJS.enc.Utf8);
|
|
||||||
return originalText;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Cyclone {
|
|
||||||
constructor() {
|
|
||||||
this.tmp = (location.pathname.split('/service/')[1]);
|
|
||||||
|
|
||||||
this.tmp = this.tmp.substring(0, this.tmp.length);
|
|
||||||
this.tmp = this.tmp.replace("http://", '')
|
|
||||||
this.tmp = this.tmp.replace("https://", '')
|
|
||||||
this.tmp = this.tmp.replace("http:/", '')
|
|
||||||
this.tmp = this.tmp.replace("https:/", '')
|
|
||||||
this.tmp = location.protocol + "//" + this.tmp
|
|
||||||
|
|
||||||
document._location = new URL(this.tmp);
|
|
||||||
var l = new URL(this.tmp);
|
|
||||||
|
|
||||||
this.url = new URL(document._location.href);
|
|
||||||
|
|
||||||
this.prefix = (location.pathname).split('/')[1];
|
|
||||||
this.bareEndpoint = location.host + "/" + this.prefix;
|
|
||||||
|
|
||||||
if (this.url.pathname == "/") {
|
|
||||||
this.paths = ['/']
|
|
||||||
} else {
|
|
||||||
this.paths = this.url.pathname.split('/')
|
|
||||||
}
|
|
||||||
this.host = 'https://' + this.url.host
|
|
||||||
|
|
||||||
this.targetAttrs = ['href', 'src', 'action', 'srcdoc', 'srcset'];
|
|
||||||
|
|
||||||
if (!document.cycloneInjected) {
|
|
||||||
console.log("Cyclone Injected with paths of:", this.paths, this.url.pathname)
|
|
||||||
document.cycloneInjected = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const LocationHandler = {
|
|
||||||
get(target, prop, reciver) {
|
|
||||||
return document._location[prop]
|
|
||||||
},
|
|
||||||
set(target, prop, val) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//const locProxy = new Proxy(document.location, LocationHandler)
|
|
||||||
Object.defineProperty(document, '_location', {
|
|
||||||
writable: true,
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
value: l
|
|
||||||
});
|
|
||||||
Object.defineProperty(window.document, '_location', {
|
|
||||||
writable: true,
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
value: l
|
|
||||||
});
|
|
||||||
Object.defineProperty(window, '_location', {
|
|
||||||
writable: true,
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
value: l
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
rewriteUrl(link) {
|
|
||||||
if (!link) {
|
|
||||||
link = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
var rewritten;
|
|
||||||
|
|
||||||
if (link.startsWith('https://') || link.startsWith('http://') || link.startsWith('//')) {
|
|
||||||
if (link.startsWith('//')) {
|
|
||||||
rewritten = 'https:' + link;
|
|
||||||
} else {
|
|
||||||
rewritten = link;
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
if (link.startsWith('.')) {
|
|
||||||
let offset = 1;
|
|
||||||
if (link.startsWith('..')) {
|
|
||||||
offset = 2;
|
|
||||||
}
|
|
||||||
let file = link.substr(link.indexOf('.') + 1 + offset, link.length)
|
|
||||||
|
|
||||||
rewritten = this.url.hostname + file
|
|
||||||
} else {
|
|
||||||
if (link.startsWith('/')) {
|
|
||||||
rewritten = this.host + link
|
|
||||||
} else {
|
|
||||||
rewritten = this.host + '/' + link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var exceptions = ['about:', 'mailto:', 'javascript:', 'data:']
|
|
||||||
let needstowrite = true;
|
|
||||||
for (let i = 0; i < exceptions.length; i++) {
|
|
||||||
if (link.startsWith(exceptions[i])) {
|
|
||||||
needstowrite = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (needstowrite) {
|
|
||||||
rewritten = location.protocol + '//' + this.bareEndpoint + '/' + rewritten
|
|
||||||
return (rewritten);
|
|
||||||
} else {
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rewriteSrcset(sample) {
|
|
||||||
return sample.split(',').map(e => {
|
|
||||||
return (e.split(' ').map(a => {
|
|
||||||
if (a.startsWith('http') || (a.startsWith('/') && !a.startsWith(this.prefix))) {
|
|
||||||
var url = this.rewriteUrl(url);
|
|
||||||
}
|
|
||||||
return a.replace(a, (url || a))
|
|
||||||
}).join(' '))
|
|
||||||
}).join(',')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rewriting of data types
|
|
||||||
|
|
||||||
// CSS
|
|
||||||
class CSSRewriter extends Cyclone {
|
|
||||||
rewriteCSS(tag) {
|
|
||||||
var styles = window.getComputedStyle(tag)
|
|
||||||
var _values = styles['_values']
|
|
||||||
|
|
||||||
var prop = styles.getPropertyValue('background-image')
|
|
||||||
var name = "background-image"
|
|
||||||
|
|
||||||
if (prop == "") {
|
|
||||||
if (!styles.getPropertyValue('background') == "") {
|
|
||||||
prop = styles.getPropertyValue('background')
|
|
||||||
name = "background"
|
|
||||||
} else {
|
|
||||||
name = "";
|
|
||||||
prop = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prop.includes("url(")) {
|
|
||||||
var start = prop.indexOf('url(') + 4
|
|
||||||
var end = prop.indexOf(')') - 4
|
|
||||||
|
|
||||||
var url = prop.substring(start, end).toString('ascii');
|
|
||||||
|
|
||||||
if (url.startsWith(location.origin)) {
|
|
||||||
url = url.split(location.origin)
|
|
||||||
} else {
|
|
||||||
url = url.slice(url.indexOf(location.origin));
|
|
||||||
}
|
|
||||||
|
|
||||||
url = this.rewriteUrl(url)
|
|
||||||
tag.style[name] = url
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// JS
|
|
||||||
|
|
||||||
class JavaScriptRewriter extends Cyclone {
|
|
||||||
constructor(proxy) {
|
|
||||||
super();
|
|
||||||
//Proxied methods
|
|
||||||
this.setAttrCy = HTMLElement.prototype.setAttribute;
|
|
||||||
this.getAttrCy = HTMLElement.prototype.getAttribute;
|
|
||||||
this.proxy = proxy
|
|
||||||
}
|
|
||||||
|
|
||||||
rewriteJavascript(js) {
|
|
||||||
var javascript = js.replace(/window\.location/g, 'document._location')
|
|
||||||
javascript = javascript.replace(/document\.location/g, 'document._location')
|
|
||||||
return javascript
|
|
||||||
}
|
|
||||||
|
|
||||||
setAttribute(attr, value, mode) {
|
|
||||||
const setAttrCy = HTMLElement.prototype.setAttribute;
|
|
||||||
|
|
||||||
if (mode) {
|
|
||||||
this.setAttrCy.call(this, attr, value);
|
|
||||||
} else {
|
|
||||||
var url = attr
|
|
||||||
if (cyclone.targetAttrs.includes(attr)) {
|
|
||||||
url = cyclone.rewriteUrl(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
setAttrCy.call(this, attr, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getAttribute(attrN, mode) {
|
|
||||||
const getAttrCy = HTMLElement.prototype.getAttribute;
|
|
||||||
|
|
||||||
if (mode) {
|
|
||||||
return getAttrCy.call(this, attrN);
|
|
||||||
} else {
|
|
||||||
var val = getAttrCy.call(this, attrN);
|
|
||||||
if (cyclone.targetAttrs.includes(attrN)) {
|
|
||||||
val = getAttrCy.call(this, 'data-origin-' + attrN);
|
|
||||||
}
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HTML
|
|
||||||
class HTMLRewriter extends Cyclone {
|
|
||||||
rewriteElement(element) {
|
|
||||||
var targetAttrs = this.targetAttrs;
|
|
||||||
var attrs;
|
|
||||||
try {
|
|
||||||
attrs = [...element.attributes || {}].reduce((attrs, attribute) => {
|
|
||||||
attrs[attribute.name] = attribute.value;
|
|
||||||
return attrs;
|
|
||||||
}, {});
|
|
||||||
} catch {
|
|
||||||
attrs = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element.__proto__.getAttribute) {
|
|
||||||
var jsWrite = new JavaScriptRewriter();
|
|
||||||
var elementAttributes = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < targetAttrs.length; i++) {
|
|
||||||
var attr = targetAttrs[i]
|
|
||||||
var attrName = Object.keys(attrs)[i];
|
|
||||||
var data = {
|
|
||||||
name: attr,
|
|
||||||
value: element.getAttribute('data-origin-' + attr, 'cyclone') || element.getAttribute(attr, 'cyclone')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.value) {
|
|
||||||
elementAttributes.push(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element.nonce) {
|
|
||||||
element.setAttribute('nononce', element.nonce, '')
|
|
||||||
element.removeAttribute('nonce')
|
|
||||||
}
|
|
||||||
if (element.integrity) {
|
|
||||||
element.setAttribute('nointegrity', element.integrity, '')
|
|
||||||
element.removeAttribute('integrity')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element.tagName == "script") {
|
|
||||||
if (!element.getAttribute('src')) {
|
|
||||||
var jsRewrite = new JavaScriptRewriter();
|
|
||||||
element.innerHTML = jsRewrite.rewriteJavascript(element.innerHTML)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Css
|
|
||||||
var cssRewrite = new CSSRewriter();
|
|
||||||
cssRewrite.rewriteCSS(element)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < elementAttributes.length; i++) {
|
|
||||||
var attr = elementAttributes[i];
|
|
||||||
var attrName = attr.name;
|
|
||||||
var value = attr.value;
|
|
||||||
|
|
||||||
var bareValue = this.rewriteUrl(value);
|
|
||||||
if (attrName == "srcset" || attrName == 'srcset') {
|
|
||||||
bareValue = this.rewriteSrcset(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
element.setAttribute(attrName, bareValue);
|
|
||||||
element.setAttribute("data-origin-" + attrName, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rewriteDocument() {
|
|
||||||
var docElements = document.querySelectorAll('*');
|
|
||||||
for (var i = 0; i < docElements.length; i++) {
|
|
||||||
var element = docElements[i];
|
|
||||||
|
|
||||||
this.rewriteElement(element)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rewriteiFrame(iframe) {
|
|
||||||
var frameDoc = (iframe.contentWindow || iframe.contentDocument || iframe.document);
|
|
||||||
|
|
||||||
let tags = frameDoc.querySelectorAll('*')
|
|
||||||
|
|
||||||
for (var i = 0; i < tags.length; i++) {
|
|
||||||
var tag = tags[i]
|
|
||||||
this.rewriteElement(tag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rewriteDocObject(docObj) {
|
|
||||||
var docElements = docObj.querySelectorAll('*');
|
|
||||||
for (var i = 0; i < docElements.length; i++) {
|
|
||||||
var element = docElements[i];
|
|
||||||
|
|
||||||
this.rewriteElement(element)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const cyclone = new Cyclone();
|
|
||||||
|
|
||||||
const htmlRewriter = new HTMLRewriter();
|
|
||||||
|
|
||||||
const FetchIntercept = window.fetch;
|
|
||||||
window.fetch = async(...args) => {
|
|
||||||
let [resource, config] = args;
|
|
||||||
resource = cyclone.rewriteUrl(resource);
|
|
||||||
|
|
||||||
const response = await FetchIntercept(resource, config);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
const MessageIntercept = window.postMessage;
|
|
||||||
const messageInterceptionFunc = (...args) => {
|
|
||||||
let [message, target, config] = args;
|
|
||||||
target = cyclone.rewriteUrl(target);
|
|
||||||
|
|
||||||
const response = MessageIntercept(message, target, config);
|
|
||||||
console.log(response);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.defineProperty(window, 'postMessage', {
|
|
||||||
writable: false,
|
|
||||||
value: messageInterceptionFunc
|
|
||||||
})
|
|
||||||
|
|
||||||
var CWOriginal = Object.getOwnPropertyDescriptor(window.HTMLIFrameElement.prototype, 'contentWindow')
|
|
||||||
|
|
||||||
Object.defineProperty(window.HTMLIFrameElement.prototype, 'contentWindow', {
|
|
||||||
get() {
|
|
||||||
var iWindow = CWOriginal.get.call(this);
|
|
||||||
htmlRewriter.rewriteiFrame(iWindow);
|
|
||||||
|
|
||||||
return iWindow
|
|
||||||
},
|
|
||||||
set() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
const open = XMLHttpRequest.prototype.open;
|
|
||||||
XMLHttpRequest.prototype.open = function(method, url, ...rest) {
|
|
||||||
url = cyclone.rewriteUrl(url)
|
|
||||||
|
|
||||||
return open.call(this, method, url, ...rest);
|
|
||||||
};
|
|
||||||
|
|
||||||
var oPush = window.history.pushState;
|
|
||||||
var oPlace = window.history.replaceState;
|
|
||||||
|
|
||||||
function CycloneStates(dat, unused, url) {
|
|
||||||
var cyUrl = cyclone.rewriteUrl(url);
|
|
||||||
|
|
||||||
oPush.call(this, dat, unused, cyUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.history.pushState = CycloneStates
|
|
||||||
window.history.replaceState = CycloneStates
|
|
||||||
history.pushState = CycloneStates
|
|
||||||
history.replaceState = CycloneStates
|
|
||||||
|
|
||||||
const OriginalWebsocket = window.WebSocket
|
|
||||||
const ProxiedWebSocket = function() {
|
|
||||||
const ws = new OriginalWebsocket(...arguments)
|
|
||||||
|
|
||||||
const originalAddEventListener = ws.addEventListener
|
|
||||||
const proxiedAddEventListener = function() {
|
|
||||||
if (arguments[0] === "message") {
|
|
||||||
const cb = arguments[1]
|
|
||||||
arguments[1] = function() {
|
|
||||||
var origin = arguments[0].origin
|
|
||||||
arguments[0].origin = cyclone.rewriteUrl(origin);
|
|
||||||
|
|
||||||
return cb.apply(this, arguments)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return originalAddEventListener.apply(this, arguments)
|
|
||||||
}
|
|
||||||
ws.addEventListener = proxiedAddEventListener
|
|
||||||
|
|
||||||
Object.defineProperty(ws, "onmessage", {
|
|
||||||
set(func) {
|
|
||||||
return proxiedAddEventListener.apply(this, [
|
|
||||||
"message",
|
|
||||||
func,
|
|
||||||
false
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return ws;
|
|
||||||
};
|
|
||||||
|
|
||||||
window.WebSocket = ProxiedWebSocket;
|
|
||||||
|
|
||||||
// Request
|
|
||||||
var requestProxyHandler = {
|
|
||||||
get(target, prop, receiver) {
|
|
||||||
console.log(target);
|
|
||||||
if (prop == "url") {
|
|
||||||
return 'the j';
|
|
||||||
}
|
|
||||||
|
|
||||||
return Reflect.get(...arguments);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Request.prototype = new Proxy(Request.prototype, requestProxyHandler);
|
|
||||||
Request.__proto__ = new Proxy(Request.__proto__, requestProxyHandler);
|
|
||||||
|
|
||||||
const nwtb = window.open
|
|
||||||
|
|
||||||
function openNewTab(url, target, features) {
|
|
||||||
url = cyclone.rewriteUrl(url)
|
|
||||||
nwtb(url, target, features)
|
|
||||||
}
|
|
||||||
|
|
||||||
window.open = openNewTab;
|
|
||||||
|
|
||||||
window.onload = function() {
|
|
||||||
for (var i = 0; i < 50; i++) {
|
|
||||||
setTimeout(() => {
|
|
||||||
htmlRewriter.rewriteDocument();
|
|
||||||
}, 500)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mutationE = new MutationObserver((mutationList, observer) => {
|
|
||||||
for (const mutation of mutationList) {
|
|
||||||
mutation.addedNodes.forEach(node => {
|
|
||||||
htmlRewriter.rewriteElement(node);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).observe(document, {
|
|
||||||
childList: true,
|
|
||||||
subtree: true
|
|
||||||
})
|
|
||||||
|
|
||||||
//For intercepting all requests
|
|
||||||
if (!document.serviceWorkerRegistered) {
|
|
||||||
if ('serviceWorker' in navigator) {
|
|
||||||
window.addEventListener('load', function() {
|
|
||||||
navigator.serviceWorker.register(location.origin + '/cySw.js').then(function(registration) {
|
|
||||||
console.log('Service worker registered with scope: ', registration.scope);
|
|
||||||
}, function(err) {
|
|
||||||
console.log('ServiceWorker registration failed: ', err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
document.serviceWorkerRegistered = true
|
|
||||||
}
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
import fs from 'fs';
|
|
||||||
|
|
||||||
const xor = {
|
|
||||||
encode: (url) => encodeURIComponent(url.toString().split("").map((char, ind) => ind % 2 ? String
|
|
||||||
.fromCharCode(char.charCodeAt() ^ 2) : char).join("")),
|
|
||||||
decode: (url) => decodeURIComponent(url.split("?")[0]).split("").map((char, ind) => ind % 2 ? String
|
|
||||||
.fromCharCode(char.charCodeAt(0) ^ 2) : char).join("") + (url.split("?").slice(1).length ? "?" +
|
|
||||||
url.split("?").slice(1).join("?") : "")
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBlockPage(site, reason) {
|
|
||||||
return `<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<style>
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@700&display=swap');
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: #ff4f4f;
|
|
||||||
color: white;
|
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: 54px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<center>
|
|
||||||
<p>Access Denied</p>
|
|
||||||
|
|
||||||
<div class="main">
|
|
||||||
<img src="/images/denied_sign.svg" width="200" onclick="location.pathname = '/service/google.com'">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<a style="position: absolute; bottom: 10; right: 0; left: 0; display: inline;">
|
|
||||||
Looks like ${site} is blocked for ${reason}
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</center>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>`
|
|
||||||
}
|
|
||||||
|
|
||||||
const blacklist = [
|
|
||||||
'netflix.com',
|
|
||||||
'www.netflix.com',
|
|
||||||
'accounts.google.com',
|
|
||||||
]
|
|
||||||
|
|
||||||
function filter(req, res) {
|
|
||||||
var decode = req.url.split("/service/")[1];
|
|
||||||
|
|
||||||
decode = decode.replace("http://", '')
|
|
||||||
decode = decode.replace("https://", '')
|
|
||||||
decode = decode.replace("http:/", '')
|
|
||||||
decode = decode.replace("https:/", '')
|
|
||||||
|
|
||||||
decode = 'https://' + decode;
|
|
||||||
|
|
||||||
var uri = new URL(decode);
|
|
||||||
|
|
||||||
var toBlock = (blacklist.includes(uri.host));
|
|
||||||
|
|
||||||
if (toBlock) {
|
|
||||||
var b = getBlockPage(uri.host, 'cyclone__DenyURL');
|
|
||||||
res.end(b);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
filter as
|
|
||||||
default
|
|
||||||
} // don't want Netflix's legal team to go sicko mode
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
import CryptoJS from 'crypto-js';
|
|
||||||
|
|
||||||
const encryptWithAES = (text) => {
|
|
||||||
const passphrase = '123';
|
|
||||||
return CryptoJS.AES.encrypt(text, passphrase).toString();
|
|
||||||
};
|
|
||||||
|
|
||||||
const decryptWithAES = (ciphertext) => {
|
|
||||||
const passphrase = '123';
|
|
||||||
const bytes = CryptoJS.AES.decrypt(ciphertext, passphrase);
|
|
||||||
const originalText = bytes.toString(CryptoJS.enc.Utf8);
|
|
||||||
return originalText;
|
|
||||||
};
|
|
||||||
|
|
||||||
export {
|
|
||||||
encryptWithAES as encrypt,
|
|
||||||
decryptWithAES as decrypt
|
|
||||||
}
|
|
||||||
|
|
@ -41,8 +41,6 @@
|
||||||
<br>
|
<br>
|
||||||
<li> <a style='color:black;' href="https://github.com/cohenerickson"> Cohen </a></li>
|
<li> <a style='color:black;' href="https://github.com/cohenerickson"> Cohen </a></li>
|
||||||
<br>
|
<br>
|
||||||
<li> <a style='color:black;' href="https://github.com/SmartCoder3000"> System32 </a></li>
|
|
||||||
<br>
|
|
||||||
<li> <a style='color:black;' href="https://github.com/schooldev49"> simplydeveloper </a></li>
|
<li> <a style='color:black;' href="https://github.com/schooldev49"> simplydeveloper </a></li>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
|
|
@ -67,7 +65,6 @@
|
||||||
<div style='color:black;'> Acknowledgements are resources Nebula is using/has used.
|
<div style='color:black;'> Acknowledgements are resources Nebula is using/has used.
|
||||||
<ul style='color:black;'>
|
<ul style='color:black;'>
|
||||||
<li><a style='color:black;' href="https://github.com/titaniumnetwork-dev/Ultraviolet">UV (one of the back-end proxy we use)</a></li>
|
<li><a style='color:black;' href="https://github.com/titaniumnetwork-dev/Ultraviolet">UV (one of the back-end proxy we use)</a></li>
|
||||||
<li><a style='color:black;' href="https://github.com/NebulaServices/Cyclone">Cyclone (one of the back-end proxy we use)</a></li>
|
|
||||||
<li><a style='color:black;' href="https://github.com/NebulaServices/Osana">Osana (one of the back-end proxy we use)</a></li>
|
<li><a style='color:black;' href="https://github.com/NebulaServices/Osana">Osana (one of the back-end proxy we use)</a></li>
|
||||||
<li><a style='color:black;' href="https://github.com/tomphttp/bare-server-node">Bare Server</a></li>
|
<li><a style='color:black;' href="https://github.com/tomphttp/bare-server-node">Bare Server</a></li>
|
||||||
<br>
|
<br>
|
||||||
|
|
@ -115,9 +112,8 @@
|
||||||
<a onclick="unsavedChanges();"> <select class="dropdown" id="proxySwitcher">
|
<a onclick="unsavedChanges();"> <select class="dropdown" id="proxySwitcher">
|
||||||
<option value="uv">UltraViolet</option>
|
<option value="uv">UltraViolet</option>
|
||||||
<option value="osana">Osana (beta)</option>
|
<option value="osana">Osana (beta)</option>
|
||||||
<option value="cyclone">Cyclone (Legacy)</option>
|
|
||||||
</select>
|
</select>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
<a onclick="saveIc();switchProxy()" class="button-save"> Apply </a>
|
<a onclick="saveIc();switchProxy()" class="button-save"> Apply </a>
|
||||||
|
|
|
||||||
|
|
@ -140,19 +140,6 @@ window.addEventListener('load', () => {
|
||||||
blob.body.appendChild(iframe)
|
blob.body.appendChild(iframe)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (proxy == 'cyclone') {
|
|
||||||
const value = event.target.firstElementChild.value;
|
|
||||||
|
|
||||||
let url = value.trim();
|
|
||||||
if (!isUrl(url)) url = 'www.google.com/search?q=' + url;
|
|
||||||
if (!(url.startsWith('https://') || url.startsWith('http://'))) url = 'http://' + url;
|
|
||||||
let redirectTo = '/cyclone/' + url;
|
|
||||||
|
|
||||||
const option = localStorage.getItem('nogg');
|
|
||||||
if (option === 'on') {
|
|
||||||
stealthEngine(redirectTo);
|
|
||||||
} else location.pathname = redirectTo;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1291,7 +1278,7 @@ console.log(day + ", " + formatAMPM(new Date))
|
||||||
// Search Result.
|
// Search Result.
|
||||||
|
|
||||||
const suggestFromString = async(input) => {
|
const suggestFromString = async(input) => {
|
||||||
var request = await fetch("https://tomphttp-bare.jimmynuetron.repl.co/v1/", { headers: { 'x-bare-host': 'duckduckgo.com', 'x-bare-protocol': 'https:', 'x-bare-path': '/ac/?q=' + encodeURIComponent(input), 'x-bare-port': '443', 'x-bare-headers': JSON.stringify({ Host: 'duckduckgo.com' }), 'x-bare-forward-headers': '[]' } });
|
var request = await fetch("/bare/v1/", { headers: { 'x-bare-host': 'duckduckgo.com', 'x-bare-protocol': 'https:', 'x-bare-path': '/ac/?q=' + encodeURIComponent(input), 'x-bare-port': '443', 'x-bare-headers': JSON.stringify({ Host: 'duckduckgo.com' }), 'x-bare-forward-headers': '[]' } });
|
||||||
var json = await request.json();
|
var json = await request.json();
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -154,19 +154,6 @@ scope: '/service/'
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (proxy == 'cyclone') {
|
|
||||||
const value = event.target.firstElementChild.value;
|
|
||||||
|
|
||||||
let url = value.trim();
|
|
||||||
if (!isUrl(url)) url = 'www.google.com/search?q=' + url;
|
|
||||||
if (!(url.startsWith('https://') || url.startsWith('http://'))) url = 'http://' + url;
|
|
||||||
let redirectTo = '/service/next/' + url;
|
|
||||||
|
|
||||||
const option = localStorage.getItem('nogg');
|
|
||||||
if (option === 'on') {
|
|
||||||
stealthEngine(redirectTo);
|
|
||||||
} else location.pathname = redirectTo;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1311,7 +1298,7 @@ console.log(day + ", " + formatAMPM(new Date))
|
||||||
// Search Result.
|
// Search Result.
|
||||||
|
|
||||||
const suggestFromString = async(input) => {
|
const suggestFromString = async(input) => {
|
||||||
var request = await fetch("https://tomphttp-bare.jimmynuetron.repl.co/v1/", { headers: { 'x-bare-host': 'duckduckgo.com', 'x-bare-protocol': 'https:', 'x-bare-path': '/ac/?q=' + encodeURIComponent(input), 'x-bare-port': '443', 'x-bare-headers': JSON.stringify({ Host: 'duckduckgo.com' }), 'x-bare-forward-headers': '[]' } });
|
var request = await fetch("/bare/v1", { headers: { 'x-bare-host': 'duckduckgo.com', 'x-bare-protocol': 'https:', 'x-bare-path': '/ac/?q=' + encodeURIComponent(input), 'x-bare-port': '443', 'x-bare-headers': JSON.stringify({ Host: 'duckduckgo.com' }), 'x-bare-forward-headers': '[]' } });
|
||||||
var json = await request.json();
|
var json = await request.json();
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue