mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 00:18:19 +01:00
feat(frontend): ✨ Finish glitch frontend implementation
This commit is contained in:
parent
e5e8099883
commit
972ced1f10
|
|
@ -87,6 +87,8 @@ bait_ips = ["127.0.0.1", "::1"]
|
|||
bait_user_agents = ["curl", "wget"]
|
||||
|
||||
[frontend]
|
||||
# Enable custom frontends (warning: not enabling this or Glitch will make Lysand only accessible via the Mastodon API)
|
||||
enabled = true
|
||||
# The URL to reach the frontend at (should be on a local network)
|
||||
url = "http://localhost:3000"
|
||||
|
||||
|
|
|
|||
41
index.ts
41
index.ts
|
|
@ -59,21 +59,38 @@ await dualServerLogger.log(
|
|||
`Database is online, now serving ${postCount} posts`,
|
||||
);
|
||||
|
||||
// Check if frontend is reachable
|
||||
const response = await fetch(new URL("/", config.frontend.url))
|
||||
.then((res) => res.ok)
|
||||
.catch(() => false);
|
||||
if (config.frontend.enabled) {
|
||||
if (!URL.canParse(config.frontend.url)) {
|
||||
await dualServerLogger.log(
|
||||
LogLevel.ERROR,
|
||||
"Server",
|
||||
`Frontend URL is not a valid URL: ${config.frontend.url}`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!response) {
|
||||
// Check if frontend is reachable
|
||||
const response = await fetch(new URL("/", config.frontend.url))
|
||||
.then((res) => res.ok)
|
||||
.catch(() => false);
|
||||
|
||||
if (!response) {
|
||||
await dualServerLogger.log(
|
||||
LogLevel.ERROR,
|
||||
"Server",
|
||||
`Frontend is unreachable at ${config.frontend.url}`,
|
||||
);
|
||||
await dualServerLogger.log(
|
||||
LogLevel.ERROR,
|
||||
"Server",
|
||||
"Please ensure the frontend is online and reachable",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
await dualServerLogger.log(
|
||||
LogLevel.ERROR,
|
||||
LogLevel.WARNING,
|
||||
"Server",
|
||||
`Frontend is unreachable at ${config.frontend.url}`,
|
||||
);
|
||||
await dualServerLogger.log(
|
||||
LogLevel.ERROR,
|
||||
"Server",
|
||||
"Please ensure the frontend is online and reachable",
|
||||
"Frontend is disabled, skipping check",
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,6 +121,9 @@ export interface Config {
|
|||
};
|
||||
|
||||
frontend: {
|
||||
/** @default true */
|
||||
enabled: boolean;
|
||||
|
||||
/** @default "http://localhost:3000" */
|
||||
url: string;
|
||||
|
||||
|
|
@ -442,6 +445,7 @@ export const defaultConfig: Config = {
|
|||
},
|
||||
},
|
||||
frontend: {
|
||||
enabled: true,
|
||||
url: "http://localhost:3000",
|
||||
glitch: {
|
||||
enabled: false,
|
||||
|
|
|
|||
210
packages/glitch-server/glitch-languages.ts
Normal file
210
packages/glitch-server/glitch-languages.ts
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
export const languages = [
|
||||
["aa", "Afar", "Afaraf"],
|
||||
["ab", "Abkhaz", "аҧсуа бызшәа"],
|
||||
["ae", "Avestan", "avesta"],
|
||||
["af", "Afrikaans", "Afrikaans"],
|
||||
["ak", "Akan", "Akan"],
|
||||
["am", "Amharic", "አማርኛ"],
|
||||
["an", "Aragonese", "aragonés"],
|
||||
["ar", "Arabic", "اللغة العربية"],
|
||||
["as", "Assamese", "অসমীয়া"],
|
||||
["av", "Avaric", "авар мацӀ"],
|
||||
["ay", "Aymara", "aymar aru"],
|
||||
["az", "Azerbaijani", "azərbaycan dili"],
|
||||
["ba", "Bashkir", "башҡорт теле"],
|
||||
["be", "Belarusian", "беларуская мова"],
|
||||
["bg", "Bulgarian", "български език"],
|
||||
["bh", "Bihari", "भोजपुरी"],
|
||||
["bi", "Bislama", "Bislama"],
|
||||
["bm", "Bambara", "bamanankan"],
|
||||
["bn", "Bengali", "বাংলা"],
|
||||
["bo", "Tibetan", "བོད་ཡིག"],
|
||||
["br", "Breton", "brezhoneg"],
|
||||
["bs", "Bosnian", "bosanski jezik"],
|
||||
["ca", "Catalan", "Català"],
|
||||
["ce", "Chechen", "нохчийн мотт"],
|
||||
["ch", "Chamorro", "Chamoru"],
|
||||
["co", "Corsican", "corsu"],
|
||||
["cr", "Cree", "ᓀᐦᐃᔭᐍᐏᐣ"],
|
||||
["cs", "Czech", "čeština"],
|
||||
["cu", "Old Church Slavonic", "ѩзыкъ словѣньскъ"],
|
||||
["cv", "Chuvash", "чӑваш чӗлхи"],
|
||||
["cy", "Welsh", "Cymraeg"],
|
||||
["da", "Danish", "dansk"],
|
||||
["de", "German", "Deutsch"],
|
||||
["dv", "Divehi", "Dhivehi"],
|
||||
["dz", "Dzongkha", "རྫོང་ཁ"],
|
||||
["ee", "Ewe", "Eʋegbe"],
|
||||
["el", "Greek", "Ελληνικά"],
|
||||
["en", "English", "English"],
|
||||
["eo", "Esperanto", "Esperanto"],
|
||||
["es", "Spanish", "Español"],
|
||||
["et", "Estonian", "eesti"],
|
||||
["eu", "Basque", "euskara"],
|
||||
["fa", "Persian", "فارسی"],
|
||||
["ff", "Fula", "Fulfulde"],
|
||||
["fi", "Finnish", "suomi"],
|
||||
["fj", "Fijian", "Vakaviti"],
|
||||
["fo", "Faroese", "føroyskt"],
|
||||
["fr", "French", "Français"],
|
||||
["fy", "Western Frisian", "Frysk"],
|
||||
["ga", "Irish", "Gaeilge"],
|
||||
["gd", "Scottish Gaelic", "Gàidhlig"],
|
||||
["gl", "Galician", "galego"],
|
||||
["gu", "Gujarati", "ગુજરાતી"],
|
||||
["gv", "Manx", "Gaelg"],
|
||||
["ha", "Hausa", "هَوُسَ"],
|
||||
["he", "Hebrew", "עברית"],
|
||||
["hi", "Hindi", "हिन्दी"],
|
||||
["ho", "Hiri Motu", "Hiri Motu"],
|
||||
["hr", "Croatian", "Hrvatski"],
|
||||
["ht", "Haitian", "Kreyòl ayisyen"],
|
||||
["hu", "Hungarian", "magyar"],
|
||||
["hy", "Armenian", "Հայերեն"],
|
||||
["hz", "Herero", "Otjiherero"],
|
||||
["ia", "Interlingua", "Interlingua"],
|
||||
["id", "Indonesian", "Bahasa Indonesia"],
|
||||
["ie", "Interlingue", "Interlingue"],
|
||||
["ig", "Igbo", "Asụsụ Igbo"],
|
||||
["ii", "Nuosu", "ꆈꌠ꒿ Nuosuhxop"],
|
||||
["ik", "Inupiaq", "Iñupiaq"],
|
||||
["io", "Ido", "Ido"],
|
||||
["is", "Icelandic", "Íslenska"],
|
||||
["it", "Italian", "Italiano"],
|
||||
["iu", "Inuktitut", "ᐃᓄᒃᑎᑐᑦ"],
|
||||
["ja", "Japanese", "日本語"],
|
||||
["jv", "Javanese", "basa Jawa"],
|
||||
["ka", "Georgian", "ქართული"],
|
||||
["kg", "Kongo", "Kikongo"],
|
||||
["ki", "Kikuyu", "Gĩkũyũ"],
|
||||
["kj", "Kwanyama", "Kuanyama"],
|
||||
["kk", "Kazakh", "қазақ тілі"],
|
||||
["kl", "Kalaallisut", "kalaallisut"],
|
||||
["km", "Khmer", "ខេមរភាសា"],
|
||||
["kn", "Kannada", "ಕನ್ನಡ"],
|
||||
["ko", "Korean", "한국어"],
|
||||
["kr", "Kanuri", "Kanuri"],
|
||||
["ks", "Kashmiri", "कश्मीरी"],
|
||||
["ku", "Kurmanji (Kurdish)", "Kurmancî"],
|
||||
["kv", "Komi", "коми кыв"],
|
||||
["kw", "Cornish", "Kernewek"],
|
||||
["ky", "Kyrgyz", "Кыргызча"],
|
||||
["la", "Latin", "latine"],
|
||||
["lb", "Luxembourgish", "Lëtzebuergesch"],
|
||||
["lg", "Ganda", "Luganda"],
|
||||
["li", "Limburgish", "Limburgs"],
|
||||
["ln", "Lingala", "Lingála"],
|
||||
["lo", "Lao", "ລາວ"],
|
||||
["lt", "Lithuanian", "lietuvių kalba"],
|
||||
["lu", "Luba-Katanga", "Tshiluba"],
|
||||
["lv", "Latvian", "latviešu valoda"],
|
||||
["mg", "Malagasy", "fiteny malagasy"],
|
||||
["mh", "Marshallese", "Kajin M̧ajeļ"],
|
||||
["mi", "Māori", "te reo Māori"],
|
||||
["mk", "Macedonian", "македонски јазик"],
|
||||
["ml", "Malayalam", "മലയാളം"],
|
||||
["mn", "Mongolian", "Монгол хэл"],
|
||||
["mr", "Marathi", "मराठी"],
|
||||
["ms", "Malay", "Bahasa Melayu"],
|
||||
["ms-Arab", "Jawi Malay", "بهاس ملايو"],
|
||||
["mt", "Maltese", "Malti"],
|
||||
["my", "Burmese", "ဗမာစာ"],
|
||||
["na", "Nauru", "Ekakairũ Naoero"],
|
||||
["nb", "Norwegian Bokmål", "Norsk bokmål"],
|
||||
["nd", "Northern Ndebele", "isiNdebele"],
|
||||
["ne", "Nepali", "नेपाली"],
|
||||
["ng", "Ndonga", "Owambo"],
|
||||
["nl", "Dutch", "Nederlands"],
|
||||
["nn", "Norwegian Nynorsk", "Norsk Nynorsk"],
|
||||
["no", "Norwegian", "Norsk"],
|
||||
["nr", "Southern Ndebele", "isiNdebele"],
|
||||
["nv", "Navajo", "Diné bizaad"],
|
||||
["ny", "Chichewa", "chiCheŵa"],
|
||||
["oc", "Occitan", "occitan"],
|
||||
["oj", "Ojibwe", "ᐊᓂᔑᓈᐯᒧᐎᓐ"],
|
||||
["om", "Oromo", "Afaan Oromoo"],
|
||||
["or", "Oriya", "ଓଡ଼ିଆ"],
|
||||
["os", "Ossetian", "ирон æвзаг"],
|
||||
["pa", "Punjabi", "ਪੰਜਾਬੀ"],
|
||||
["pi", "Pāli", "पाऴि"],
|
||||
["pl", "Polish", "Polski"],
|
||||
["ps", "Pashto", "پښتو"],
|
||||
["pt", "Portuguese", "Português"],
|
||||
["qu", "Quechua", "Runa Simi"],
|
||||
["rm", "Romansh", "rumantsch grischun"],
|
||||
["rn", "Kirundi", "Ikirundi"],
|
||||
["ro", "Romanian", "Română"],
|
||||
["ru", "Russian", "Русский"],
|
||||
["rw", "Kinyarwanda", "Ikinyarwanda"],
|
||||
["sa", "Sanskrit", "संस्कृतम्"],
|
||||
["sc", "Sardinian", "sardu"],
|
||||
["sd", "Sindhi", "सिन्धी"],
|
||||
["se", "Northern Sami", "Davvisámegiella"],
|
||||
["sg", "Sango", "yângâ tî sängö"],
|
||||
["si", "Sinhala", "සිංහල"],
|
||||
["sk", "Slovak", "slovenčina"],
|
||||
["sl", "Slovenian", "slovenščina"],
|
||||
["sn", "Shona", "chiShona"],
|
||||
["so", "Somali", "Soomaaliga"],
|
||||
["sq", "Albanian", "Shqip"],
|
||||
["sr", "Serbian", "српски језик"],
|
||||
["ss", "Swati", "SiSwati"],
|
||||
["st", "Southern Sotho", "Sesotho"],
|
||||
["su", "Sundanese", "Basa Sunda"],
|
||||
["sv", "Swedish", "Svenska"],
|
||||
["sw", "Swahili", "Kiswahili"],
|
||||
["ta", "Tamil", "தமிழ்"],
|
||||
["te", "Telugu", "తెలుగు"],
|
||||
["tg", "Tajik", "тоҷикӣ"],
|
||||
["th", "Thai", "ไทย"],
|
||||
["ti", "Tigrinya", "ትግርኛ"],
|
||||
["tk", "Turkmen", "Türkmen"],
|
||||
["tl", "Tagalog", "Wikang Tagalog"],
|
||||
["tn", "Tswana", "Setswana"],
|
||||
["to", "Tonga", "faka Tonga"],
|
||||
["tr", "Turkish", "Türkçe"],
|
||||
["ts", "Tsonga", "Xitsonga"],
|
||||
["tt", "Tatar", "татар теле"],
|
||||
["tw", "Twi", "Twi"],
|
||||
["ty", "Tahitian", "Reo Tahiti"],
|
||||
["ug", "Uyghur", "ئۇيغۇرچە"],
|
||||
["uk", "Ukrainian", "Українська"],
|
||||
["ur", "Urdu", "اردو"],
|
||||
["uz", "Uzbek", "Ўзбек"],
|
||||
["ve", "Venda", "Tshivenḓa"],
|
||||
["vi", "Vietnamese", "Tiếng Việt"],
|
||||
["vo", "Volapük", "Volapük"],
|
||||
["wa", "Walloon", "walon"],
|
||||
["wo", "Wolof", "Wollof"],
|
||||
["xh", "Xhosa", "isiXhosa"],
|
||||
["yi", "Yiddish", "ייִדיש"],
|
||||
["yo", "Yoruba", "Yorùbá"],
|
||||
["za", "Zhuang", "Saɯ cueŋƅ"],
|
||||
["zh", "Chinese", "中文"],
|
||||
["zu", "Zulu", "isiZulu"],
|
||||
["zh-CN", "Chinese (China)", "简体中文"],
|
||||
["zh-HK", "Chinese (Hong Kong)", "繁體中文(香港)"],
|
||||
["zh-TW", "Chinese (Taiwan)", "繁體中文(臺灣)"],
|
||||
["zh-YUE", "Cantonese", "廣東話"],
|
||||
["ast", "Asturian", "Asturianu"],
|
||||
["chr", "Cherokee", "ᏣᎳᎩ ᎦᏬᏂᎯᏍᏗ"],
|
||||
["ckb", "Sorani (Kurdish)", "سۆرانی"],
|
||||
["cnr", "Montenegrin", "crnogorski"],
|
||||
["csb", "Kashubian", "Kaszëbsczi"],
|
||||
["jbo", "Lojban", "la .lojban."],
|
||||
["kab", "Kabyle", "Taqbaylit"],
|
||||
["ldn", "Láadan", "Láadan"],
|
||||
["lfn", "Lingua Franca Nova", "lingua franca nova"],
|
||||
["moh", "Mohawk", "Kanienʼkéha"],
|
||||
["nds", "Low German", "Plattdüütsch"],
|
||||
["pdc", "Pennsylvania Dutch", "Pennsilfaani-Deitsch"],
|
||||
["sco", "Scots", "Scots"],
|
||||
["sma", "Southern Sami", "Åarjelsaemien Gïele"],
|
||||
["smj", "Lule Sami", "Julevsámegiella"],
|
||||
["szl", "Silesian", "ślůnsko godka"],
|
||||
["tok", "Toki Pona", "toki pona"],
|
||||
["vai", "Vai", "ꕙꔤ"],
|
||||
["xal", "Kalmyk", "Хальмг келн"],
|
||||
["zba", "Balaibalan", "باليبلن"],
|
||||
["zgh", "Standard Moroccan Tamazight", "ⵜⴰⵎⴰⵣⵉⵖⵜ"],
|
||||
];
|
||||
|
|
@ -1,17 +1,12 @@
|
|||
import { join } from "node:path";
|
||||
import { dualLogger } from "@loggers";
|
||||
import { errorResponse } from "@response";
|
||||
import { config } from "config-manager";
|
||||
import {
|
||||
LogLevel,
|
||||
type LogManager,
|
||||
type MultiLogManager,
|
||||
} from "~packages/log-manager";
|
||||
import type { LogManager, MultiLogManager } from "~packages/log-manager";
|
||||
import { languages } from "./glitch-languages";
|
||||
|
||||
export const handleGlitchRequest = async (
|
||||
req: Request,
|
||||
logger: LogManager | MultiLogManager,
|
||||
): Promise<Response> => {
|
||||
): Promise<Response | null> => {
|
||||
const url = new URL(req.url);
|
||||
let path = url.pathname;
|
||||
|
||||
|
|
@ -28,10 +23,102 @@ export const handleGlitchRequest = async (
|
|||
const file = Bun.file(join(config.frontend.glitch.assets, path));
|
||||
|
||||
if (await file.exists()) {
|
||||
return new Response(file);
|
||||
let fileContents = await file.text();
|
||||
|
||||
for (const server of config.frontend.glitch.server) {
|
||||
fileContents = fileContents.replace(
|
||||
`${new URL(server).origin}/`,
|
||||
"/",
|
||||
);
|
||||
}
|
||||
|
||||
fileContents = fileContents.replaceAll(
|
||||
"Glitch-soc is free open source software forked from Mastodon.",
|
||||
"Lysand is free and open-source software using the Glitch-Soc frontend.",
|
||||
);
|
||||
fileContents = fileContents.replaceAll("Mastodon", "Lysand");
|
||||
fileContents = fileContents.replaceAll(
|
||||
"Lysand is free, open-source software, and a trademark of Mastodon gGmbH.",
|
||||
"This is not a Mastodon instance.",
|
||||
);
|
||||
fileContents = fileContents.replaceAll(
|
||||
"joinmastodon.org",
|
||||
"lysand.org",
|
||||
);
|
||||
|
||||
// Check if file is index
|
||||
if (path === "/index.html") {
|
||||
// Find script id="initial-state" and replace its contents with custom json
|
||||
const rewriter = new HTMLRewriter()
|
||||
.on("script#initial-state", {
|
||||
element(element) {
|
||||
element.setInnerContent(
|
||||
JSON.stringify({
|
||||
meta: {
|
||||
access_token: null,
|
||||
activity_api_enabled: true,
|
||||
admin: null,
|
||||
domain: new URL(config.http.base_url).host,
|
||||
limited_federation_mode: false,
|
||||
locale: "en",
|
||||
mascot: "https://media.tech.lgbt/site_uploads/files/000/000/004/original/1a16a73feb5c2463.png",
|
||||
profile_directory: true,
|
||||
registrations_open: true,
|
||||
repository: "lysand-org/lysand",
|
||||
search_enabled: true,
|
||||
single_user_mode: false,
|
||||
source_url:
|
||||
"https://github.com/lysand-org/lysand",
|
||||
sso_redirect: null,
|
||||
status_page_url: null,
|
||||
streaming_api_base_url: null,
|
||||
timeline_preview: true,
|
||||
title: config.instance.name,
|
||||
trends_as_landing_page: false,
|
||||
trends_enabled: true,
|
||||
version: "4.3.0-alpha.3+glitch",
|
||||
auto_play_gif: null,
|
||||
display_media: null,
|
||||
reduce_motion: null,
|
||||
use_blurhash: null,
|
||||
},
|
||||
compose: { text: "" },
|
||||
accounts: {},
|
||||
media_attachments: {
|
||||
accept_content_types:
|
||||
config.validation.allowed_mime_types,
|
||||
},
|
||||
settings: {},
|
||||
max_feed_hashtags: 4,
|
||||
poll_limits: {
|
||||
max_options:
|
||||
config.validation.max_poll_options,
|
||||
max_option_chars:
|
||||
config.validation.max_poll_option_size,
|
||||
min_expiration:
|
||||
config.validation.min_poll_duration,
|
||||
max_expiration:
|
||||
config.validation.max_poll_duration,
|
||||
},
|
||||
languages: languages,
|
||||
push_subscription: null,
|
||||
role: null,
|
||||
}),
|
||||
);
|
||||
},
|
||||
})
|
||||
.transform(new Response(fileContents));
|
||||
|
||||
fileContents = await rewriter.text();
|
||||
}
|
||||
return new Response(fileContents, {
|
||||
headers: {
|
||||
"Content-Type": `${file.type}; charset=utf-8`,
|
||||
"Content-Length": String(file.size),
|
||||
Date: new Date().toUTCString(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
dualLogger.log(LogLevel.WARNING, "Glitch-Soc", `Asset not found: ${path}`);
|
||||
|
||||
return errorResponse("Glitch-Soc route not found", 404);
|
||||
return null;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -126,8 +126,10 @@ export const createServer = (
|
|||
}
|
||||
|
||||
if (config.frontend.glitch.enabled) {
|
||||
// Proxy all /web requests to Glitch-Soc
|
||||
return await handleGlitchRequest(req, dualLogger);
|
||||
return (
|
||||
(await handleGlitchRequest(req, dualLogger)) ??
|
||||
errorResponse("Route not found", 404)
|
||||
);
|
||||
}
|
||||
|
||||
const base_url_with_http = config.http.base_url.replace(
|
||||
|
|
|
|||
Loading…
Reference in a new issue