8 | Please wait a moment. Our service maybe under high load causing some slowness on our
9 | servers. Your request will eventually be responded to.
10 |
11 |
12 |
38 |
39 |
--------------------------------------------------------------------------------
/src/components/settings/Loader.astro:
--------------------------------------------------------------------------------
1 |
28 |
--------------------------------------------------------------------------------
/server/message.ts:
--------------------------------------------------------------------------------
1 | import gradient from 'npm:gradient-string';
2 | import chalk from 'chalk';
3 | const message = `
4 | ___ _ _
5 | |_ _|_ __ ___ ___ _ __ (_) |_ ___
6 | | || '_ \\ / __/ _ \\| '_ \\| | __/ _ \\
7 | | || | | | (_| (_) | | | | | || (_) |
8 | |___|_| |_|\\___\\___/|_| |_|_|\\__\\___/
9 | `;
10 | const messageColors = {
11 | green: '#34b874',
12 | white: '#ffffff',
13 | blue: '#161923',
14 | };
15 |
16 | const listeningMessage = (port: number, server: 'fastify' | 'hono') => {
17 | console.log(
18 | `${chalk.hex('#34b874')('Server listening on')} ${
19 | chalk.white.bold('http://localhost:' + port)
20 | }`,
21 | );
22 | console.log(
23 | chalk.white.bold(
24 | `Server also listening on ${chalk.hex('#34b874').bold('http://0.0.0.0:' + port)}`,
25 | ),
26 | );
27 | console.log(
28 | chalk.hex('#34b874').bold(
29 | `The server in use ${
30 | server === 'fastify'
31 | ? chalk.bold.whiteBright('Fastify (Not Deno native, includes wisp server)')
32 | : chalk.bold.whiteBright('Hono (no wisp server, deno-native)')
33 | }`,
34 | ),
35 | );
36 | };
37 |
38 | export { listeningMessage, message, messageColors };
39 |
--------------------------------------------------------------------------------
/src/ts/serviceWorker.ts:
--------------------------------------------------------------------------------
1 | function initServiceWorker() {
2 | return new Promise((resolve) => {
3 | if ('serviceWorker' in navigator) {
4 | console.log('OOGOGOGOGO');
5 | //@ts-ignore these are a fucking thing
6 | //wait for the scripts to load
7 | const scram = window.loadProxyScripts().then(async (): typeof ScramjetController => {
8 | const scramjet = new ScramjetController({
9 | prefix: "/~/scramjet/",
10 | files: {
11 | wasm: "/scram/scramjet.wasm.js",
12 | worker: "/scram/scramjet.worker.js",
13 | client: "/scram/scramjet.client.js",
14 | shared: "/scram/scramjet.shared.js",
15 | sync: "/scram/scramjet.sync.js"
16 | }
17 | });
18 | //@ts-ignore these fucking exist
19 | //make sure the transport is set before continuing
20 | await window.setTransport(localStorage.getItem('incog||transport'));
21 | await scramjet.init('/sw.js');
22 | return scramjet;
23 | });
24 | return resolve(scram);
25 | };
26 | });
27 | }
28 |
29 | export { initServiceWorker };
30 |
--------------------------------------------------------------------------------
/server/standalone/standalone.ts:
--------------------------------------------------------------------------------
1 | import { Hono } from 'jsr:@hono/hono';
2 | import { serveStatic } from 'jsr:@hono/hono/deno';
3 | import { compress } from 'jsr:@hono/hono/compress';
4 | import { listeningMessage } from '../message.ts';
5 | import { config } from '../config/config.ts';
6 | import { fromFileUrl } from 'jsr:@std/path';
7 |
8 | const startServer = async (configPath: string, seo?: boolean) => {
9 | const parsedDoc = await config(configPath);
10 | const app = new Hono();
11 | const distPath = fromFileUrl(new URL('../../dist', import.meta.url));
12 |
13 | app.use(compress({
14 | encoding: 'gzip',
15 | }));
16 |
17 | app.use('/*', (ctx, next) => {
18 | if (new URL(ctx.req.url).host === new URL(Deno.env.get('DOMAIN') || parsedDoc.seo.domain).host && seo || parsedDoc.seo.enabled) {
19 | return serveStatic({ root: `${distPath}/seo` })(ctx, next);
20 | }
21 | else {
22 | return serveStatic({ root: `${distPath}/noseo` })(ctx, next);
23 | }
24 | });
25 |
26 | Deno.serve({
27 | hostname: '0.0.0.0',
28 | port: parseInt(Deno.env.get('PORT') as string) || parsedDoc.server.port || 8000,
29 | onListen() {
30 | listeningMessage(parseInt(Deno.env.get('PORT') as string) || parsedDoc.server.port || 8000, 'hono');
31 | },
32 | }, app.fetch);
33 | }
34 |
35 | export { startServer }
36 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/ISSUE-TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report Or Feature request
3 | about: Report a Bug or submit a Feature that you would like to see
4 | title: "[BUG/Feature Request]"
5 | labels: ''
6 | assignees: ''
7 | ---
8 |
9 | **Note: for support questions, please use our [Discord](https://discord.gg/unblock)**. This repository's issues are reserved for feature requests and bug reports.
10 |
11 | - **I'm submitting a ...**
12 | - [ ] bug report
13 | - [ ] feature request
14 | - [ ] support request => Please do not submit support request here, see note at the top of this template.
15 |
16 | - **Do you want to request a _feature_ or report a _bug_?**
17 |
18 | - **What is the current behavior?**
19 |
20 | - **If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem**
21 |
22 | - **What is the expected behavior?**
23 |
24 | - **What is the motivation / use case for changing the behavior?**
25 |
26 | - **Please tell us about your environment:**
27 |
28 | - Version: 2.0.0-beta.X
29 | - Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
30 | - Language: [all | TypeScript X.X | ES6/7 | ES5 | Dart]
31 |
32 | - **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)
33 |
--------------------------------------------------------------------------------
/.github/workflows/docker-build.yml:
--------------------------------------------------------------------------------
1 | name: Build Docker image
2 | on:
3 | push:
4 | tags:
5 | - v*
6 | workflow_dispatch:
7 |
8 | env:
9 | REGISTRY: ghcr.io
10 | IMAGE_NAME: ${{ github.repository }}
11 |
12 | jobs:
13 | build-and-push:
14 | name: Build and push Docker image to registry
15 | runs-on: ubuntu-latest
16 | if: ${{ github.repository_owner == 'titaniumnetwork-dev' }}
17 | permissions:
18 | contents: write
19 | packages: write
20 | steps:
21 | - name: Checkout repo
22 | uses: actions/checkout@v3
23 | - name: Setup docker buildx
24 | uses: docker/setup-buildx-action@v3
25 | - name: Login To registry ${{ env.REGISTRY }}
26 | uses: docker/login-action@v3
27 | with:
28 | registry: ${{ env.REGISTRY }}
29 | username: ${{ github.actor }}
30 | password: ${{ github.token }}
31 | - name: Extract Docker metadata
32 | id: meta
33 | uses: docker/metadata-action@v3
34 | with:
35 | images: ${{ env.REGISTRY }}/titaniumnetwork-dev/incognito
36 | - name: Build and push
37 | id: build-and-push
38 | uses: docker/build-push-action@v4
39 | with:
40 | context: .
41 | platforms: linux/amd64,linux/arm64
42 | file: ./Dockerfile
43 | name: incognito
44 | push: ${{ github.event_name != 'pull_request' }}
45 | tags: ${{ steps.meta.outputs.tags }}
46 | labels: ${{ steps.meta.outputs.labels }}
47 | cache-from: type=gha
48 | cache-to: type=gha,mode=max
49 |
--------------------------------------------------------------------------------
/server/config/config.ts:
--------------------------------------------------------------------------------
1 | import { parse } from "smol-toml";
2 |
3 | interface Data {
4 | buildOpts: {
5 | games: boolean;
6 | };
7 | server: {
8 | wisp: boolean;
9 | port: number;
10 | };
11 | seo: {
12 | enabled: boolean;
13 | domain: string;
14 | };
15 | }
16 |
17 | const config = async (configFile: string): Promise => {
18 | const doc = await Deno.readTextFile(configFile);
19 | const parsedDoc = parse(doc) as unknown as Data;
20 |
21 | if (typeof parsedDoc.buildOpts !== "object") {
22 | throw new Error(`Invalid structure: "buildOpts" should be an object`);
23 | }
24 | if (typeof parsedDoc.server !== "object") {
25 | throw new Error(`Invalid structure: "server" should be an object`);
26 | }
27 | if (typeof parsedDoc.buildOpts.games !== "boolean") {
28 | throw new Error(`Invalid type for "buildOpts.games"! It should be a boolean (true/false)`);
29 | }
30 | if (typeof parsedDoc.server.wisp !== "boolean") {
31 | throw new Error(`Invalid type for "server.wisp"! It should be a boolean (true/false)`);
32 | }
33 | if (typeof parsedDoc.server.port !== "number") {
34 | throw new Error(`Invalid type for "server.port"! It should be a number`);
35 | }
36 | if (typeof parsedDoc.seo.enabled !== "boolean") {
37 | throw new Error(`Invalid type for "seo.enabled"! It should be an boolean (true/false)`);
38 | }
39 | if (typeof parsedDoc.seo.domain !== "string") {
40 | throw new Error(`Invalid type for "seo.domain"! It should be an string`);
41 | } else {
42 | try {
43 | new URL(parsedDoc.seo.domain);
44 | } catch (e: any) {
45 | throw new Error(e);
46 | }
47 | }
48 | return parsedDoc;
49 | }
50 |
51 | export { type Data as TOMLConfig, config };
52 |
--------------------------------------------------------------------------------
/vendor/scramjet/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ---
6 |
7 | > [!WARNING]
8 | > Scramjet is not currently production ready, DO NOT USE THIS AS THE MAIN OPTION IN YOUR SITE.
9 |
10 |
11 |
12 | Scramjet is an experimental interception based web proxy that aims to be the successor to Ultraviolet. It is designed with security, developer friendliness, and performance in mind. Scramjet strives to have a clean, organized codebase to improve maintainability. Scramjet is made to evade internet censorship and bypass arbitrary web browser restrictions.
13 |
14 | ## Supported Sites
15 |
16 | Some of the popular websites that Scramjet supports include:
17 |
18 | - [Google](https://google.com)
19 | - [Youtube](https://www.youtube.com)
20 | - [Spotify](https://spotify.com)
21 | - [Discord](https://discord.com)
22 | - [Reddit](https://reddit.com)
23 | - [GeForce NOW](https://play.geforcenow.com/)
24 | - [now.gg](https://now.gg)
25 |
26 | ## Development
27 |
28 | ### Dependencies
29 |
30 | - Recent versions of `node.js` and `pnpm`
31 | - `rustup`
32 | - `wasm-bindgen`
33 | - `wasm-opt`
34 | - [this `wasm-snip` fork](https://github.com/r58Playz/wasm-snip)
35 |
36 | #### Building
37 |
38 | - Clone the repository with `git clone --recursive https://github.com/MercuryWorkshop/scramjet`
39 | - Install the dependencies with `pnpm i`
40 | - Build the rewriter with `pnpm rewriter:build`
41 | - Build Scramjet with `pnpm build`
42 |
43 | ### Running Scramjet Locally
44 |
45 | You can run the Scramjet dev server with the command
46 |
47 | ```sh
48 | pnpm dev
49 | ```
50 |
51 | Scramjet should now be running at `localhost:1337` and should rebuild upon a file being changed (excluding the rewriter).
52 |
--------------------------------------------------------------------------------
/server/full/server.ts:
--------------------------------------------------------------------------------
1 | import fastifyCompress from '@fastify/compress';
2 | import fastifyCookie from '@fastify/cookie';
3 | import fastifyHttpProxy from '@fastify/http-proxy';
4 | import fastifyMiddie from '@fastify/middie';
5 | import fastifyStatic from '@fastify/static';
6 | import Fastify from 'fastify';
7 | import { sFactory } from './serverFactory.ts';
8 | import { listeningMessage } from "../message.ts";
9 | import { config } from "../config/config.ts";
10 | import { fromFileUrl } from "jsr:@std/path";
11 |
12 | const startServer = async (configPath: string, seo?: boolean) => {
13 | const parsedDoc = await config(configPath);
14 | const serverFactory = await sFactory(configPath);
15 | const distPath = fromFileUrl(new URL('../../dist', import.meta.url));
16 | const app = Fastify({ logger: false, serverFactory: serverFactory });
17 |
18 | await app.register(fastifyCookie, {
19 | secret: Deno.env.get('COOKIE_SECRET') || 'yes',
20 | parseOptions: {}
21 | });
22 | await app.register(fastifyCompress, {
23 | encodings: ['br', 'gzip', 'deflate']
24 | });
25 |
26 | await app.register(fastifyStatic, {
27 | root: `${distPath}/noseo`,
28 | etag: false,
29 | lastModified: false
30 | });
31 | if (seo || parsedDoc.seo.enabled) {
32 | await app.register(fastifyStatic, {
33 | root: `${distPath}/seo`,
34 | constraints: { host: new URL(Deno.env.get('DOMAIN') || parsedDoc.seo.domain).host },
35 | etag: false,
36 | lastModified: false,
37 | decorateReply: false
38 | })
39 | }
40 |
41 | await app.register(fastifyMiddie);
42 | await app.register(fastifyHttpProxy, {
43 | upstream: 'https://rawcdn.githack.com/ruby-network/ruby-assets/main/',
44 | prefix: '/gms/',
45 | http2: false
46 | });
47 |
48 | const port = parseInt(Deno.env.get('PORT') as string) || parsedDoc.server.port || 8000;
49 |
50 | app.listen({ port: port, host: '0.0.0.0' }).then(() => {
51 | listeningMessage(port, "fastify");
52 | });
53 | }
54 |
55 | export { startServer }
56 |
--------------------------------------------------------------------------------
/vendor/scramjet/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@mercuryworkshop/scramjet",
3 | "version": "1.0.2-dev",
4 | "description": "An experimental web proxy that aims to be the successor to Ultraviolet",
5 | "main": "./lib/index.cjs",
6 | "types": "./lib/index.d.js",
7 | "type": "module",
8 | "repository": {
9 | "type": "git",
10 | "url": "https://github.com/MercuryWorkshop/scramjet"
11 | },
12 | "files": [
13 | "dist/*.js",
14 | "dist/*.js.map",
15 | "lib"
16 | ],
17 | "keywords": [],
18 | "author": "",
19 | "license": "MIT",
20 | "devDependencies": {
21 | "@eslint/eslintrc": "^3.2.0",
22 | "@eslint/js": "^9.17.0",
23 | "@estruyf/github-actions-reporter": "^1.9.2",
24 | "@fastify/static": "^8.0.3",
25 | "@mercuryworkshop/bare-as-module3": "^2.2.5",
26 | "@mercuryworkshop/epoxy-transport": "^2.1.27",
27 | "@mercuryworkshop/libcurl-transport": "^1.3.14",
28 | "@nebula-services/bare-server-node": "^2.0.4",
29 | "@playwright/test": "^1.49.1",
30 | "@rsdoctor/rspack-plugin": "^0.4.11",
31 | "@rspack/cli": "^1.1.6",
32 | "@rspack/core": "^1.1.6",
33 | "@types/eslint": "^9.6.1",
34 | "@types/estree": "^1.0.6",
35 | "@types/node": "^22.10.2",
36 | "@types/serviceworker": "^0.0.107",
37 | "@typescript-eslint/eslint-plugin": "^8.18.0",
38 | "@typescript-eslint/parser": "^8.18.0",
39 | "dotenv": "^16.4.7",
40 | "eslint": "^9.17.0",
41 | "fastify": "^5.1.0",
42 | "playwright": "^1.49.1",
43 | "prettier": "^3.4.2",
44 | "tslib": "^2.8.1",
45 | "typescript": "^5.7.2",
46 | "wisp-server-node": "^1.1.7"
47 | },
48 | "dependencies": {
49 | "@mercuryworkshop/bare-mux": "^2.1.7",
50 | "dom-serializer": "^2.0.0",
51 | "domhandler": "^5.0.3",
52 | "domutils": "^3.1.0",
53 | "htmlparser2": "^9.1.0",
54 | "parse-domain": "^8.2.2",
55 | "set-cookie-parser": "^2.7.1"
56 | },
57 | "scripts": {
58 | "build": "rspack build --mode production",
59 | "rewriter:build": "cd rewriter/wasm/ && bash build.sh && cd ../../",
60 | "dev": "node server.js",
61 | "pub": "npm publish --no-git-checks --access public",
62 | "format": "prettier --config .prettierrc.js --write .",
63 | "lint": "eslint ./src/",
64 | "lint:fix": "eslint ./src/ --fix",
65 | "test": "npx playwright test"
66 | }
67 | }
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 1.0.0
2 | - The initial rewrite to Astro. Includes:
3 | - Fully static
4 | - Easier to build
5 | - Feels/is faster to use
6 | - Fixes some bugs
7 | - Among tons of other stuff
8 |
9 | # 1.0.1
10 | - Fixes the games and apps page looking weird
11 |
12 | # 1.0.2
13 | - Fixes Dockerfile issues
14 |
15 | # 1.0.3
16 | - Turns off Rammerhead by default for now
17 | - Docker env fixes again
18 | - SEO
19 |
20 | # 1.0.4
21 | - Bumps RH
22 | - Fixes issues with bare-server-node
23 |
24 | # 1.1.0
25 | - Switches to Deno (mostly)
26 | - General bug fixes
27 | - Removes Rammerhead as an option and replaces it with Scramjet (coming soon)
28 | - Removes bare server and adds libcurl as an option
29 | - Adds a different Deno native server (Hono) - Command: `deno task start:standalone`
30 | - Removes Masqr
31 | - No more SSR, it's purely statically generated
32 | - CI fixes and other general improvements
33 | - Configuration is done via TOML over a bunch of environment vars
34 | - Removes Biome in place of Deno's native formatter
35 | - A better roadmap of what should be done in the future.
36 |
37 | # 1.1.1
38 | - Fixes a bug where if games aren't enabled it redirects to localhost:8080 over just /
39 | - Fixes a bug where if games aren't enabled, it still loads and compresses images over just ignoring them.
40 |
41 | # 1.1.2
42 | - Fixes bugs with apps opening as the full url instead of just the correct link
43 | - Fixes a bug with the iFrame panel where it copies & pastes the full link instead of just the normal link.
44 | - Add Scramjet
45 |
46 | # 1.1.3
47 | - Add the notice that ScramJet is in beta and may break
48 |
49 | # 1.1.4
50 | - Add the ability to disable/enable SEO or selectively render/show it
51 | - Adds the docker-builds.yml file to show the builds I am doing for the docker images.
52 |
53 | # 1.1.5
54 | - Fixes the games (mostly)
55 |
56 | # 1.1.6
57 | - Add the ability to run Incog from a prebuilt file
58 |
59 | # 1.1.7
60 | - Builds both the SEO & non SEO versions of the website for easier deployment
61 | - Adds a `--seo` CLI flag which can enable the SEO build without the config.toml file
62 | - CLI is now easier to use & interact with
63 | - Change and cleanup docs
64 | - Docker command cleanup to reflect new changes
65 | - docker-compose.build.yml no longer exists.
66 |
67 | # v1.1.8
68 | - Add the ability to self update your binary
69 | - Change the way parts of the CLI look
70 |
--------------------------------------------------------------------------------
/src/components/MobileNav.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { Icon } from 'astro-icon/components';
3 | const { options, page } = Astro.props;
4 | import { GAMES_LINK } from 'astro:env/client';
5 | ---
6 |
26 |
27 | ## NOTE:
28 |
29 | - This will **NOT** deploy on Github Pages, Netlify, Vercel, Gitlab Pages or any other _static_ host
30 | - This will **NOT** work on Render
31 |
32 | ---
33 |
34 | ## How to get links
35 |
36 | [](https://discord.gg/unblock)
37 |
38 | ---
39 |
40 | ## Features
41 |
42 | - Lots and lots of games
43 |
44 | - Multiple Proxy "Backends":
45 | - [Ultraviolet](https://github.com/titaniumnetwork-dev/ultraviolet)
46 | - [Scramjet](https://github.com/mercuryworkshop/scramjet)
47 |
48 | ---
49 |
50 | ## Contributors
51 |
52 | - [MotorTruck1221](https://motortruck1221.com) - Maintainer
53 | - [Rifting](https://github.com/rifting) - Maintainer
54 | - [caracal-js](https://github.com/caracal-js) - Original Creator
55 |
56 | ---
57 |
58 | ## Tech Stack
59 |
60 | - [Astro](https://astro.build)
61 | - [Fastify](https://fastify.dev)
62 | - [Ultraviolet](https://github.com/titaniumnetwork-dev/ultraviolet)
63 | - [Epoxy](https://github.com/mercuryworkshop/epoxy-tls)
64 | - [Libcurl.js](https://github.com/ading2210/libcurl.js)
65 | - [Hono](https://github.com/honojs) as a Deno native alternative to fastify. Run with command: `deno task start --server standalone`
66 | - [Deno 2.0](https://github.com/denoland/deno)
67 | - HTML, CSS, and JavaScript (DUH)
68 |
69 | ---
70 |
71 | ## Roadmap
72 |
73 | - [x] - [Implement Scramjet](https://github.com/mercuryworkshop/scramjet)
74 | - [ ] - Remove dependency on Fastify & switch completely to Hono
75 | - [ ] - General codebase cleanup & remove all of the functions exisiting on `window`
76 | - [ ] - Games page needs to be reworked due to more games
77 | - [ ] - [i18n](https://github.com/alexandre-fernandez/astro-i18n)
78 | - [ ] - More themes
79 | - [ ] - Detatch from the [Original repo](https://github.com/caracal-js/incognito)
80 |
81 | ---
82 |
83 | ## Branches
84 |
85 | - main - Latest stable branch & production ready
86 | - dev - all major changes are made here before being merged into main
87 |
88 | ---
89 |
90 | ## Deployment
91 |
92 | - Incognito is the easiest proxy to deploy!
93 | - Currently, there are 3 ways to deploy Incognito
94 | - [Pre-built binaries](#Pre-built-binaries)
95 | - [Docker]()
96 | - [Building and running yourself]()
97 |
98 | #### Pre-built Binaries
99 |
100 | - When a new version is pushed, our CI automagically builds & uploads pre-built binaries to the release.
101 | - This enables you to:
102 | - A. Not install any extra runtime or install any new packages
103 | - B. Updates are easy and quick. Just download the new binary!
104 |
105 | ###### Usage:
106 |
107 | - First grab the current binary for your system & OS [here](https://github.com/titaniumnetwork-dev/incognito/releases/latest)
108 | - Then simply run the binary!
109 | - For example using linux:
110 | ```bash
111 | ./incognito-linux --server full
112 | ```
113 |
114 | > [!NOTE]
115 | > - You MAY have to make the binary executable on certain systems.
116 | > - For example in Linux:
117 | > ```bash
118 | > chmod +x ./incognito-linux
119 | > ```
120 | >
121 | > - To see all of the CLI options & usage see: [cli](#cli)
122 |
123 | #### Docker
124 |
125 | - Docker is the second easiest way to run Incognito.
126 | - Currently, Docker images are built by [@motortruck1221](https://github.com/motortruck1221) manually per version update.
127 | - They can be located here: [https://hub.docker.com/r/motortruck1221/incognito](https://hub.docker.com/r/motortruck1221/incognito)
128 | - This enables:
129 | - Automatic updates
130 | - Easier deployment then building yourself.
131 | - No dependencies besides docker w/compose
132 |
133 | ###### Usage:
134 |
135 | - The Docker builds currently have 2 tags:
136 | - Latest
137 | - Or a pinned version of the build (eg: 1.1.7)
138 | - Currently, only Docker compose is supported. Docker without compose *can be used* but it's highly discouraged.
139 |
140 | - Prerequisites:
141 | - Docker w/compose
142 |
143 | - First, create a `config.toml` file and copy the [example config from the repo](https://github.com/titaniumnetwork-dev/incognito/blob/main/config.example.toml)
144 | - Then, copy and paste the contents of the [docker-compose.yml file](https://github.com/titaniumnetwork-dev/incognito/blob/main/docker-compose.yml) into your own docker-compose.yml file
145 | - After that, edit the `docker-compose.yml` file to your liking.
146 | - And finally:
147 | ```bash
148 | docker compose up
149 | ```
150 | - That should fire Incognito up and you should be good!
151 |
152 | > [!NOTE]
153 | > - To see all of the CLI options & usage see: [cli](#cli)
154 | >
155 | > - To see all of the `config.toml` options see: [config](#config)
156 |
157 | #### Building & Running yourself
158 |
159 | - This is the last way to run Incognito
160 |
161 | ###### Usage:
162 |
163 | - Prerequisites:
164 | - Git
165 | - Deno 2.1.4 or newer
166 | - Node.js & NPM
167 |
168 | 1. Clone the repo
169 | ```bash
170 | git clone https://github.com/titaniumnetwork-dev/incognito.git
171 | ```
172 |
173 | 2. Install all of the dependencies:
174 | ```bash
175 | deno install --allow-scripts # This flag is here due to sharp, bufferutil and some others
176 | ```
177 |
178 | 3. Create a `config.toml` file
179 | ```bash
180 | cp config.example.toml config.toml
181 | ```
182 |
183 | 4. Modify the `config.toml` file to your liking. See: [config](#config)
184 |
185 | 5. Build the frontend
186 | ```bash
187 | deno task build
188 | ```
189 |
190 | 6. Start the server
191 | ```bash
192 | deno task start --server full
193 | ```
194 |
195 | > [!NOTE]
196 | > - To see all of the CLI options & usage see: [cli](#cli)
197 |
198 | ---
199 |
200 | ## CLI
201 |
202 | - Incognito has a built in CLI for starting and running
203 | - Currently, there are only 4 flags. And 1 extra command
204 |
205 | - `--help` - This triggers the help prompt even when other flags are passed.
206 | - `--server [full|standalone]` - Choose between the full or standalone server. This option is ***required*** otherwise, it will just show the help prompt.
207 | - Full - Uses Fastify has a built in Wisp server (via [wisp server node](https://github.com/mercuryworkshop/wisp-server-node)) *(recommended for self hosters)*
208 | - Standalone - Uses Hono as the server with no built in Wisp server. *(recommended for a huge production instance with an external wisp server)*
209 | - These are the only two options. Anything else passed here WILL throw an error.
210 | - `--config ` - Use a config located somewhere else.
211 | - Useful when using the [Pre-built binaries](#pre-built-binaries)
212 | - The path can either be absolute or relative.
213 | - `--seo` - Currently the default is to only use the build with no seo enabled. This flag enables the seo build.
214 | - Domain must be set in the [config](#config)
215 | - Overrides the enabled option in the [config](#config)
216 |
217 | - `upgrade` - Allows for the ability to self-update the binary. Run this to self upgrade
218 | - `--check` check for a new version. Tells you if one is available.
219 |
220 | ---
221 |
222 | ## Config
223 |
224 | - Incognito currently uses a config file in the toml format.
225 | - An example of this file can be found [here](https://github.com/titaniumnetwork-dev/incognito/blob/main/config.example.toml)
226 |
227 | ##### Build Opts
228 | | Type | Default | Description | Can be overwritten by ENV var |
229 | |------|---------|------------------------------------|-------------------------------|
230 | | games | `true` | Disables or enables the games page | - [ ] - No |
231 |
232 | ##### Server
233 | | Type | Default | Description | Can be overwritten by ENV var |
234 | |------|---------|-----------------------------------------------------------------------------------------------------------------|------------------------------|
235 | | port | `8000` | Change the default port. *Note: the environment var `PORT` takes precedence* | - [x] - Yes |
236 | | wisp | `true` | Disable or enables the in built wisp server. *Note: when using the Hono server there is no built-in wisp server | - [ ] - No |
237 |
238 | ##### SEO
239 | | Type | Default | Description | Can be overwritten by ENV var |
240 | ---------|-------------------------|--------------------------------------------------------------------------|-------------------------------|
241 | | SEO | `false` | Change whether or not to enabled SEO | - [x] - Yes - `SEO` (as well via a CLI flag `--seo` |
242 | | DOMAIN | `http://localhost:8000` | When the `both` option is enable, only show the SEO stuff on this domain | - [x] - Yes - `DOMAIN` |
243 |
--------------------------------------------------------------------------------
/vendor/scramjet/dist/scramjet.controller.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"scramjet.controller.js","sources":["webpack://@mercuryworkshop/scramjet/./src/log.ts","webpack://@mercuryworkshop/scramjet/./src/symbols.ts","webpack://@mercuryworkshop/scramjet/./src/controller/frame.ts","webpack://@mercuryworkshop/scramjet/./src/scramjet.ts","webpack://@mercuryworkshop/scramjet/./src/controller/index.ts"],"sourcesContent":["export default {\n\tfmt: function (severity: string, message: string, ...args: any[]) {\n\t\tconst old = Error.prepareStackTrace;\n\n\t\tError.prepareStackTrace = (_, stack) => {\n\t\t\tstack.shift(); // stack();\n\t\t\tstack.shift(); // fmt();\n\t\t\tstack.shift();\n\n\t\t\tlet fmt = \"\";\n\t\t\tfor (let i = 1; i < Math.min(2, stack.length); i++) {\n\t\t\t\tif (stack[i].getFunctionName()) {\n\t\t\t\t\t// const f = stack[i].getThis()?.constructor?.name;\n\t\t\t\t\t// if (f) fmt += `${f}.`\n\t\t\t\t\tfmt += `${stack[i].getFunctionName()} -> ` + fmt;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfmt += stack[0].getFunctionName() || \"Anonymous\";\n\n\t\t\treturn fmt;\n\t\t};\n\n\t\tconst fmt = (function stack() {\n\t\t\ttry {\n\t\t\t\tthrow new Error();\n\t\t\t} catch (e) {\n\t\t\t\treturn e.stack;\n\t\t\t}\n\t\t})();\n\n\t\tError.prepareStackTrace = old;\n\n\t\tconst fn = console[severity] || console.log;\n\t\tconst bg = {\n\t\t\tlog: \"#000\",\n\t\t\twarn: \"#f80\",\n\t\t\terror: \"#f00\",\n\t\t\tdebug: \"transparent\",\n\t\t}[severity];\n\t\tconst fg = {\n\t\t\tlog: \"#fff\",\n\t\t\twarn: \"#fff\",\n\t\t\terror: \"#fff\",\n\t\t\tdebug: \"gray\",\n\t\t}[severity];\n\t\tconst padding = {\n\t\t\tlog: 2,\n\t\t\twarn: 4,\n\t\t\terror: 4,\n\t\t\tdebug: 0,\n\t\t}[severity];\n\n\t\tfn(\n\t\t\t`%c${fmt}%c ${message}`,\n\t\t\t`\n\t\tbackground-color: ${bg};\n\t\tcolor: ${fg};\n\t\tpadding: ${padding}px;\n\t\tfont-weight: bold;\n\t\tfont-family: monospace;\n\t\tfont-size: 0.9em;\n\t`,\n\t\t\t`${severity === \"debug\" ? \"color: gray\" : \"\"}`,\n\t\t\t...args\n\t\t);\n\t},\n\tlog: function (message: string, ...args: any[]) {\n\t\tthis.fmt(\"log\", message, ...args);\n\t},\n\twarn: function (message: string, ...args: any[]) {\n\t\tthis.fmt(\"warn\", message, ...args);\n\t},\n\terror: function (message: string, ...args: any[]) {\n\t\tthis.fmt(\"error\", message, ...args);\n\t},\n\tdebug: function (message: string, ...args: any[]) {\n\t\tthis.fmt(\"debug\", message, ...args);\n\t},\n};\n","// see types.d.ts for what these mean\nexport const SCRAMJETCLIENT = Symbol.for(\"scramjet client global\");\nexport const SCRAMJETFRAME = Symbol.for(\"scramjet frame handle\");\n","import { ScramjetController } from \".\";\nimport type { ScramjetClient } from \"../client/client\";\nimport { SCRAMJETCLIENT, SCRAMJETFRAME } from \"../symbols\";\n\nexport class ScramjetFrame extends EventTarget {\n\tconstructor(\n\t\tprivate controller: ScramjetController,\n\t\tpublic frame: HTMLIFrameElement\n\t) {\n\t\tsuper();\n\t\tframe[SCRAMJETFRAME] = this;\n\t}\n\n\tget client(): ScramjetClient {\n\t\treturn this.frame.contentWindow.window[SCRAMJETCLIENT];\n\t}\n\n\tget url(): URL {\n\t\treturn this.client.url;\n\t}\n\n\tgo(url: string | URL) {\n\t\tif (url instanceof URL) url = url.toString();\n\n\t\tdbg.log(\"navigated to\", url);\n\n\t\tthis.frame.src = this.controller.encodeUrl(url);\n\t}\n\n\tback() {\n\t\tthis.frame.contentWindow?.history.back();\n\t}\n\n\tforward() {\n\t\tthis.frame.contentWindow?.history.forward();\n\t}\n\n\treload() {\n\t\tthis.frame.contentWindow?.location.reload();\n\t}\n}\n","import { ScramjetFlags } from \"./types\";\n\nif (!(\"$scramjet\" in self)) {\n\t// @ts-expect-error ts stuff\n\tself.$scramjet = {\n\t\tversion: {\n\t\t\tbuild: COMMITHASH,\n\t\t\tversion: VERSION,\n\t\t},\n\t\tcodec: {},\n\t\tflagEnabled,\n\t};\n}\n\nexport const $scramjet = self.$scramjet;\n\nconst nativeFunction = Function;\nexport function loadCodecs() {\n\t$scramjet.codec.encode = nativeFunction(\n\t\t\"url\",\n\t\t$scramjet.config.codec.encode\n\t) as any;\n\t$scramjet.codec.decode = nativeFunction(\n\t\t\"url\",\n\t\t$scramjet.config.codec.decode\n\t) as any;\n}\n\nexport function flagEnabled(flag: keyof ScramjetFlags, url: URL): boolean {\n\tconst value = $scramjet.config.flags[flag];\n\tfor (const regex in $scramjet.config.siteFlags) {\n\t\tconst partialflags = $scramjet.config.siteFlags[regex];\n\t\tif (new RegExp(regex).test(url.href) && flag in partialflags) {\n\t\t\treturn partialflags[flag];\n\t\t}\n\t}\n\n\treturn value;\n}\n","import { ScramjetConfig } from \"../types\";\nimport { ScramjetFrame } from \"./frame\";\nimport { $scramjet, loadCodecs } from \"../scramjet\";\n\nexport class ScramjetController {\n\tprivate db: IDBDatabase;\n\n\tconstructor(config: Partial) {\n\t\t// sane ish defaults\n\t\tconst defaultConfig: ScramjetConfig = {\n\t\t\tprefix: \"/scramjet/\",\n\t\t\tglobals: {\n\t\t\t\twrapfn: \"$scramjet$wrap\",\n\t\t\t\twrapthisfn: \"$scramjet$wrapthis\",\n\t\t\t\ttrysetfn: \"$scramjet$tryset\",\n\t\t\t\timportfn: \"$scramjet$import\",\n\t\t\t\trewritefn: \"$scramjet$rewrite\",\n\t\t\t\tmetafn: \"$scramjet$meta\",\n\t\t\t\tsetrealmfn: \"$scramjet$setrealm\",\n\t\t\t\tpushsourcemapfn: \"$scramjet$pushsourcemap\",\n\t\t\t},\n\t\t\tfiles: {\n\t\t\t\twasm: \"/scramjet.wasm.js\",\n\t\t\t\tshared: \"/scramjet.shared.js\",\n\t\t\t\tworker: \"/scramjet.worker.js\",\n\t\t\t\tclient: \"/scramjet.client.js\",\n\t\t\t\tsync: \"/scramjet.sync.js\",\n\t\t\t},\n\t\t\tflags: {\n\t\t\t\tserviceworkers: false,\n\t\t\t\tsyncxhr: false,\n\t\t\t\tnaiiveRewriter: false,\n\t\t\t\tstrictRewrites: true,\n\t\t\t\trewriterLogs: true,\n\t\t\t\tcaptureErrors: true,\n\t\t\t\tcleanErrors: false,\n\t\t\t\tscramitize: false,\n\t\t\t\tsourcemaps: false,\n\t\t\t},\n\t\t\tsiteFlags: {},\n\t\t\tcodec: {\n\t\t\t\tencode: `if (!url) return url;\n\t\t\t\t\treturn encodeURIComponent(url);`,\n\t\t\t\tdecode: `if (!url) return url;\n\t\t\t\t\treturn decodeURIComponent(url);`,\n\t\t\t},\n\t\t};\n\n\t\tconst deepMerge = (target: any, source: any): any => {\n\t\t\tfor (const key in source) {\n\t\t\t\tif (source[key] instanceof Object && key in target) {\n\t\t\t\t\tObject.assign(source[key], deepMerge(target[key], source[key]));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn Object.assign(target || {}, source);\n\t\t};\n\n\t\t$scramjet.config = deepMerge(defaultConfig, config);\n\t}\n\n\tasync init(serviceWorkerPath: string): Promise {\n\t\tloadCodecs();\n\n\t\tawait this.openIDB();\n\n\t\tconst reg = await navigator.serviceWorker.register(serviceWorkerPath);\n\t\tdbg.log(\"service worker registered\");\n\n\t\treturn reg;\n\t}\n\n\tcreateFrame(frame?: HTMLIFrameElement): ScramjetFrame {\n\t\tif (!frame) {\n\t\t\tframe = document.createElement(\"iframe\");\n\t\t}\n\n\t\treturn new ScramjetFrame(this, frame);\n\t}\n\n\tencodeUrl(url: string | URL): string {\n\t\tif (url instanceof URL) url = url.toString();\n\n\t\treturn $scramjet.config.prefix + $scramjet.codec.encode(url);\n\t}\n\n\tdecodeUrl(url: string | URL) {\n\t\tif (url instanceof URL) url = url.toString();\n\n\t\treturn $scramjet.codec.decode(url);\n\t}\n\n\tasync openIDB(): Promise {\n\t\tconst db = indexedDB.open(\"$scramjet\", 1);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tdb.onsuccess = async () => {\n\t\t\t\tthis.db = db.result;\n\t\t\t\tawait this.#saveConfig();\n\t\t\t\tresolve(db.result);\n\t\t\t};\n\t\t\tdb.onupgradeneeded = () => {\n\t\t\t\tconst res = db.result;\n\t\t\t\tif (!res.objectStoreNames.contains(\"config\")) {\n\t\t\t\t\tres.createObjectStore(\"config\");\n\t\t\t\t}\n\t\t\t\tif (!res.objectStoreNames.contains(\"cookies\")) {\n\t\t\t\t\tres.createObjectStore(\"cookies\");\n\t\t\t\t}\n\t\t\t};\n\t\t\tdb.onerror = () => reject(db.error);\n\t\t});\n\t}\n\n\tasync #saveConfig() {\n\t\tif (!this.db) {\n\t\t\tconsole.error(\"Store not ready!\");\n\n\t\t\treturn;\n\t\t}\n\t\tconst tx = this.db.transaction(\"config\", \"readwrite\");\n\t\tconst store = tx.objectStore(\"config\");\n\t\tconst req = store.put($scramjet.config, \"config\");\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\treq.onsuccess = resolve;\n\t\t\treq.onerror = reject;\n\t\t});\n\t}\n\n\tasync modifyConfig(config: ScramjetConfig) {\n\t\t$scramjet.config = Object.assign({}, $scramjet.config, config);\n\t\tloadCodecs();\n\n\t\tawait this.#saveConfig();\n\t}\n}\n\nwindow.ScramjetController = ScramjetController;\n"],"names":["severity","message","args","old","Error","_","stack","fmt","i","Math","e","fn","console","SCRAMJETCLIENT","Symbol","SCRAMJETFRAME","ScramjetFrame","EventTarget","controller","frame","url","URL","dbg","self","COMMITHASH","VERSION","flagEnabled","flag","value","$scramjet","regex","partialflags","RegExp","nativeFunction","Function","loadCodecs","window","ScramjetController","config","defaultConfig","deepMerge","target","source","key","Object","serviceWorkerPath","reg","navigator","document","db","indexedDB","Promise","resolve","reject","res","req","store","tx"],"mappings":"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"}
--------------------------------------------------------------------------------
/vendor/scramjet/dist/scramjet.worker.js:
--------------------------------------------------------------------------------
1 | (()=>{"use strict";var e={1762:function(e,t,r){r.d(t,{Z:function(){return o}});let o={fmt:function(e,t,...r){let o=Error.prepareStackTrace;Error.prepareStackTrace=(e,t)=>{t.shift(),t.shift(),t.shift();let r="";for(let e=1;e `+r);return r+=t[0].getFunctionName()||"Anonymous"};let s=function(){try{throw Error()}catch(e){return e.stack}}();Error.prepareStackTrace=o;let n=console[e]||console.log;n(`%c${s}%c ${t}`,`
2 | background-color: ${{log:"#000",warn:"#f80",error:"#f00",debug:"transparent"}[e]};
3 | color: ${{log:"#fff",warn:"#fff",error:"#fff",debug:"gray"}[e]};
4 | padding: ${{log:2,warn:4,error:4,debug:0}[e]}px;
5 | font-weight: bold;
6 | font-family: monospace;
7 | font-size: 0.9em;
8 | `,`${"debug"===e?"color: gray":""}`,...r)},log:function(e,...t){this.fmt("log",e,...t)},warn:function(e,...t){this.fmt("warn",e,...t)},error:function(e,...t){this.fmt("error",e,...t)},debug:function(e,...t){this.fmt("debug",e,...t)}}}},t={};function r(o){var s=t[o];if(void 0!==s)return s.exports;var n=t[o]={exports:{}};return e[o](n,n.exports,r),n.exports}r.d=function(e,t){for(var o in t)r.o(t,o)&&!r.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};class o{handle;origin;syncToken;promises;messageChannel;connected;constructor(e,t){this.handle=e,this.origin=t,this.syncToken=0,this.promises={},this.messageChannel=new MessageChannel,this.connected=!1,this.messageChannel.port1.addEventListener("message",e=>{"scramjet$type"in e.data&&("init"===e.data.scramjet$type?this.connected=!0:this.handleMessage(e.data))}),this.messageChannel.port1.start(),this.handle.postMessage({scramjet$type:"init",scramjet$port:this.messageChannel.port2},[this.messageChannel.port2])}handleMessage(e){let t=this.promises[e.scramjet$token];t&&(t(e),delete this.promises[e.scramjet$token])}async fetch(e){let t=this.syncToken++,r={scramjet$type:"fetch",scramjet$token:t,scramjet$request:{url:e.url,body:e.body,headers:Array.from(e.headers.entries()),method:e.method,mode:e.mode,destinitation:e.destination}},o=e.body?[e.body]:[];this.handle.postMessage(r,o);let{scramjet$response:s}=await new Promise(e=>{this.promises[t]=e});return!!s&&new Response(s.body,{headers:s.headers,status:s.status,statusText:s.statusText})}}!("$scramjet"in self)&&(self.$scramjet={version:{build:"1efcf85",version:"1.0.2-dev"},codec:{},flagEnabled:function(e,t){let r=s.config.flags[e];for(let r in s.config.siteFlags){let o=s.config.siteFlags[r];if(new RegExp(r).test(t.href)&&e in o)return o[e]}return r}});let s=self.$scramjet,n=Function,{util:{BareClient:i,ScramjetHeaders:a,BareMuxConnection:c},url:{rewriteUrl:l,unrewriteUrl:d,rewriteBlob:u,unrewriteBlob:h},rewrite:{rewriteCss:p,unrewriteCss:f,rewriteHtml:m,unrewriteHtml:g,rewriteSrcset:y,rewriteJs:b,rewriteHeaders:w,rewriteWorkers:v,htmlRules:k},CookieStore:x}=s.shared;function R(e){return{origin:e,base:e}}async function S(e,t){let r=new URLSearchParams(new URL(e.url).search);if(r.has("url"))return Response.redirect(l(r.get("url"),R(new URL(r.get("url")))));try{let o=new URL(e.url),n="";if(o.searchParams.has("type")&&(n=o.searchParams.get("type"),o.searchParams.delete("type")),o.searchParams.has("dest")&&o.searchParams.delete("dest"),o.pathname.startsWith(this.config.prefix+"blob:")||o.pathname.startsWith(this.config.prefix+"data:")){let r,s=o.pathname.substring(this.config.prefix.length);s.startsWith("blob:")&&(s=h(s));let i=await fetch(s,{}),a=s.startsWith("blob:")?s:"(data url)";i.finalURL=a,i.body&&(r=await $(i,t?{base:new URL(new URL(t.url).origin),origin:new URL(new URL(t.url).origin)}:R(new URL(d(e.referrer))),e.destination,n,this.cookieStore));let c=Object.fromEntries(i.headers.entries());return crossOriginIsolated&&(c["Cross-Origin-Opener-Policy"]="same-origin",c["Cross-Origin-Embedder-Policy"]="require-corp"),new Response(r,{status:i.status,statusText:i.statusText,headers:c})}let i=new URL(d(o)),c=this.serviceWorkers.find(e=>e.origin===i.origin);if(c&&c.connected&&"swruntime"!==r.get("from")){let t=await c.fetch(e);if(t)return t}if(i.origin==new URL(e.url).origin)throw Error("attempted to fetch from same origin - this means the site has obtained a reference to the real origin, aborting");let l=new a;for(let[t,r]of e.headers.entries())l.set(t,r);if(t&&new URL(t.url).pathname.startsWith(s.config.prefix)){let e=new URL(d(t.url));e.toString().includes("youtube.com")||(l.set("Referer",e.toString()),l.set("Origin",e.origin?`${e.protocol}//${e.host}`:"null"))}let u=this.cookieStore.getCookies(i,!1);u.length&&l.set("Cookie",u),l.set("Sec-Fetch-Dest",e.destination),l.set("Sec-Fetch-Site","same-origin"),l.set("Sec-Fetch-Mode","cors"===e.mode?e.mode:"same-origin");let p=new E(i,e.body,e.method,e.destination,t,l.headers);this.dispatchEvent(p);let f=p.response||await this.client.fetch(p.url,{method:p.method,body:p.body,headers:p.requestHeaders,credentials:"omit",mode:"cors"===e.mode?e.mode:"same-origin",cache:e.cache,redirect:"manual",duplex:"half"});return await C(i,n,e.destination,f,this.cookieStore,t,this)}catch(r){let t={message:r.message,url:e.url,destination:e.destination,timestamp:new Date().toISOString()};if(r.stack&&(t.stack=r.stack),console.error("ERROR FROM SERVICE WORKER FETCH: ",t),!["document","iframe"].includes(e.destination))return new Response(void 0,{status:500});return function(e,t){let r={"content-type":"text/html"};return crossOriginIsolated&&(r["Cross-Origin-Embedder-Policy"]="require-corp"),new Response(function(e,t){let r=`
9 | errorTrace.value = ${JSON.stringify(e)};
10 | fetchedURL.textContent = ${JSON.stringify(t)};
11 | for (const node of document.querySelectorAll("#hostname")) node.textContent = ${JSON.stringify(location.hostname)};
12 | reload.addEventListener("click", () => location.reload());
13 | version.textContent = ${JSON.stringify(s.version.version)};
14 | build.textContent = ${JSON.stringify(s.version.build)};
15 |
16 | document.getElementById('copy-button').addEventListener('click', async () => {
17 | const text = document.getElementById('errorTrace').value;
18 | await navigator.clipboard.writeText(text);
19 | const btn = document.getElementById('copy-button');
20 | btn.textContent = 'Copied!';
21 | setTimeout(() => btn.textContent = 'Copy', 2000);
22 | });
23 | `;return`
24 |
25 |
26 |
27 | Scramjet
28 |
141 |
142 |
143 |
144 |