diff --git a/.gitignore b/.gitignore index 5dd1bb5e..01d75f32 100644 --- a/.gitignore +++ b/.gitignore @@ -174,4 +174,5 @@ pages/dist log.txt *.log build -config/extended_description_test.md \ No newline at end of file +config/extended_description_test.md +glitch \ No newline at end of file diff --git a/bun.lockb b/bun.lockb index 66275428..0280bdd6 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/config/config.example.toml b/config/config.example.toml index 0335c88e..c1798df0 100644 --- a/config/config.example.toml +++ b/config/config.example.toml @@ -90,6 +90,14 @@ bait_user_agents = ["curl", "wget"] # The URL to reach the frontend at (should be on a local network) url = "http://localhost:3000" +[frontend.glitch] +# Enable the Glitch frontend integration +enabled = false +# Glitch assets folder +assets = "glitch" +# Server the assets were ripped from (and any eventual CDNs) +server = ["https://glitch.social", "https://static.glitch.social"] + [smtp] # SMTP server to use for sending emails server = "smtp.example.com" diff --git a/packages/config-manager/config.type.ts b/packages/config-manager/config.type.ts index 4483f10e..8b655b55 100644 --- a/packages/config-manager/config.type.ts +++ b/packages/config-manager/config.type.ts @@ -123,6 +123,17 @@ export interface Config { frontend: { /** @default "http://localhost:3000" */ url: string; + + glitch: { + /** @default false */ + enabled: boolean; + + /** @default "glitch" */ + assets: string; + + /** @default [] */ + server: string[]; + }; }; smtp: { @@ -437,6 +448,11 @@ export const defaultConfig: Config = { }, frontend: { url: "http://localhost:3000", + glitch: { + enabled: false, + assets: "glitch", + server: [], + }, }, smtp: { server: "smtp.example.com", diff --git a/packages/glitch-server/main.ts b/packages/glitch-server/main.ts new file mode 100644 index 00000000..cac5a745 --- /dev/null +++ b/packages/glitch-server/main.ts @@ -0,0 +1,37 @@ +import { dualLogger } from "@loggers"; +import { errorResponse } from "@response"; +import { config } from "config-manager"; +import { join } from "node:path"; +import { + LogLevel, + type LogManager, + type MultiLogManager, +} from "~packages/log-manager"; + +export const handleGlitchRequest = async ( + req: Request, + logger: LogManager | MultiLogManager, +): Promise => { + const url = new URL(req.url); + let path = url.pathname; + + // Strip leading /web from path + if (path.startsWith("/web")) path = path.slice(4); + + // Redirect / to /index.html + if (path === "/" || path === "") path = "/index.html"; + // If path doesn't have an extension (e.g. /about), serve index.html + // Also check if Accept header contains text/html + if (!path.includes(".") && req.headers.get("Accept")?.includes("text/html")) + path = "/index.html"; + + const file = Bun.file(join(config.frontend.glitch.assets, path)); + + if (await file.exists()) { + return new Response(file); + } + + dualLogger.log(LogLevel.WARNING, "Glitch-Soc", `Asset not found: ${path}`); + + return errorResponse("Glitch-Soc route not found", 404); +}; diff --git a/packages/glitch-server/package.json b/packages/glitch-server/package.json new file mode 100644 index 00000000..cb46f74f --- /dev/null +++ b/packages/glitch-server/package.json @@ -0,0 +1,6 @@ +{ + "name": "glitch-server", + "version": "0.0.0", + "main": "index.ts", + "dependencies": {} +} diff --git a/server.ts b/server.ts index 90f5476a..5564bec4 100644 --- a/server.ts +++ b/server.ts @@ -1,9 +1,11 @@ +import { dualLogger } from "@loggers"; import { errorResponse, response } from "@response"; import type { Config } from "config-manager"; import { matches } from "ip-matching"; import type { LogManager, MultiLogManager } from "log-manager"; import { LogLevel } from "log-manager"; import { processRoute } from "server-handler"; +import { handleGlitchRequest } from "~packages/glitch-server/main"; import { matchRoute } from "~routes"; export const createServer = ( @@ -115,6 +117,16 @@ export const createServer = ( ); } + if (config.frontend.glitch.enabled) { + // Proxy all /web requests to Glitch-Soc + if ( + new URL(req.url).pathname.startsWith("/web") || + new URL(req.url).pathname.startsWith("/packs") + ) { + return await handleGlitchRequest(req, dualLogger); + } + } + // If route is .well-known, remove dot because the filesystem router can't handle dots for some reason const matchedRoute = matchRoute( req.url.replace(".well-known", "well-known"),