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() => {
|
||||
await import('./app.mjs');
|
||||
await
|
||||
import ('./app.mjs');
|
||||
})();
|
||||
20
app.mjs
20
app.mjs
|
|
@ -5,6 +5,13 @@ import nodeStatic from 'node-static';
|
|||
import fs from 'fs';
|
||||
import * as custombare from './static/customBare.mjs';
|
||||
|
||||
|
||||
const httpPort = 80;
|
||||
const httpsPort = 443;
|
||||
const debug = true;
|
||||
|
||||
|
||||
|
||||
const bareServer = createBareServer('/bare/', {
|
||||
logErrors: false,
|
||||
localAddress: undefined,
|
||||
|
|
@ -39,8 +46,11 @@ httpsServer.on('request', request);
|
|||
httpServer.on('upgrade', upgrade);
|
||||
httpsServer.on('upgrade', upgrade);
|
||||
|
||||
function request (request, response) {
|
||||
function request(request, response) {
|
||||
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)) {
|
||||
bareServer.routeRequest(request, response);
|
||||
|
|
@ -49,7 +59,7 @@ function request (request, response) {
|
|||
}
|
||||
}
|
||||
|
||||
function upgrade (req, socket, head) {
|
||||
function upgrade(req, socket, head) {
|
||||
if (bareServer.shouldRoute(req)) {
|
||||
bareServer.routeUpgrade(req, socket, head);
|
||||
} else {
|
||||
|
|
@ -57,7 +67,7 @@ function upgrade (req, socket, head) {
|
|||
}
|
||||
}
|
||||
|
||||
httpServer.listen(80);
|
||||
httpsServer.listen(443);
|
||||
httpServer.listen(httpPort);
|
||||
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.",
|
||||
"dependencies": {
|
||||
"@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-static": "^0.7.11"
|
||||
"node-static": "^0.7.11",
|
||||
"ws": "^8.8.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tomphttp/bare-server-node": {
|
||||
"version": "1.0.2-beta-readme5",
|
||||
"resolved": "https://registry.npmjs.org/@tomphttp/bare-server-node/-/bare-server-node-1.0.2-beta-readme5.tgz",
|
||||
"integrity": "sha512-WOYNae3faSj9Yt4dKVqzjbh1ovpKRhsevnJaM2BgC6LkRULFN/GhtslXDXG6KLbqeokFFj0XqpZ8TTzdxKyhkw==",
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tomphttp/bare-server-node/-/bare-server-node-1.0.3.tgz",
|
||||
"integrity": "sha512-mKMipi9qntDy3wcalWGuK3iKzM0XQT4sW3E6yRXeIU4BxFZVSLzSDejPxL6wWwniKGm0faSwZ4Pk0dQ04JEFNA==",
|
||||
"dependencies": {
|
||||
"commander": "^9.0.0",
|
||||
"dotenv": "^16.0.1",
|
||||
"fetch-headers": "^3.0.1",
|
||||
"headers-polyfill": "^3.0.10",
|
||||
"http-errors": "^2.0.0"
|
||||
},
|
||||
"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": {
|
||||
|
|
@ -44,6 +69,24 @@
|
|||
"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": {
|
||||
"version": "4.0.0",
|
||||
"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_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": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
||||
|
|
@ -119,6 +144,11 @@
|
|||
"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": {
|
||||
"version": "2.0.0",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "1.6.0",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||
|
|
@ -251,17 +294,47 @@
|
|||
"engines": {
|
||||
"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": {
|
||||
"@tomphttp/bare-server-node": {
|
||||
"version": "1.0.2-beta-readme5",
|
||||
"resolved": "https://registry.npmjs.org/@tomphttp/bare-server-node/-/bare-server-node-1.0.2-beta-readme5.tgz",
|
||||
"integrity": "sha512-WOYNae3faSj9Yt4dKVqzjbh1ovpKRhsevnJaM2BgC6LkRULFN/GhtslXDXG6KLbqeokFFj0XqpZ8TTzdxKyhkw==",
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tomphttp/bare-server-node/-/bare-server-node-1.0.3.tgz",
|
||||
"integrity": "sha512-mKMipi9qntDy3wcalWGuK3iKzM0XQT4sW3E6yRXeIU4BxFZVSLzSDejPxL6wWwniKGm0faSwZ4Pk0dQ04JEFNA==",
|
||||
"requires": {
|
||||
"commander": "^9.0.0",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
|
|
@ -275,6 +348,20 @@
|
|||
"resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz",
|
||||
"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": {
|
||||
"version": "4.0.0",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
||||
|
|
@ -312,6 +394,11 @@
|
|||
"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": {
|
||||
"version": "2.0.0",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "1.6.0",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||
|
|
@ -397,6 +494,12 @@
|
|||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
|
||||
"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",
|
||||
"license": "Copyright Nebula Services. All Rights Reserved.",
|
||||
"dependencies": {
|
||||
"@tomphttp/bare-server-node": "^1.0.2-beta-readme5",
|
||||
"bare-server-node": "github:tomphttp/bare-server-node",
|
||||
"css-tree": "^2.1.0",
|
||||
"node-fetch": "^3.2.6",
|
||||
"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 * as csstree from 'css-tree';
|
||||
import * as ws from 'ws';
|
||||
import filter from './cyclone/filter.cyclone.mjs';
|
||||
import * as security from './cyclone/security.cyclone.mjs';
|
||||
|
||||
const config = {
|
||||
prefix: "/service",
|
||||
|
|
@ -10,10 +12,6 @@ const config = {
|
|||
defaultHeaders: {
|
||||
'X-Content-Type-Options': 'no-sniff',
|
||||
},
|
||||
//proxy: {
|
||||
// host: "3.211.17.212",
|
||||
// port: "80"
|
||||
//} // HTTP Proxy
|
||||
}
|
||||
|
||||
if (config.requireSSL) {
|
||||
|
|
@ -23,24 +21,24 @@ if (config.requireSSL) {
|
|||
}
|
||||
|
||||
function rewriteJavascript(js) {
|
||||
var javascript = js.replace('window.location', 'document._dlocation')
|
||||
javascript = javascript.replace('document.location', 'document._dlocation')
|
||||
javascript = javascript.replace('location.', 'document._location.')
|
||||
var javascript = js.replace(/window\.location/g, 'window._dlocation')
|
||||
javascript = javascript.replace(/document\.location/g, 'document._dlocation')
|
||||
javascript = javascript.replace(/location\./g, '_location.')
|
||||
return javascript
|
||||
}
|
||||
|
||||
function insertScript(html) {
|
||||
var res = `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script preload src="/cyclone/cyclone.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
${html}
|
||||
</body>
|
||||
</html>`
|
||||
<html>
|
||||
<head>
|
||||
<script preload src="/cyclone.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
${html}
|
||||
</body>
|
||||
</html>`
|
||||
return res
|
||||
} //
|
||||
}
|
||||
|
||||
async function fetchBare(url, res, req) {
|
||||
try {
|
||||
|
|
@ -58,9 +56,8 @@ async function fetchBare(url, res, req) {
|
|||
} catch (e) {
|
||||
var request = {
|
||||
text() {
|
||||
return 'Error: '+e;
|
||||
return 'Error: ' + e;
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,8 +67,8 @@ async function fetchBare(url, res, req) {
|
|||
var contentType = 'application/javascript';
|
||||
}
|
||||
|
||||
if (url.href.endsWith('.js')||url.href.endsWith(".js")) contentType = "application/javascript";
|
||||
if (url.href.endsWith('.css')||url.href.endsWith(".css")) contentType = "text/css";
|
||||
if (url.href.endsWith('.js') || url.href.endsWith(".js")) contentType = "application/javascript";
|
||||
if (url.href.endsWith('.css') || url.href.endsWith(".css")) contentType = "text/css";
|
||||
|
||||
var output = null;
|
||||
|
||||
|
|
@ -92,18 +89,16 @@ async function fetchBare(url, res, req) {
|
|||
} else {
|
||||
request.body.pipe(res)
|
||||
}
|
||||
|
||||
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
res.writeHead(500, 'Error', {
|
||||
'content-type': 'application/javascript'
|
||||
})
|
||||
res.end(e)
|
||||
res.end(e);
|
||||
}
|
||||
}
|
||||
|
||||
function websocketIntercept(req,res) {
|
||||
function websocketIntercept(req, res) {
|
||||
console.log(req);
|
||||
}
|
||||
|
||||
|
|
@ -111,13 +106,17 @@ function route(req, res) {
|
|||
var path = req.url;
|
||||
|
||||
if (path.startsWith(config.prefix + "/")) {
|
||||
var decoded = path.split(config.prefix + "/")[1];
|
||||
|
||||
try {
|
||||
var url = new URL(path.split(config.prefix + "/")[1])
|
||||
var url = new URL(decoded);
|
||||
} 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 {
|
||||
return false;
|
||||
|
|
@ -132,9 +131,9 @@ function routeSocket(req, socket) {
|
|||
var path = req.url;
|
||||
|
||||
try {
|
||||
var url = new URL(path.split(config.prefix + "/")[1])
|
||||
var url = new URL(path(config.prefix + "/")[1])
|
||||
} catch {
|
||||
var url = new URL("wss://" + path.split(config.prefix + "/")[1])
|
||||
var url = new URL("wss://" + path(config.prefix + "/")[1])
|
||||
}
|
||||
|
||||
console.log(url);
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ self.addEventListener('fetch', function(event) {
|
|||
var tmp = uri.href;
|
||||
|
||||
event.respondWith(
|
||||
fetch("https://Cyclone2.jimmynuetron.repl.co/service/"+tmp)
|
||||
fetch("https://Cyclone2.jimmynuetron.repl.co/service/" + tmp)
|
||||
)
|
||||
}
|
||||
});
|
||||
|
|
@ -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>
|
||||
<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>
|
||||
<title>Nebula</title>
|
||||
|
|
@ -7,14 +7,13 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!-- Stylesheets -->
|
||||
<script src="resources/nebula.bundle.js"></script>
|
||||
<link rel="stylesheet" href="style/master.css">
|
||||
<link rel="stylesheet" href="style/main.css">
|
||||
<!-- Embed -->
|
||||
<meta name="theme-color" content="#eb6f92">
|
||||
<meta property="og:title" content="Nebula">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:image" content="/images/logo.png">
|
||||
<meta property="og:description" content="">
|
||||
<meta property="og:description" content="Nebula Web">
|
||||
<script>
|
||||
if (location.protocol === "http:" && location.host !== "localhost") location.protocol = "https:";
|
||||
</script>
|
||||
|
|
@ -27,7 +26,7 @@
|
|||
<script src="uv/uv.config.js"></script>
|
||||
<div id="navbar">
|
||||
<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>
|
||||
|
||||
|
|
@ -75,7 +74,7 @@
|
|||
|
||||
<!-- Stamp -->
|
||||
<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="tos" href="privacy/">Privacy</a>
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
<script src="uv/uv.config.js"></script>
|
||||
<div id="navbar">
|
||||
<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>
|
||||
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@
|
|||
<p class="name"> Stealth Mode</p>
|
||||
<p class="description">Stops extensions from peeping</p>
|
||||
|
||||
<input class="setting-input" id="undefined" type="checkbox" onclick="saveIc();toggleNoGG()">
|
||||
<label for="undefined" class="toogle-button"></label>
|
||||
<input id="undefined" type="checkbox" onclick="saveIc();toggleNoGG()">
|
||||
<label for="undefined"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-cont">
|
||||
|
|
@ -66,7 +66,8 @@
|
|||
<span class="custom-dropdown big">
|
||||
<a onclick="unsavedChanges();"> <select class="dropdown" id="proxySwitcher">
|
||||
<option value="uv">UltraViolet</option>
|
||||
<option value="cyclone">Cyclone</option>
|
||||
<option value="cyclone">Cyclone (BETA)</option>
|
||||
<option value="osana" disabled>Osana (BETA)</option>
|
||||
</select>
|
||||
</a>
|
||||
|
||||
|
|
@ -85,7 +86,7 @@
|
|||
<a onclick="unsavedChanges();"> <select class="dropdown" id="themeSwitcher">
|
||||
<option value="dark">Shades</option>
|
||||
<option value="light">Blizzard</option>
|
||||
<option value="hacker">Hacker</option>
|
||||
<option value="custom">Custom (Beta)</option>
|
||||
</select>
|
||||
</a>
|
||||
|
||||
|
|
@ -101,7 +102,7 @@
|
|||
<div id='sidebar'>
|
||||
</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 -->
|
||||
<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
|
||||
// Form.js
|
||||
// For the submission of the URL form to the server.
|
||||
// #################################################################################################################################################
|
||||
// #################################################################################################################################################
|
||||
// #################################################################################################################################################
|
||||
|
|
@ -131,7 +132,8 @@ window.addEventListener('load', () => {
|
|||
// #################################################################################################################################################
|
||||
// #################################################################################################################################################
|
||||
// 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() {
|
||||
var selecter = document.getElementById("themeSwitcher");
|
||||
var selectedOption = selecter.value
|
||||
|
||||
localStorage.setItem("theme", selectedOption);
|
||||
var storedChoice = localStorage.getItem('theme');
|
||||
console.log(selectedOption)
|
||||
if (storedChoice == 'light') {
|
||||
//LIGHT
|
||||
console.log("loaded theme:", storedChoice);
|
||||
document.body.style.backgroundColor = " #d8d8d8";
|
||||
const descriptions = document.getElementsByClassName('description');
|
||||
for (const element of descriptions) {
|
||||
element.style.color = "#000000";
|
||||
if (selectedOption == "dark") {
|
||||
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);
|
||||
}
|
||||
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";
|
||||
}
|
||||
//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";
|
||||
if (selectedOption == "light") {
|
||||
changeCSS('--background-primary', '#d8d8d8', true);
|
||||
changeCSS('--navbar-color', '#a2a2a2', true);
|
||||
changeCSS('--navbar-height', '4em', 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);
|
||||
changeCSS('--text-color-primary', '#303030', true);
|
||||
|
||||
}
|
||||
document.getElementById('navbar').style.backgroundColor = "#26233a";
|
||||
var storedChoice = localStorage.getItem('theme');
|
||||
} else if (storedChoice == '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";
|
||||
}
|
||||
if (selectedOption == "custom") {
|
||||
let response = prompt('Please enter the code for a custom theme:', '')
|
||||
alert('This feature is not ready yet. Please try again later.')
|
||||
};
|
||||
location.reload()
|
||||
|
||||
|
||||
};
|
||||
|
||||
function getOption(option) {
|
||||
console.log(localStorage.getItem(option));
|
||||
function defaultThemes() {
|
||||
|
||||
}
|
||||
|
||||
// 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() {
|
||||
// Update the CheckBox to match the settings
|
||||
|
||||
if (localStorage.getItem('proxy') == "null" || localStorage.getItem('nogg') == "null") {
|
||||
|
||||
console.ch("Applied Settings: ", "NoGG is ", localStorage.getItem('nogg'), " | Proxy set to", localStorage.getItem('proxy'))
|
||||
} else {
|
||||
|
||||
console.warn("Applied Settings: ", "NoGG is ", localStorage.getItem('nogg'), " | Proxy set to", localStorage.getItem('proxy'))
|
||||
console.warn("If these values are 'null', there was an error getting a localstorage item. ")
|
||||
};
|
||||
if (window.location.pathname == '/static/options/' || window.location.pathname == 'options/' || window.location.pathname == '/options/') {
|
||||
if (localStorage.getItem('nogg') == 'on') {
|
||||
setTimeout(() => {
|
||||
var item = document.getElementById("undefined");
|
||||
document.getElementById("undefined").checked = true;
|
||||
}, 600);
|
||||
}
|
||||
|
||||
// Update the front end to match option localstorage
|
||||
var selecter = document.getElementById("proxySwitcher");
|
||||
var storedChoice = localStorage.getItem('proxy');
|
||||
selecter.value = storedChoice;
|
||||
|
||||
// ThemeSet
|
||||
var themeSelector = document.getElementById("themeSwitcher");
|
||||
var storedTheme = localStorage.getItem('theme');
|
||||
themeSelector.value = storedTheme;
|
||||
}
|
||||
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";
|
||||
}
|
||||
};
|
||||
let background = localStorage.getItem('--background-primary');
|
||||
let navbar = localStorage.getItem('--navbar-color');
|
||||
let navbarHeight = localStorage.getItem('--navbar-height');
|
||||
let navbarText = localStorage.getItem('--navbar-text-color');
|
||||
let inputText = localStorage.getItem('--input-text-color');
|
||||
let inputPlaceholder = localStorage.getItem('--input-placeholder-color');
|
||||
let inputBackground = localStorage.getItem('--input-background-color');
|
||||
let inputBorder = localStorage.getItem('--input-border-color');
|
||||
let inputBorderSize = localStorage.getItem('--input-border-size');
|
||||
let navbarFont = localStorage.getItem('--navbar-font');
|
||||
let navbarLink = localStorage.getItem('--navbar-link-color');
|
||||
let navbarLogoFilter = localStorage.getItem('--navbar-logo-filter');
|
||||
let textColorPrimary = localStorage.getItem('--text-color-primary');
|
||||
changeCSS('--background-primary', background);
|
||||
changeCSS('--navbar-color', navbar);
|
||||
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);
|
||||
}
|
||||
|
||||
function resetViews() {
|
||||
changeCSS('--background-primary', '#191724', true);
|
||||
changeCSS('--navbar-color', '#26233a', true);
|
||||
changeCSS('--navbar-height', '60px', true);
|
||||
changeCSS('--navbar-text-color', '#4de0fa', true);
|
||||
changeCSS('--navbar-link-color', '#e0def4', true);
|
||||
changeCSS('--navbar-font', '"Roboto"', 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);
|
||||
return "All views reset"
|
||||
}
|
||||
|
||||
// #################################################################################################################################################
|
||||
// #################################################################################################################################################
|
||||
|
|
@ -585,3 +340,35 @@ function induce(inductor) {
|
|||
}
|
||||
}
|
||||
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 {
|
||||
--background-primary: #191724;
|
||||
--navbar-color: #26233a;
|
||||
--navbar-height: 4em;
|
||||
--navbar-text-color: #e0def4;
|
||||
--navbar-height: 60px;
|
||||
--navbar-text-color: #4de0fa;
|
||||
--navbar-link-color: #e0def4;
|
||||
--navbar-font: "Roboto";
|
||||
--input-text-color: #e0def4;
|
||||
--input-placeholder-color: #6e6a86;
|
||||
--input-placeholder-color: white;
|
||||
--input-background-color: #1f1d2e;
|
||||
--input-border-color: #eb6f92;
|
||||
--input-border-size: 0.1em;
|
||||
--input-border-size: 1.3px;
|
||||
--navbar-logo-filter: none;
|
||||
}
|
||||
|
||||
::-webkit-input-placeholder {
|
||||
|
|
@ -20,7 +25,7 @@
|
|||
}
|
||||
|
||||
#navbar {
|
||||
height: 60px;
|
||||
height: var(--navbar-height);
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
|
|
@ -32,7 +37,7 @@
|
|||
}
|
||||
|
||||
a {
|
||||
color: white;
|
||||
color: var(--navbar-link-color);
|
||||
text-decoration: none !important;
|
||||
font-family: 'Roboto';
|
||||
}
|
||||
|
|
@ -81,7 +86,7 @@ a:hover {
|
|||
|
||||
::placeholder,
|
||||
input[type='text'] {
|
||||
color: white;
|
||||
color: var(--input-placeholder-color);
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
font-family: 'Roboto';
|
||||
|
|
@ -153,7 +158,7 @@ ul li ul:hover {
|
|||
text-align: center;
|
||||
font-family: 'Calibri';
|
||||
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-radius: 15px;
|
||||
background-color: var(--input-background-color);
|
||||
|
|
@ -162,7 +167,6 @@ ul li ul:hover {
|
|||
height: 50px;
|
||||
box-shadow: none !important;
|
||||
outline: none;
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-family: 'Roboto';
|
||||
animation-name: inputwide;
|
||||
|
|
@ -214,3 +218,82 @@ svg rect {
|
|||
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;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.name {
|
||||
|
|
@ -359,7 +359,7 @@ ul li {
|
|||
|
||||
.custom-dropdown select {
|
||||
background-color: #1abc9c;
|
||||
color: #fff;
|
||||
color: var(--text-color-primary);
|
||||
font-size: inherit;
|
||||
padding: .5em;
|
||||
padding-right: 2.5em;
|
||||
|
|
@ -438,3 +438,45 @@ ul li {
|
|||
font-weight: 400;
|
||||
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