Better theme system + updated Cyclone
This commit is contained in:
parent
0f218baf9e
commit
1cd37529aa
19 changed files with 2261 additions and 1159 deletions
3
app.js
3
app.js
|
|
@ -1,3 +1,4 @@
|
||||||
(async() => {
|
(async() => {
|
||||||
await import('./app.mjs');
|
await
|
||||||
|
import ('./app.mjs');
|
||||||
})();
|
})();
|
||||||
16
app.mjs
16
app.mjs
|
|
@ -5,6 +5,13 @@ import nodeStatic from 'node-static';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import * as custombare from './static/customBare.mjs';
|
import * as custombare from './static/customBare.mjs';
|
||||||
|
|
||||||
|
|
||||||
|
const httpPort = 80;
|
||||||
|
const httpsPort = 443;
|
||||||
|
const debug = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const bareServer = createBareServer('/bare/', {
|
const bareServer = createBareServer('/bare/', {
|
||||||
logErrors: false,
|
logErrors: false,
|
||||||
localAddress: undefined,
|
localAddress: undefined,
|
||||||
|
|
@ -41,6 +48,9 @@ httpsServer.on('upgrade', upgrade);
|
||||||
|
|
||||||
function request(request, response) {
|
function request(request, response) {
|
||||||
if (custombare.route(request, response)) return true;
|
if (custombare.route(request, response)) return true;
|
||||||
|
if (debug === true) {
|
||||||
|
console.log(`[${request.method}] - ${request.url} - LINK: ${request.headers['host']} - AGENT: ${request.headers['user-agent']}`);
|
||||||
|
}
|
||||||
|
|
||||||
if (bareServer.shouldRoute(request)) {
|
if (bareServer.shouldRoute(request)) {
|
||||||
bareServer.routeRequest(request, response);
|
bareServer.routeRequest(request, response);
|
||||||
|
|
@ -57,7 +67,7 @@ function upgrade (req, socket, head) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
httpServer.listen(80);
|
httpServer.listen(httpPort);
|
||||||
httpsServer.listen(443);
|
httpsServer.listen(httpsPort);
|
||||||
|
|
||||||
console.log("Server running on port 80 and 443.");
|
console.log("Server running on http://localhost:" + httpPort + " and https://localhost:" + httpsPort);
|
||||||
169
package-lock.json
generated
169
package-lock.json
generated
|
|
@ -10,22 +10,47 @@
|
||||||
"license": "Copyright Nebula Services. All Rights Reserved.",
|
"license": "Copyright Nebula Services. All Rights Reserved.",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tomphttp/bare-server-node": "^1.0.2-beta-readme5",
|
"@tomphttp/bare-server-node": "^1.0.2-beta-readme5",
|
||||||
|
"bare-server-node": "github:tomphttp/bare-server-node",
|
||||||
|
"crypto-js": "4.1.1",
|
||||||
|
"css-tree": "^2.1.0",
|
||||||
"node-fetch": "^3.2.6",
|
"node-fetch": "^3.2.6",
|
||||||
"node-static": "^0.7.11"
|
"node-static": "^0.7.11",
|
||||||
|
"ws": "^8.8.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tomphttp/bare-server-node": {
|
"node_modules/@tomphttp/bare-server-node": {
|
||||||
"version": "1.0.2-beta-readme5",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@tomphttp/bare-server-node/-/bare-server-node-1.0.2-beta-readme5.tgz",
|
"resolved": "https://registry.npmjs.org/@tomphttp/bare-server-node/-/bare-server-node-1.0.3.tgz",
|
||||||
"integrity": "sha512-WOYNae3faSj9Yt4dKVqzjbh1ovpKRhsevnJaM2BgC6LkRULFN/GhtslXDXG6KLbqeokFFj0XqpZ8TTzdxKyhkw==",
|
"integrity": "sha512-mKMipi9qntDy3wcalWGuK3iKzM0XQT4sW3E6yRXeIU4BxFZVSLzSDejPxL6wWwniKGm0faSwZ4Pk0dQ04JEFNA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commander": "^9.0.0",
|
"commander": "^9.0.0",
|
||||||
"dotenv": "^16.0.1",
|
"dotenv": "^16.0.1",
|
||||||
"fetch-headers": "^3.0.1",
|
"headers-polyfill": "^3.0.10",
|
||||||
"http-errors": "^2.0.0"
|
"http-errors": "^2.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"bare-server-node": "scripts/start.js"
|
"bare-server-node": "scripts/cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/bare-server-node": {
|
||||||
|
"name": "@tomphttp/bare-server-node",
|
||||||
|
"version": "1.0.3-deps2",
|
||||||
|
"resolved": "git+ssh://git@github.com/tomphttp/bare-server-node.git#c5a87ef6c063c4728bb88a362db9581f26be2225",
|
||||||
|
"license": "GPL-3.0",
|
||||||
|
"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": {
|
||||||
|
"node": ">=16.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/colors": {
|
"node_modules/colors": {
|
||||||
|
|
@ -44,6 +69,24 @@
|
||||||
"node": "^12.20.0 || >=14"
|
"node": "^12.20.0 || >=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/crypto-js": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
|
||||||
|
},
|
||||||
|
"node_modules/css-tree": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-PcysZRzToBbrpoUrZ9qfblRIRf8zbEAkU0AIpQFtgkFK0vSbzOmBCvdSAx2Zg7Xx5wiYJKUKk0NMP7kxevie/A==",
|
||||||
|
"dependencies": {
|
||||||
|
"mdn-data": "2.0.27",
|
||||||
|
"source-map-js": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
|
||||||
|
"npm": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/data-uri-to-buffer": {
|
"node_modules/data-uri-to-buffer": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
|
||||||
|
|
@ -90,24 +133,6 @@
|
||||||
"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",
|
||||||
|
|
@ -119,6 +144,11 @@
|
||||||
"node": ">=12.20.0"
|
"node": ">=12.20.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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",
|
||||||
|
|
@ -139,6 +169,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/mdn-data": {
|
||||||
|
"version": "2.0.27",
|
||||||
|
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.27.tgz",
|
||||||
|
"integrity": "sha512-kwqO0I0jtWr25KcfLm9pia8vLZ8qoAKhWZuZMbneJq3jjBD3gl5nZs8l8Tu3ZBlBAHVQtDur9rdDGyvtfVraHQ=="
|
||||||
|
},
|
||||||
"node_modules/mime": {
|
"node_modules/mime": {
|
||||||
"version": "1.6.0",
|
"version": "1.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||||
|
|
@ -220,6 +255,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/source-map-js": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/statuses": {
|
"node_modules/statuses": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||||
|
|
@ -251,17 +294,47 @@
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ws": {
|
||||||
|
"version": "8.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz",
|
||||||
|
"integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": "^5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tomphttp/bare-server-node": {
|
"@tomphttp/bare-server-node": {
|
||||||
"version": "1.0.2-beta-readme5",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@tomphttp/bare-server-node/-/bare-server-node-1.0.2-beta-readme5.tgz",
|
"resolved": "https://registry.npmjs.org/@tomphttp/bare-server-node/-/bare-server-node-1.0.3.tgz",
|
||||||
"integrity": "sha512-WOYNae3faSj9Yt4dKVqzjbh1ovpKRhsevnJaM2BgC6LkRULFN/GhtslXDXG6KLbqeokFFj0XqpZ8TTzdxKyhkw==",
|
"integrity": "sha512-mKMipi9qntDy3wcalWGuK3iKzM0XQT4sW3E6yRXeIU4BxFZVSLzSDejPxL6wWwniKGm0faSwZ4Pk0dQ04JEFNA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"commander": "^9.0.0",
|
"commander": "^9.0.0",
|
||||||
"dotenv": "^16.0.1",
|
"dotenv": "^16.0.1",
|
||||||
"fetch-headers": "^3.0.1",
|
"headers-polyfill": "^3.0.10",
|
||||||
|
"http-errors": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bare-server-node": {
|
||||||
|
"version": "git+ssh://git@github.com/tomphttp/bare-server-node.git#c5a87ef6c063c4728bb88a362db9581f26be2225",
|
||||||
|
"from": "bare-server-node@github:tomphttp/bare-server-node",
|
||||||
|
"requires": {
|
||||||
|
"commander": "^9.0.0",
|
||||||
|
"dotenv": "^16.0.1",
|
||||||
|
"headers-polyfill": "^3.0.10",
|
||||||
"http-errors": "^2.0.0"
|
"http-errors": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -275,6 +348,20 @@
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz",
|
||||||
"integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw=="
|
"integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw=="
|
||||||
},
|
},
|
||||||
|
"crypto-js": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
|
||||||
|
},
|
||||||
|
"css-tree": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-PcysZRzToBbrpoUrZ9qfblRIRf8zbEAkU0AIpQFtgkFK0vSbzOmBCvdSAx2Zg7Xx5wiYJKUKk0NMP7kxevie/A==",
|
||||||
|
"requires": {
|
||||||
|
"mdn-data": "2.0.27",
|
||||||
|
"source-map-js": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"data-uri-to-buffer": {
|
"data-uri-to-buffer": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
|
||||||
|
|
@ -299,11 +386,6 @@
|
||||||
"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",
|
||||||
|
|
@ -312,6 +394,11 @@
|
||||||
"fetch-blob": "^3.1.2"
|
"fetch-blob": "^3.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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",
|
||||||
|
|
@ -329,6 +416,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||||
},
|
},
|
||||||
|
"mdn-data": {
|
||||||
|
"version": "2.0.27",
|
||||||
|
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.27.tgz",
|
||||||
|
"integrity": "sha512-kwqO0I0jtWr25KcfLm9pia8vLZ8qoAKhWZuZMbneJq3jjBD3gl5nZs8l8Tu3ZBlBAHVQtDur9rdDGyvtfVraHQ=="
|
||||||
|
},
|
||||||
"mime": {
|
"mime": {
|
||||||
"version": "1.6.0",
|
"version": "1.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||||
|
|
@ -378,6 +470,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
||||||
},
|
},
|
||||||
|
"source-map-js": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
|
||||||
|
},
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||||
|
|
@ -397,6 +494,12 @@
|
||||||
"version": "0.0.3",
|
"version": "0.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
|
||||||
"integrity": "sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw=="
|
"integrity": "sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw=="
|
||||||
|
},
|
||||||
|
"ws": {
|
||||||
|
"version": "8.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz",
|
||||||
|
"integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==",
|
||||||
|
"requires": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,12 @@
|
||||||
"author": "Nebula Services",
|
"author": "Nebula Services",
|
||||||
"license": "Copyright Nebula Services. All Rights Reserved.",
|
"license": "Copyright Nebula Services. All Rights Reserved.",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@tomphttp/bare-server-node": "^1.0.2-beta-readme5",
|
||||||
"bare-server-node": "github:tomphttp/bare-server-node",
|
"bare-server-node": "github:tomphttp/bare-server-node",
|
||||||
"css-tree": "^2.1.0",
|
"css-tree": "^2.1.0",
|
||||||
"node-fetch": "^3.2.6",
|
"node-fetch": "^3.2.6",
|
||||||
"node-static": "^0.7.11",
|
"node-static": "^0.7.11",
|
||||||
"ws": "^8.8.1"
|
"ws": "^8.8.1",
|
||||||
|
"crypto-js": "4.1.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,6 +3,8 @@ import { URL } from 'url';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import * as csstree from 'css-tree';
|
import * as csstree from 'css-tree';
|
||||||
import * as ws from 'ws';
|
import * as ws from 'ws';
|
||||||
|
import filter from './cyclone/filter.cyclone.mjs';
|
||||||
|
import * as security from './cyclone/security.cyclone.mjs';
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
prefix: "/service",
|
prefix: "/service",
|
||||||
|
|
@ -10,10 +12,6 @@ const config = {
|
||||||
defaultHeaders: {
|
defaultHeaders: {
|
||||||
'X-Content-Type-Options': 'no-sniff',
|
'X-Content-Type-Options': 'no-sniff',
|
||||||
},
|
},
|
||||||
//proxy: {
|
|
||||||
// host: "3.211.17.212",
|
|
||||||
// port: "80"
|
|
||||||
//} // HTTP Proxy
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.requireSSL) {
|
if (config.requireSSL) {
|
||||||
|
|
@ -23,9 +21,9 @@ if (config.requireSSL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function rewriteJavascript(js) {
|
function rewriteJavascript(js) {
|
||||||
var javascript = js.replace('window.location', 'document._dlocation')
|
var javascript = js.replace(/window\.location/g, 'window._dlocation')
|
||||||
javascript = javascript.replace('document.location', 'document._dlocation')
|
javascript = javascript.replace(/document\.location/g, 'document._dlocation')
|
||||||
javascript = javascript.replace('location.', 'document._location.')
|
javascript = javascript.replace(/location\./g, '_location.')
|
||||||
return javascript
|
return javascript
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -33,14 +31,14 @@ function insertScript(html) {
|
||||||
var res = `<!DOCTYPE html>
|
var res = `<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<script preload src="/cyclone/cyclone.js"></script>
|
<script preload src="/cyclone.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
${html}
|
${html}
|
||||||
</body>
|
</body>
|
||||||
</html>`
|
</html>`
|
||||||
return res
|
return res
|
||||||
} //
|
}
|
||||||
|
|
||||||
async function fetchBare(url, res, req) {
|
async function fetchBare(url, res, req) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -60,7 +58,6 @@ async function fetchBare(url, res, req) {
|
||||||
text() {
|
text() {
|
||||||
return 'Error: ' + e;
|
return 'Error: ' + e;
|
||||||
},
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,14 +89,12 @@ async function fetchBare(url, res, req) {
|
||||||
} else {
|
} else {
|
||||||
request.body.pipe(res)
|
request.body.pipe(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
res.writeHead(500, 'Error', {
|
res.writeHead(500, 'Error', {
|
||||||
'content-type': 'application/javascript'
|
'content-type': 'application/javascript'
|
||||||
})
|
})
|
||||||
res.end(e)
|
res.end(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,13 +106,17 @@ function route(req, res) {
|
||||||
var path = req.url;
|
var path = req.url;
|
||||||
|
|
||||||
if (path.startsWith(config.prefix + "/")) {
|
if (path.startsWith(config.prefix + "/")) {
|
||||||
|
var decoded = path.split(config.prefix + "/")[1];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var url = new URL(path.split(config.prefix + "/")[1])
|
var url = new URL(decoded);
|
||||||
} catch {
|
} catch {
|
||||||
var url = new URL("https://" + path.split(config.prefix + "/")[1])
|
var url = new URL("https://" + decoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchBare(url, res,req);
|
if (filter(req, res)) return;
|
||||||
|
|
||||||
|
return fetchBare(url, res, req);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -132,9 +131,9 @@ function routeSocket(req, socket) {
|
||||||
var path = req.url;
|
var path = req.url;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var url = new URL(path.split(config.prefix + "/")[1])
|
var url = new URL(path(config.prefix + "/")[1])
|
||||||
} catch {
|
} catch {
|
||||||
var url = new URL("wss://" + path.split(config.prefix + "/")[1])
|
var url = new URL("wss://" + path(config.prefix + "/")[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(url);
|
console.log(url);
|
||||||
|
|
|
||||||
|
|
@ -1,442 +0,0 @@
|
||||||
const config = {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class Cyclone {
|
|
||||||
constructor() {
|
|
||||||
this.tmp = location.pathname.split('/service')[1]
|
|
||||||
|
|
||||||
this.tmp = this.tmp.substring(1, 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, 'window._dlocation')
|
|
||||||
javascript = javascript.replace(/document\.location/g, 'document._dlocation')
|
|
||||||
javascript = javascript.replace(/location\./g, '_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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
476
static/cyclone/cyclone.js
Normal file
476
static/cyclone/cyclone.js
Normal file
|
|
@ -0,0 +1,476 @@
|
||||||
|
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
|
||||||
|
}
|
||||||
82
static/cyclone/filter.cyclone.mjs
Normal file
82
static/cyclone/filter.cyclone.mjs
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
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
|
||||||
18
static/cyclone/security.cyclone.mjs
Normal file
18
static/cyclone/security.cyclone.mjs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html style="--background-primary:#191724; --navbar-color:#26233a; --navbar-height:4em; --navbar-text-color:#e0def4; --input-text-color:#e0def4; --input-placeholder-color:#6e6a86; --input-background-color:#1f1d2e; --input-border-color:#eb6f92; --input-border-size:#3F51B5;">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>Nebula</title>
|
<title>Nebula</title>
|
||||||
|
|
@ -7,14 +7,13 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<!-- Stylesheets -->
|
<!-- Stylesheets -->
|
||||||
<script src="resources/nebula.bundle.js"></script>
|
<script src="resources/nebula.bundle.js"></script>
|
||||||
<link rel="stylesheet" href="style/master.css">
|
|
||||||
<link rel="stylesheet" href="style/main.css">
|
<link rel="stylesheet" href="style/main.css">
|
||||||
<!-- Embed -->
|
<!-- Embed -->
|
||||||
<meta name="theme-color" content="#eb6f92">
|
<meta name="theme-color" content="#eb6f92">
|
||||||
<meta property="og:title" content="Nebula">
|
<meta property="og:title" content="Nebula">
|
||||||
<meta property="og:type" content="website">
|
<meta property="og:type" content="website">
|
||||||
<meta property="og:image" content="/images/logo.png">
|
<meta property="og:image" content="/images/logo.png">
|
||||||
<meta property="og:description" content="">
|
<meta property="og:description" content="Nebula Web">
|
||||||
<script>
|
<script>
|
||||||
if (location.protocol === "http:" && location.host !== "localhost") location.protocol = "https:";
|
if (location.protocol === "http:" && location.host !== "localhost") location.protocol = "https:";
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -27,7 +26,7 @@
|
||||||
<script src="uv/uv.config.js"></script>
|
<script src="uv/uv.config.js"></script>
|
||||||
<div id="navbar">
|
<div id="navbar">
|
||||||
<img src='images/logo.png' id="thumbImg" style='height: 90%; margin-left: 5%; border-radius: 5px; '>
|
<img src='images/logo.png' id="thumbImg" style='height: 90%; margin-left: 5%; border-radius: 5px; '>
|
||||||
<h1 class="nebHeader" style='margin-left: .5%; font-family: "Roboto"; color: #4de0fa'>nebula.</h1>
|
<h1 class="nebHeader">nebula.</h1>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
|
||||||
|
|
@ -75,7 +74,7 @@
|
||||||
|
|
||||||
<!-- Stamp -->
|
<!-- Stamp -->
|
||||||
<div>
|
<div>
|
||||||
<p class="stamp"> © Nebula Services. All rights reserved. </p>
|
<p class="stamp"> Nebula Copyright (©) Nebula Services 2022 </p>
|
||||||
<a class="github" href="https://github.com/NebulaServices/Nebula">GitHub</a>
|
<a class="github" href="https://github.com/NebulaServices/Nebula">GitHub</a>
|
||||||
<a class="tos" href="privacy/">Privacy</a>
|
<a class="tos" href="privacy/">Privacy</a>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
<script src="uv/uv.config.js"></script>
|
<script src="uv/uv.config.js"></script>
|
||||||
<div id="navbar">
|
<div id="navbar">
|
||||||
<img src='/images/logo.png' style='height: 90%; margin-left: 5%; border-radius: 5px; '>
|
<img src='/images/logo.png' style='height: 90%; margin-left: 5%; border-radius: 5px; '>
|
||||||
<h1 style='margin-left: .5%; font-family: "Roboto"; color: #4de0fa'>nebula</h1>
|
<h1 class="htext">nebula</h1>
|
||||||
|
|
||||||
<h1 style='margin-left: .5%; font-family: "Roboto"; color: #838282; font-size: 15px; bottom: 0; padding-top: 15px;'>mobile</h1>
|
<h1 style='margin-left: .5%; font-family: "Roboto"; color: #838282; font-size: 15px; bottom: 0; padding-top: 15px;'>mobile</h1>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,8 @@
|
||||||
<p class="name"> Stealth Mode</p>
|
<p class="name"> Stealth Mode</p>
|
||||||
<p class="description">Stops extensions from peeping</p>
|
<p class="description">Stops extensions from peeping</p>
|
||||||
|
|
||||||
<input class="setting-input" id="undefined" type="checkbox" onclick="saveIc();toggleNoGG()">
|
<input id="undefined" type="checkbox" onclick="saveIc();toggleNoGG()">
|
||||||
<label for="undefined" class="toogle-button"></label>
|
<label for="undefined"></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-cont">
|
<div class="settings-cont">
|
||||||
|
|
@ -66,7 +66,8 @@
|
||||||
<span class="custom-dropdown big">
|
<span class="custom-dropdown big">
|
||||||
<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="cyclone">Cyclone</option>
|
<option value="cyclone">Cyclone (BETA)</option>
|
||||||
|
<option value="osana" disabled>Osana (BETA)</option>
|
||||||
</select>
|
</select>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
@ -85,7 +86,7 @@
|
||||||
<a onclick="unsavedChanges();"> <select class="dropdown" id="themeSwitcher">
|
<a onclick="unsavedChanges();"> <select class="dropdown" id="themeSwitcher">
|
||||||
<option value="dark">Shades</option>
|
<option value="dark">Shades</option>
|
||||||
<option value="light">Blizzard</option>
|
<option value="light">Blizzard</option>
|
||||||
<option value="hacker">Hacker</option>
|
<option value="custom">Custom (Beta)</option>
|
||||||
</select>
|
</select>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
@ -101,7 +102,7 @@
|
||||||
<div id='sidebar'>
|
<div id='sidebar'>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="stamp"> Version 7.1 (Public Release) | © Nebula Services 2021 - Present</p>
|
<p class="stamp"> Version 7.1.1 (Public Release) | Nebula Copyright (©) Nebula Services 2022 </p>
|
||||||
|
|
||||||
<!-- Panelbear -->
|
<!-- Panelbear -->
|
||||||
<script async src="https://cdn.panelbear.com/analytics.js?site=AZa75ZyiRRZ">
|
<script async src="https://cdn.panelbear.com/analytics.js?site=AZa75ZyiRRZ">
|
||||||
|
|
|
||||||
1009
static/resources/cryptojs.min.js
vendored
Normal file
1009
static/resources/cryptojs.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -4,6 +4,7 @@
|
||||||
// #################################################################################################################################################
|
// #################################################################################################################################################
|
||||||
// Copyright Nebula Services 2021-2022
|
// Copyright Nebula Services 2021-2022
|
||||||
// Form.js
|
// Form.js
|
||||||
|
// For the submission of the URL form to the server.
|
||||||
// #################################################################################################################################################
|
// #################################################################################################################################################
|
||||||
// #################################################################################################################################################
|
// #################################################################################################################################################
|
||||||
// #################################################################################################################################################
|
// #################################################################################################################################################
|
||||||
|
|
@ -131,7 +132,8 @@ window.addEventListener('load', () => {
|
||||||
// #################################################################################################################################################
|
// #################################################################################################################################################
|
||||||
// #################################################################################################################################################
|
// #################################################################################################################################################
|
||||||
// Copyright Nebula Services 2021-2022
|
// Copyright Nebula Services 2021-2022
|
||||||
// Options.js
|
// settings.js
|
||||||
|
// For the settings of the application.
|
||||||
// #################################################################################################################################################
|
// #################################################################################################################################################
|
||||||
// #################################################################################################################################################
|
// #################################################################################################################################################
|
||||||
// #################################################################################################################################################
|
// #################################################################################################################################################
|
||||||
|
|
@ -154,37 +156,6 @@ function toggleNoGG() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Notification Banner
|
|
||||||
function saveIc() {
|
|
||||||
console.log("Checked")
|
|
||||||
var notification = `
|
|
||||||
<div class="notification-container" id="notification-container">
|
|
||||||
<div class="notification notification-success">
|
|
||||||
<strong>Success!</strong> Your settings have been saved - Reloading.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
document.getElementById('notifhere').innerHTML = notification
|
|
||||||
setTimeout(() => {
|
|
||||||
var NotificationOBJ = document.getElementById('notifhere')
|
|
||||||
|
|
||||||
}, 2000);
|
|
||||||
};
|
|
||||||
|
|
||||||
function unsavedChanges() {
|
|
||||||
var notification = `
|
|
||||||
<div class="notification-container" id="notification-container">
|
|
||||||
<div class="notification notification-danger" id="notification-container">
|
|
||||||
<strong>Danger!</strong> You have unsaved changes!
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
document.getElementById('notifhere').innerHTML = notification
|
|
||||||
setTimeout(() => {
|
|
||||||
var NotificationOBJ = document.getElementById('notifhere')
|
|
||||||
|
|
||||||
}, 2000);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -203,324 +174,108 @@ function switchProxy() {
|
||||||
function switchTheme() {
|
function switchTheme() {
|
||||||
var selecter = document.getElementById("themeSwitcher");
|
var selecter = document.getElementById("themeSwitcher");
|
||||||
var selectedOption = selecter.value
|
var selectedOption = selecter.value
|
||||||
|
if (selectedOption == "dark") {
|
||||||
localStorage.setItem("theme", selectedOption);
|
changeCSS('--background-primary', '#191724', true);
|
||||||
var storedChoice = localStorage.getItem('theme');
|
changeCSS('--navbar-color', '#26233a', true);
|
||||||
console.log(selectedOption)
|
changeCSS('--navbar-height', '60px', true);
|
||||||
if (storedChoice == 'light') {
|
changeCSS('--navbar-text-color', '#4de0fa', true);
|
||||||
//LIGHT
|
changeCSS('--input-text-color', '#e0def4', true);
|
||||||
console.log("loaded theme:", storedChoice);
|
changeCSS('--input-placeholder-color', '#6e6a86', true);
|
||||||
document.body.style.backgroundColor = " #d8d8d8";
|
changeCSS('--input-background-color', '#1f1d2e', true);
|
||||||
const descriptions = document.getElementsByClassName('description');
|
changeCSS('--input-placeholder-color', 'white', true);
|
||||||
for (const element of descriptions) {
|
changeCSS('--input-border-color', '#eb6f92', true);
|
||||||
element.style.color = "#000000";
|
changeCSS('--input-border-size', '1.3px', true);
|
||||||
|
changeCSS('--navbar-link-color', '#e0def4', true);
|
||||||
|
changeCSS('--navbar-font', '"Roboto"', true);
|
||||||
|
changeCSS('--navbar-logo-filter', 'invert(0%)', true);
|
||||||
|
changeCSS('--text-color-primary', '#e0def4', true);
|
||||||
}
|
}
|
||||||
const names = document.getElementsByClassName('name');
|
if (selectedOption == "light") {
|
||||||
for (const element of names) {
|
changeCSS('--background-primary', '#d8d8d8', true);
|
||||||
element.style.color = "#000000";
|
changeCSS('--navbar-color', '#a2a2a2', true);
|
||||||
}
|
changeCSS('--navbar-height', '4em', true);
|
||||||
const dropdowns = document.getElementsByClassName('dropdown');
|
changeCSS('--navbar-text-color', '#000000', true);
|
||||||
for (const element of dropdowns) {
|
changeCSS('--input-text-color', '#e0def4', true);
|
||||||
element.style.backgroundColor = "#606b69";
|
changeCSS('--input-placeholder-color', 'white', true);
|
||||||
}
|
changeCSS('--input-background-color', 'black', true);
|
||||||
const buttons = document.getElementsByClassName('button-save');
|
changeCSS('--input-border-color', '#eb6f92', true);
|
||||||
for (const element of buttons) {
|
changeCSS('--input-border-size', '1.3px', true);
|
||||||
element.style.backgroundColor = "#606b69";
|
changeCSS('--navbar-link-color', '#000000', true);
|
||||||
}
|
changeCSS('--navbar-font', '"Roboto"', true);
|
||||||
const switches = document.getElementsByClassName('toogle-button');
|
changeCSS('--navbar-logo-filter', 'invert(30%)', true);
|
||||||
for (const element of switches) {
|
changeCSS('--text-color-primary', '#303030', true);
|
||||||
element.style.backgroundColor = "#606b69";
|
|
||||||
}
|
|
||||||
//DARK
|
|
||||||
} else if (storedChoice == 'dark') {
|
|
||||||
console.log("loaded theme:", storedChoice);
|
|
||||||
document.body.style.backgroundColor = "#191724";
|
|
||||||
const descriptions = document.getElementsByClassName('description');
|
|
||||||
for (const element of descriptions) {
|
|
||||||
element.style.color = "#6e6a86";
|
|
||||||
}
|
|
||||||
const names = document.getElementsByClassName('name');
|
|
||||||
for (const element of names) {
|
|
||||||
element.style.color = "#e0def4";
|
|
||||||
}
|
|
||||||
const dropdowns = document.getElementsByClassName('dropdown');
|
|
||||||
for (const element of dropdowns) {
|
|
||||||
element.style.backgroundColor = "#1abc9c";
|
|
||||||
}
|
|
||||||
const buttons = document.getElementsByClassName('button-save');
|
|
||||||
for (const element of buttons) {
|
|
||||||
element.style.backgroundColor = "#1abc9c";
|
|
||||||
}
|
|
||||||
const switches = document.getElementsByClassName('toogle-button');
|
|
||||||
for (const element of switches) {
|
|
||||||
element.style.backgroundColor = "#1abc9c";
|
|
||||||
|
|
||||||
}
|
}
|
||||||
document.getElementById('navbar').style.backgroundColor = "#26233a";
|
if (selectedOption == "custom") {
|
||||||
var storedChoice = localStorage.getItem('theme');
|
let response = prompt('Please enter the code for a custom theme:', '')
|
||||||
} else if (storedChoice == 'hacker') {
|
alert('This feature is not ready yet. Please try again later.')
|
||||||
console.log("loaded theme:", storedChoice);
|
|
||||||
document.body.style.backgroundColor = "#000";
|
|
||||||
const descriptions = document.getElementsByClassName('description');
|
|
||||||
for (const element of descriptions) {
|
|
||||||
element.style.color = "#00ff0b";
|
|
||||||
}
|
|
||||||
const names = document.getElementsByClassName('name');
|
|
||||||
for (const element of names) {
|
|
||||||
element.style.color = "#00ff0b";
|
|
||||||
}
|
|
||||||
const dropdowns = document.getElementsByClassName('dropdown');
|
|
||||||
for (const element of dropdowns) {
|
|
||||||
element.style.backgroundColor = "#00ff0b";
|
|
||||||
}
|
|
||||||
const buttons = document.getElementsByClassName('button-save');
|
|
||||||
for (const element of buttons) {
|
|
||||||
element.style.backgroundColor = "#00ff0b";
|
|
||||||
}
|
|
||||||
const switches = document.getElementsByClassName('toogle-button');
|
|
||||||
for (const element of switches) {
|
|
||||||
element.style.backgroundColor = "#00ff0b";
|
|
||||||
|
|
||||||
}
|
|
||||||
const boxes = document.getElementsByClassName('settings-cont');
|
|
||||||
for (const element of boxes) {
|
|
||||||
element.style.border = "2px solid rgb(0, 255, 11)";
|
|
||||||
|
|
||||||
}
|
|
||||||
const newTags = document.getElementsByClassName('new-tag');
|
|
||||||
for (const element of newTags) {
|
|
||||||
element.style.color = "#00ff0b";
|
|
||||||
|
|
||||||
}
|
|
||||||
document.getElementById('navbar').style.backgroundColor = "#000";
|
|
||||||
const navbuttons = document.getElementsByClassName('a-navbutton');
|
|
||||||
for (const element of navbuttons) {
|
|
||||||
element.style.color = "#00ff0b";
|
|
||||||
}
|
|
||||||
const nebheader = document.getElementsByClassName('nebHeader');
|
|
||||||
for (const element of nebheader) {
|
|
||||||
element.style.color = "#00ff0b";
|
|
||||||
}
|
|
||||||
const Obox = document.getElementsByClassName('omnibox');
|
|
||||||
for (const element of Obox) {
|
|
||||||
element.style.backgroundColor = "black";
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
location.reload()
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function getOption(option) {
|
function defaultThemes() {
|
||||||
console.log(localStorage.getItem(option));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write a function that will change css variables based on the arguments passed in the function
|
||||||
|
function changeCSS(variable, value, saveBool) {
|
||||||
|
document.documentElement.style.setProperty(variable, value);
|
||||||
|
console.log(`Sucessfully changed CSS variable: ${variable} to ${value}`)
|
||||||
|
if (saveBool === true) {
|
||||||
|
saveCSS(variable, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveCSS(variable, value) {
|
||||||
|
localStorage.setItem(variable, value);
|
||||||
|
console.log(`Updated CSS LocalStorage: ${localStorage.getItem(variable)}`)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
// Update the CheckBox to match the settings
|
let background = localStorage.getItem('--background-primary');
|
||||||
|
let navbar = localStorage.getItem('--navbar-color');
|
||||||
if (localStorage.getItem('proxy') == "null" || localStorage.getItem('nogg') == "null") {
|
let navbarHeight = localStorage.getItem('--navbar-height');
|
||||||
|
let navbarText = localStorage.getItem('--navbar-text-color');
|
||||||
console.ch("Applied Settings: ", "NoGG is ", localStorage.getItem('nogg'), " | Proxy set to", localStorage.getItem('proxy'))
|
let inputText = localStorage.getItem('--input-text-color');
|
||||||
} else {
|
let inputPlaceholder = localStorage.getItem('--input-placeholder-color');
|
||||||
|
let inputBackground = localStorage.getItem('--input-background-color');
|
||||||
console.warn("Applied Settings: ", "NoGG is ", localStorage.getItem('nogg'), " | Proxy set to", localStorage.getItem('proxy'))
|
let inputBorder = localStorage.getItem('--input-border-color');
|
||||||
console.warn("If these values are 'null', there was an error getting a localstorage item. ")
|
let inputBorderSize = localStorage.getItem('--input-border-size');
|
||||||
};
|
let navbarFont = localStorage.getItem('--navbar-font');
|
||||||
if (window.location.pathname == '/static/options/' || window.location.pathname == 'options/' || window.location.pathname == '/options/') {
|
let navbarLink = localStorage.getItem('--navbar-link-color');
|
||||||
if (localStorage.getItem('nogg') == 'on') {
|
let navbarLogoFilter = localStorage.getItem('--navbar-logo-filter');
|
||||||
setTimeout(() => {
|
let textColorPrimary = localStorage.getItem('--text-color-primary');
|
||||||
var item = document.getElementById("undefined");
|
changeCSS('--background-primary', background);
|
||||||
document.getElementById("undefined").checked = true;
|
changeCSS('--navbar-color', navbar);
|
||||||
}, 600);
|
changeCSS('--navbar-height', navbarHeight);
|
||||||
|
changeCSS('--navbar-text-color', navbarText);
|
||||||
|
changeCSS('--input-text-color', inputText);
|
||||||
|
changeCSS('--input-placeholder-color', inputPlaceholder);
|
||||||
|
changeCSS('--input-background-color', inputBackground);
|
||||||
|
changeCSS('--input-border-color', inputBorder);
|
||||||
|
changeCSS('--input-border-size', inputBorderSize);
|
||||||
|
changeCSS('--navbar-link-color', navbarLink);
|
||||||
|
changeCSS('--navbar-font', navbarFont);
|
||||||
|
changeCSS('--navbar-logo-filter', navbarLogoFilter);
|
||||||
|
changeCSS('--text-color-primary', textColorPrimary);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the front end to match option localstorage
|
function resetViews() {
|
||||||
var selecter = document.getElementById("proxySwitcher");
|
changeCSS('--background-primary', '#191724', true);
|
||||||
var storedChoice = localStorage.getItem('proxy');
|
changeCSS('--navbar-color', '#26233a', true);
|
||||||
selecter.value = storedChoice;
|
changeCSS('--navbar-height', '60px', true);
|
||||||
|
changeCSS('--navbar-text-color', '#4de0fa', true);
|
||||||
// ThemeSet
|
changeCSS('--navbar-link-color', '#e0def4', true);
|
||||||
var themeSelector = document.getElementById("themeSwitcher");
|
changeCSS('--navbar-font', '"Roboto"', true);
|
||||||
var storedTheme = localStorage.getItem('theme');
|
changeCSS('--input-text-color', '#e0def4', true);
|
||||||
themeSelector.value = storedTheme;
|
changeCSS('--input-placeholder-color', '#6e6a86', true);
|
||||||
|
changeCSS('--input-background-color', '#1f1d2e', true);
|
||||||
|
changeCSS('--input-placeholder-color', 'white', true);
|
||||||
|
changeCSS('--input-border-color', '#eb6f92', true);
|
||||||
|
changeCSS('--input-border-size', '1.3px', true);
|
||||||
|
return "All views reset"
|
||||||
}
|
}
|
||||||
if (window.location.pathname == '/static/options/' || window.location.pathname == 'options/' || window.location.pathname == '/options/') {
|
|
||||||
if (storedTheme == 'light') {
|
|
||||||
console.log("loaded theme:", storedTheme);
|
|
||||||
document.body.style.backgroundColor = " #d8d8d8";
|
|
||||||
const descriptions = document.getElementsByClassName('description');
|
|
||||||
for (const element of descriptions) {
|
|
||||||
element.style.color = "#000000";
|
|
||||||
}
|
|
||||||
const names = document.getElementsByClassName('name');
|
|
||||||
for (const element of names) {
|
|
||||||
element.style.color = "#000000";
|
|
||||||
}
|
|
||||||
const dropdowns = document.getElementsByClassName('dropdown');
|
|
||||||
for (const element of dropdowns) {
|
|
||||||
element.style.backgroundColor = "#606b69";
|
|
||||||
}
|
|
||||||
const buttons = document.getElementsByClassName('button-save');
|
|
||||||
for (const element of buttons) {
|
|
||||||
element.style.backgroundColor = "#606b69";
|
|
||||||
}
|
|
||||||
const switches = document.getElementsByClassName('toogle-button');
|
|
||||||
for (const element of switches) {
|
|
||||||
element.style.backgroundColor = "#606b69";
|
|
||||||
}
|
|
||||||
} else if (storedTheme == 'dark') {
|
|
||||||
console.log("loaded theme:", storedTheme);
|
|
||||||
document.body.style.backgroundColor = "#191724";
|
|
||||||
const descriptions = document.getElementsByClassName('description');
|
|
||||||
for (const element of descriptions) {
|
|
||||||
element.style.color = "#6e6a86";
|
|
||||||
}
|
|
||||||
const names = document.getElementsByClassName('name');
|
|
||||||
for (const element of names) {
|
|
||||||
element.style.color = "#e0def4";
|
|
||||||
}
|
|
||||||
const dropdowns = document.getElementsByClassName('dropdown');
|
|
||||||
for (const element of dropdowns) {
|
|
||||||
element.style.backgroundColor = "#1abc9c";
|
|
||||||
}
|
|
||||||
const buttons = document.getElementsByClassName('button-save');
|
|
||||||
for (const element of buttons) {
|
|
||||||
element.style.backgroundColor = "#1abc9c";
|
|
||||||
}
|
|
||||||
const switches = document.getElementsByClassName('toogle-button');
|
|
||||||
for (const element of switches) {
|
|
||||||
element.style.backgroundColor = "#1abc9c";
|
|
||||||
|
|
||||||
}
|
|
||||||
document.getElementById('navbar').style.backgroundColor = "#26233a";
|
|
||||||
} else if (storedTheme == 'hacker') {
|
|
||||||
console.log("loaded theme:", storedChoice);
|
|
||||||
document.body.style.backgroundColor = "#000";
|
|
||||||
const descriptions = document.getElementsByClassName('description');
|
|
||||||
for (const element of descriptions) {
|
|
||||||
element.style.color = "#00ff0b";
|
|
||||||
}
|
|
||||||
const names = document.getElementsByClassName('name');
|
|
||||||
for (const element of names) {
|
|
||||||
element.style.color = "#00ff0b";
|
|
||||||
}
|
|
||||||
const dropdowns = document.getElementsByClassName('dropdown');
|
|
||||||
for (const element of dropdowns) {
|
|
||||||
element.style.backgroundColor = "#00ff0b";
|
|
||||||
}
|
|
||||||
const buttons = document.getElementsByClassName('button-save');
|
|
||||||
for (const element of buttons) {
|
|
||||||
element.style.backgroundColor = "#00ff0b";
|
|
||||||
}
|
|
||||||
const switches = document.getElementsByClassName('toogle-button');
|
|
||||||
for (const element of switches) {
|
|
||||||
element.style.backgroundColor = "#00ff0b";
|
|
||||||
|
|
||||||
}
|
|
||||||
const boxes = document.getElementsByClassName('settings-cont');
|
|
||||||
for (const element of boxes) {
|
|
||||||
element.style.border = "2px solid rgb(0, 255, 11)";
|
|
||||||
|
|
||||||
}
|
|
||||||
const newTags = document.getElementsByClassName('new-tag');
|
|
||||||
for (const element of newTags) {
|
|
||||||
element.style.color = "#00ff0b";
|
|
||||||
|
|
||||||
}
|
|
||||||
document.getElementById('navbar').style.backgroundColor = "#000";
|
|
||||||
const navbuttons = document.getElementsByClassName('a-navbutton');
|
|
||||||
for (const element of navbuttons) {
|
|
||||||
element.style.color = "#00ff0b";
|
|
||||||
}
|
|
||||||
const nebheader = document.getElementsByClassName('nebHeader');
|
|
||||||
for (const element of nebheader) {
|
|
||||||
element.style.color = "#00ff0b";
|
|
||||||
}
|
|
||||||
const Obox = document.getElementsByClassName('omnibox');
|
|
||||||
for (const element of Obox) {
|
|
||||||
element.style.backgroundColor = "black";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
var storedTheme = localStorage.getItem('theme');
|
|
||||||
if (storedTheme == "light") {
|
|
||||||
document.getElementById('connecterText').style.color = "black"
|
|
||||||
document.getElementById('navbar').style.backgroundColor = "#a2a2a2";
|
|
||||||
document.body.style.backgroundColor = " #d8d8d8";
|
|
||||||
const navbuttons = document.getElementsByClassName('a-navbutton');
|
|
||||||
for (const element of navbuttons) {
|
|
||||||
element.style.color = "#000000";
|
|
||||||
}
|
|
||||||
const nebheader = document.getElementsByClassName('nebHeader');
|
|
||||||
for (const element of nebheader) {
|
|
||||||
element.style.color = "#000000";
|
|
||||||
}
|
|
||||||
const Obox = document.getElementsByClassName('omnibox');
|
|
||||||
for (const element of Obox) {
|
|
||||||
element.style.backgroundColor = "#000000";
|
|
||||||
}
|
|
||||||
const stamp = document.getElementsByClassName('stamp');
|
|
||||||
for (const element of stamp) {
|
|
||||||
element.style.color = "#000";
|
|
||||||
}
|
|
||||||
} else if (storedTheme == 'dark') {
|
|
||||||
document.getElementById('navbar').style.backgroundColor = "#26233a";
|
|
||||||
document.body.style.backgroundColor = "#191724";
|
|
||||||
|
|
||||||
|
|
||||||
} else if (storedTheme == 'hacker') {
|
|
||||||
document.getElementById('connecterText').style.color = "rgb(0, 255, 11)"
|
|
||||||
console.log("loaded theme:", storedChoice);
|
|
||||||
document.body.style.backgroundColor = "#000";
|
|
||||||
const descriptions = document.getElementsByClassName('description');
|
|
||||||
for (const element of descriptions) {
|
|
||||||
element.style.color = "#00ff0b";
|
|
||||||
}
|
|
||||||
const names = document.getElementsByClassName('name');
|
|
||||||
for (const element of names) {
|
|
||||||
element.style.color = "#00ff0b";
|
|
||||||
}
|
|
||||||
const dropdowns = document.getElementsByClassName('dropdown');
|
|
||||||
for (const element of dropdowns) {
|
|
||||||
element.style.backgroundColor = "#00ff0b";
|
|
||||||
}
|
|
||||||
const buttons = document.getElementsByClassName('button-save');
|
|
||||||
for (const element of buttons) {
|
|
||||||
element.style.backgroundColor = "#00ff0b";
|
|
||||||
}
|
|
||||||
const switches = document.getElementsByClassName('toogle-button');
|
|
||||||
for (const element of switches) {
|
|
||||||
element.style.backgroundColor = "#00ff0b";
|
|
||||||
|
|
||||||
}
|
|
||||||
const boxes = document.getElementsByClassName('settings-cont');
|
|
||||||
for (const element of boxes) {
|
|
||||||
element.style.border = "2px solid rgb(0, 255, 11)";
|
|
||||||
|
|
||||||
}
|
|
||||||
const newTags = document.getElementsByClassName('new-tag');
|
|
||||||
for (const element of newTags) {
|
|
||||||
element.style.color = "#00ff0b";
|
|
||||||
}
|
|
||||||
document.getElementById('navbar').style.backgroundColor = "#000";
|
|
||||||
const navbuttons = document.getElementsByClassName('a-navbutton');
|
|
||||||
for (const element of navbuttons) {
|
|
||||||
element.style.color = "#00ff0b";
|
|
||||||
}
|
|
||||||
const nebheader = document.getElementsByClassName('nebHeader');
|
|
||||||
for (const element of nebheader) {
|
|
||||||
element.style.color = "#00ff0b";
|
|
||||||
}
|
|
||||||
const Obox = document.getElementsByClassName('omnibox');
|
|
||||||
for (const element of Obox) {
|
|
||||||
element.style.backgroundColor = "black";
|
|
||||||
}
|
|
||||||
document.getElementById('navbar').style.backgroundColor = "#000";
|
|
||||||
var placeholderOmniBox = document.getElementById("url");
|
|
||||||
document.getElementById("url").style.color = "red";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// #################################################################################################################################################
|
// #################################################################################################################################################
|
||||||
// #################################################################################################################################################
|
// #################################################################################################################################################
|
||||||
|
|
@ -585,3 +340,35 @@ function induce(inductor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log();
|
log();
|
||||||
|
|
||||||
|
// Notification Banner
|
||||||
|
function saveIc() {
|
||||||
|
console.log("Checked")
|
||||||
|
var notification = `
|
||||||
|
<div class="notification-container" id="notification-container">
|
||||||
|
<div class="notification notification-success">
|
||||||
|
<strong>Success!</strong> Your settings have been saved - Reloading.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.getElementById('notifhere').innerHTML = notification
|
||||||
|
setTimeout(() => {
|
||||||
|
var NotificationOBJ = document.getElementById('notifhere')
|
||||||
|
|
||||||
|
}, 2000);
|
||||||
|
};
|
||||||
|
|
||||||
|
function unsavedChanges() {
|
||||||
|
var notification = `
|
||||||
|
<div class="notification-container" id="notification-container">
|
||||||
|
<div class="notification notification-danger" id="notification-container">
|
||||||
|
<strong>Danger!</strong> You have unsaved changes!
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.getElementById('notifhere').innerHTML = notification
|
||||||
|
setTimeout(() => {
|
||||||
|
var NotificationOBJ = document.getElementById('notifhere')
|
||||||
|
|
||||||
|
}, 2000);
|
||||||
|
};
|
||||||
28
static/resources/themes.default.js
Normal file
28
static/resources/themes.default.js
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
// default theme / dark theme
|
||||||
|
changeCSS('--background-primary', '#191724', true);
|
||||||
|
changeCSS('--navbar-color', '#26233a', true);
|
||||||
|
changeCSS('--navbar-height', '60px', true);
|
||||||
|
changeCSS('--navbar-text-color', '#4de0fa', true);
|
||||||
|
changeCSS('--input-text-color', '#e0def4', true);
|
||||||
|
changeCSS('--input-placeholder-color', '#6e6a86', true);
|
||||||
|
changeCSS('--input-background-color', '#1f1d2e', true);
|
||||||
|
changeCSS('--input-placeholder-color', 'white', true);
|
||||||
|
changeCSS('--input-border-color', '#eb6f92', true);
|
||||||
|
changeCSS('--input-border-size', '1.3px', true);
|
||||||
|
changeCSS('--navbar-link-color', '#e0def4', true);
|
||||||
|
changeCSS('--navbar-font', '"Roboto"', true);
|
||||||
|
changeCSS('--navbar-logo-filter', 'invert(0%)', true);
|
||||||
|
changeCSS('--text-color-primary', '#e0def4', true);
|
||||||
|
// snow theme
|
||||||
|
changeCSS('--background-primary', '#d8d8d8', true);
|
||||||
|
changeCSS('--navbar-color', '#a2a2a2', true);
|
||||||
|
changeCSS('--navbar-height', '60px', true);
|
||||||
|
changeCSS('--navbar-text-color', '#000000', true);
|
||||||
|
changeCSS('--input-text-color', '#e0def4', true);
|
||||||
|
changeCSS('--input-placeholder-color', 'white', true);
|
||||||
|
changeCSS('--input-background-color', 'black', true);
|
||||||
|
changeCSS('--input-border-color', '#eb6f92', true);
|
||||||
|
changeCSS('--input-border-size', '1.3px', true);
|
||||||
|
changeCSS('--navbar-link-color', '#000000', true);
|
||||||
|
changeCSS('--navbar-font', '"Roboto"', true);
|
||||||
|
changeCSS('--navbar-logo-filter', 'invert(30%)', true);
|
||||||
|
|
@ -1,13 +1,18 @@
|
||||||
|
@import url("https://fonts.googleapis.com/css2?family=Dongle&family=Roboto:wght@100&display=swap");
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@1,100&display=swap');
|
||||||
:root {
|
:root {
|
||||||
--background-primary: #191724;
|
--background-primary: #191724;
|
||||||
--navbar-color: #26233a;
|
--navbar-color: #26233a;
|
||||||
--navbar-height: 4em;
|
--navbar-height: 60px;
|
||||||
--navbar-text-color: #e0def4;
|
--navbar-text-color: #4de0fa;
|
||||||
|
--navbar-link-color: #e0def4;
|
||||||
|
--navbar-font: "Roboto";
|
||||||
--input-text-color: #e0def4;
|
--input-text-color: #e0def4;
|
||||||
--input-placeholder-color: #6e6a86;
|
--input-placeholder-color: white;
|
||||||
--input-background-color: #1f1d2e;
|
--input-background-color: #1f1d2e;
|
||||||
--input-border-color: #eb6f92;
|
--input-border-color: #eb6f92;
|
||||||
--input-border-size: 0.1em;
|
--input-border-size: 1.3px;
|
||||||
|
--navbar-logo-filter: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-input-placeholder {
|
::-webkit-input-placeholder {
|
||||||
|
|
@ -20,7 +25,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#navbar {
|
#navbar {
|
||||||
height: 60px;
|
height: var(--navbar-height);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -32,7 +37,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: white;
|
color: var(--navbar-link-color);
|
||||||
text-decoration: none !important;
|
text-decoration: none !important;
|
||||||
font-family: 'Roboto';
|
font-family: 'Roboto';
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +86,7 @@ a:hover {
|
||||||
|
|
||||||
::placeholder,
|
::placeholder,
|
||||||
input[type='text'] {
|
input[type='text'] {
|
||||||
color: white;
|
color: var(--input-placeholder-color);
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-family: 'Roboto';
|
font-family: 'Roboto';
|
||||||
|
|
@ -153,7 +158,7 @@ ul li ul:hover {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-family: 'Calibri';
|
font-family: 'Calibri';
|
||||||
border-style: solid !important;
|
border-style: solid !important;
|
||||||
border: 1.3px solid var(--input-border-color);
|
border: var(--input-border-size) solid var(--input-border-color);
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
background-color: var(--input-background-color);
|
background-color: var(--input-background-color);
|
||||||
|
|
@ -162,7 +167,6 @@ ul li ul:hover {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
outline: none;
|
outline: none;
|
||||||
color: white;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-family: 'Roboto';
|
font-family: 'Roboto';
|
||||||
animation-name: inputwide;
|
animation-name: inputwide;
|
||||||
|
|
@ -214,3 +218,82 @@ svg rect {
|
||||||
height: 0px;
|
height: 0px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nebHeader {
|
||||||
|
margin-left: .5%;
|
||||||
|
font-family: var(--navbar-font);
|
||||||
|
color: var(--navbar-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: var(--background-primary);
|
||||||
|
color: var(--text-color-primary);
|
||||||
|
animation: fadeInAnimation ease 1s;
|
||||||
|
animation-iteration-count: 1;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeInAnimation {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus::placeholder {
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#navbar #thumbImg {
|
||||||
|
transition: width 2s, height 2s, transform 2s;
|
||||||
|
filter: var(--navbar-logo-filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
#navbar #thumbImg:hover {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stamp {
|
||||||
|
text-align: right;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
font-family: 'Montserrat', sans-serif;
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: lighter;
|
||||||
|
color: whitesmoke;
|
||||||
|
opacity: 38%;
|
||||||
|
user-select: none;
|
||||||
|
font-size: 13px;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-bottom: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.github {
|
||||||
|
position: fixed;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tos {
|
||||||
|
position: fixed;
|
||||||
|
right: 67px;
|
||||||
|
bottom: 0;
|
||||||
|
padding-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.privacy {
|
||||||
|
position: fixed;
|
||||||
|
right: 114px;
|
||||||
|
bottom: 0;
|
||||||
|
padding-right: 15px;
|
||||||
|
}
|
||||||
|
|
@ -1,96 +0,0 @@
|
||||||
@import url("https://fonts.googleapis.com/css2?family=Dongle&family=Roboto:wght@100&display=swap");
|
|
||||||
:root {
|
|
||||||
--background-primary: #191724;
|
|
||||||
--text-color-primary: #31748f;
|
|
||||||
--text-color-secondary: #9ccfd8;
|
|
||||||
--header-color: #26233a;
|
|
||||||
--header-height: 4em;
|
|
||||||
--header-text-color: #e0def4;
|
|
||||||
--input-text-color: white;
|
|
||||||
--input-placeholder-color: #6e6a86;
|
|
||||||
--input-background-color: #1f1d2e;
|
|
||||||
--input-border-color: #eb6f92;
|
|
||||||
--input-border-size: 0.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
*,
|
|
||||||
*::before,
|
|
||||||
*::after {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
height: 100%;
|
|
||||||
cursor: url("../images/cur.gif"), url("../images/cursor.cur"), default;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: var(--background-primary);
|
|
||||||
color: var(--text-color-primary);
|
|
||||||
animation: fadeInAnimation ease 1s;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
animation-fill-mode: forwards;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fadeInAnimation {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input:focus::placeholder {
|
|
||||||
color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
#navbar #thumbImg {
|
|
||||||
transition: width 2s, height 2s, transform 2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
#navbar #thumbImg:hover {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@1,100&display=swap');
|
|
||||||
.stamp {
|
|
||||||
text-align: right;
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
font-family: 'Montserrat', sans-serif;
|
|
||||||
font-style: italic;
|
|
||||||
font-weight: lighter;
|
|
||||||
color: whitesmoke;
|
|
||||||
opacity: 38%;
|
|
||||||
user-select: none;
|
|
||||||
font-size: 13px;
|
|
||||||
padding-left: 5px;
|
|
||||||
padding-bottom: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.github {
|
|
||||||
position: fixed;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
padding-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tos {
|
|
||||||
position: fixed;
|
|
||||||
right: 67px;
|
|
||||||
bottom: 0;
|
|
||||||
padding-right: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.privacy {
|
|
||||||
position: fixed;
|
|
||||||
right: 114px;
|
|
||||||
bottom: 0;
|
|
||||||
padding-right: 15px;
|
|
||||||
}
|
|
||||||
|
|
@ -312,7 +312,7 @@ ul li {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-evenly;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
|
|
@ -359,7 +359,7 @@ ul li {
|
||||||
|
|
||||||
.custom-dropdown select {
|
.custom-dropdown select {
|
||||||
background-color: #1abc9c;
|
background-color: #1abc9c;
|
||||||
color: #fff;
|
color: var(--text-color-primary);
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
padding: .5em;
|
padding: .5em;
|
||||||
padding-right: 2.5em;
|
padding-right: 2.5em;
|
||||||
|
|
@ -438,3 +438,45 @@ ul li {
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type=checkbox] {
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
cursor: pointer;
|
||||||
|
/* text-indent: -10049px; */
|
||||||
|
width: 85px;
|
||||||
|
height: 37px;
|
||||||
|
background: #ff5c5c;
|
||||||
|
display: block;
|
||||||
|
border-radius: 100px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
label:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
left: 5px;
|
||||||
|
width: 35px;
|
||||||
|
height: 28px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 90px;
|
||||||
|
transition: 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked+label {
|
||||||
|
background: #bada55;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked+label:after {
|
||||||
|
left: calc(100% - 5px);
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
label:active:after {
|
||||||
|
width: 130px;
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue