mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 08:28:19 +01:00
Reorganize FE
This commit is contained in:
parent
e27a80c40a
commit
354493133c
29
packages/frontend/composables/useConfig.ts
Normal file
29
packages/frontend/composables/useConfig.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
export const useConfig = async () => {
|
||||
let host = useRequestHeader("X-Forwarded-Host");
|
||||
|
||||
if (!host && process.server) {
|
||||
host = process.env.BUILD_HOST;
|
||||
}
|
||||
|
||||
if (!host?.includes("http")) {
|
||||
// On server, this will be some kind of localhost
|
||||
host = `http://${host}`;
|
||||
}
|
||||
|
||||
if (process.client) {
|
||||
host = useRequestURL().origin.toString();
|
||||
}
|
||||
|
||||
console.log(host);
|
||||
|
||||
if (!host) {
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: "No X-Forwarded-Host header found",
|
||||
});
|
||||
}
|
||||
|
||||
return await fetch(new URL("/api/_fe/config", host)).then((res) =>
|
||||
res.json(),
|
||||
);
|
||||
};
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<div class="flex min-h-screen flex-col justify-center px-6 py-12 lg:px-8 relative">
|
||||
<div class="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80" aria-hidden="true">
|
||||
<div class="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80"
|
||||
aria-hidden="true">
|
||||
<div class="relative left-[calc(50%-11rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 rotate-[30deg] bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%-30rem)] sm:w-[72.1875rem]"
|
||||
style="clip-path: polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)" />
|
||||
</div>
|
||||
|
|
@ -14,7 +15,7 @@ import { getHighlighterCore } from "shiki/core";
|
|||
import getWasm from "shiki/wasm";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
const config = (await useFetch("/api/config")).data.value;
|
||||
const config = await useConfig();
|
||||
|
||||
if (!config) {
|
||||
throw new Error("Config not found");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<div class="flex min-h-screen flex-col justify-center px-6 py-12 lg:px-8 relative">
|
||||
<div class="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80" aria-hidden="true">
|
||||
<div class="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80"
|
||||
aria-hidden="true">
|
||||
<div class="relative left-[calc(50%-11rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 rotate-[30deg] bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%-30rem)] sm:w-[72.1875rem]"
|
||||
style="clip-path: polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)" />
|
||||
</div>
|
||||
|
|
@ -14,7 +15,7 @@ import { getHighlighterCore } from "shiki/core";
|
|||
import getWasm from "shiki/wasm";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
const config = (await useFetch("/api/config")).data.value;
|
||||
const config = await useConfig();
|
||||
|
||||
if (!config) {
|
||||
throw new Error("Config not found");
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@
|
|||
</div>
|
||||
<div class="text-center">
|
||||
<h1 class="text-4xl font-bold tracking-tight text-gray-900 sm:text-6xl">Welcome to Lysand</h1>
|
||||
<p class="mt-6 text-lg leading-8 text-gray-600">You can login to this server by pointing any Mastodon
|
||||
<p class="mt-6 text-lg leading-8 text-gray-600">You can login to this server by pointing any
|
||||
Mastodon
|
||||
client at <strong class="font-bold">{{ config?.http.base_url }}</strong></p>
|
||||
<div class="mt-10 flex items-center justify-center gap-6 md:flex-row flex-col">
|
||||
<a href="https://github.com/lysand-org/lysand" target="_blank"
|
||||
|
|
@ -29,7 +30,8 @@
|
|||
<p class="mt-6 text-lg leading-8 text-gray-600">Here are some recommended clients:</p>
|
||||
<ul class="w-full flex flex-col gap-3 mt-4">
|
||||
<li v-for="client of recommendedClients" :key="client.name" class="w-full">
|
||||
<a :href="client.link" class="rounded-sm ring-2 ring-black/10 px-4 py-2 w-full flex flex-row gap-3 items-center">
|
||||
<a :href="client.link"
|
||||
class="rounded-sm ring-2 ring-black/10 px-4 py-2 w-full flex flex-row gap-3 items-center">
|
||||
<img :src="client.icon" :alt="client.name" class="h-10 w-10" />
|
||||
<div class="flex flex-col justify-between items-start">
|
||||
<h2 class="font-bold">{{ client.name }}</h2>
|
||||
|
|
@ -39,11 +41,13 @@
|
|||
</li>
|
||||
</ul>
|
||||
<p class="mt-6 text-lg leading-8 text-gray-600">
|
||||
Many other clients exist, but <strong class="font-bold">they have not been tested for compatibility</strong>. Bug reports are nevertheless welcome.
|
||||
Many other clients exist, but <strong class="font-bold">they have not been tested for
|
||||
compatibility</strong>. Bug reports are nevertheless welcome.
|
||||
</p>
|
||||
|
||||
<p class="mt-6 text-lg leading-8 text-gray-600">
|
||||
Found a problem? Report it on <a href="https://github.com/lysand-org/lysand/issues/new/choose" class="underline text-purple-700">the issue tracker</a>.
|
||||
Found a problem? Report it on <a href="https://github.com/lysand-org/lysand/issues/new/choose"
|
||||
class="underline text-purple-700">the issue tracker</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -60,8 +64,7 @@
|
|||
import { recommendedClients } from "../constants";
|
||||
// @ts-ignore
|
||||
const version = __VERSION__;
|
||||
|
||||
const config = (await useFetch("/api/config")).data.value;
|
||||
const config = await useConfig();
|
||||
|
||||
useServerSeoMeta({
|
||||
title: "Welcome to Lysand!",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<div class="flex min-h-screen flex-col justify-center px-6 py-12 lg:px-8 relative">
|
||||
<div class="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80" aria-hidden="true">
|
||||
<div class="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80"
|
||||
aria-hidden="true">
|
||||
<div class="relative left-[calc(50%-11rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 rotate-[30deg] bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%-30rem)] sm:w-[72.1875rem]"
|
||||
style="clip-path: polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)" />
|
||||
</div>
|
||||
|
|
@ -66,7 +67,8 @@
|
|||
</div>
|
||||
|
||||
<div class="">
|
||||
<input type="checkbox" :value="tosAccepted" @input="tosAccepted = Boolean(($event.target as any).value)"
|
||||
<input type="checkbox" :value="tosAccepted"
|
||||
@input="tosAccepted = Boolean(($event.target as any).value)"
|
||||
class="rounded mr-1 align-middle mb-0.5" /> <span class="text-sm">I agree to the
|
||||
terms and
|
||||
conditions
|
||||
|
|
@ -89,9 +91,11 @@
|
|||
</form>
|
||||
</div>
|
||||
<div v-else>
|
||||
<h1 class="text-2xl font-bold tracking-tight text-gray-900 sm:text-4xl text-center">Registrations are disabled
|
||||
<h1 class="text-2xl font-bold tracking-tight text-gray-900 sm:text-4xl text-center">Registrations are
|
||||
disabled
|
||||
</h1>
|
||||
<p class="mt-6 text-lg leading-8 text-gray-600 text-center">Ask this instance's admin to enable them in config!
|
||||
<p class="mt-6 text-lg leading-8 text-gray-600 text-center">Ask this instance's admin to enable them in
|
||||
config!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -101,7 +105,7 @@
|
|||
import type { APIInstance } from "../../../../types/entities/instance";
|
||||
import LoginInput from "../../components/LoginInput.vue";
|
||||
|
||||
const config = (await useFetch("/api/config")).data.value;
|
||||
const config = await useConfig();
|
||||
|
||||
if (!config) {
|
||||
throw new Error("Config not found");
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
import { loadConfig } from "c12";
|
||||
import { type Config, defaultConfig } from "config-manager/config.type";
|
||||
|
||||
const promise = loadConfig<Config>({
|
||||
configFile: "./config/config.toml",
|
||||
defaultConfig: defaultConfig,
|
||||
});
|
||||
|
||||
export default defineEventHandler(async () => {
|
||||
const { config } = await promise;
|
||||
return {
|
||||
http: {
|
||||
bind: config?.http.bind,
|
||||
bind_port: config?.http.bind_port,
|
||||
base_url: config?.http.base_url,
|
||||
url: config?.http.bind.includes("http")
|
||||
? `${config?.http.bind}:${config?.http.bind_port}`
|
||||
: `http://${config?.http.bind}:${config?.http.bind_port}`,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"extends": "../.nuxt/tsconfig.server.json"
|
||||
}
|
||||
|
|
@ -82,6 +82,7 @@ export const rawRoutes = {
|
|||
"/api/v1/statuses/[id]/unpin": "./server/api/api/v1/statuses/[id]/unpin",
|
||||
"/api/v1/statuses/[id]/unreblog":
|
||||
"./server/api/api/v1/statuses/[id]/unreblog",
|
||||
"/api/_fe/config": "./server/api/api/_fe/config/index",
|
||||
"/media/[id]": "./server/api/media/[id]/index",
|
||||
"/oauth/callback/[issuer]": "./server/api/oauth/callback/[issuer]/index",
|
||||
"/objects/note/[uuid]": "./server/api/objects/note/[uuid]/index",
|
||||
|
|
|
|||
|
|
@ -193,7 +193,12 @@ export const createServer = (
|
|||
.replace(config.http.base_url, "http://localhost:5173")
|
||||
.replace(base_url_with_http, "http://localhost:5173");
|
||||
|
||||
const proxy = await fetch(replacedUrl).catch(async (e) => {
|
||||
const proxy = await fetch(replacedUrl, {
|
||||
headers: {
|
||||
// Include for SSR
|
||||
"X-Forwarded-Host": `${config.http.bind}:${config.http.bind_port}`,
|
||||
},
|
||||
}).catch(async (e) => {
|
||||
await logger.logError(
|
||||
LogLevel.ERROR,
|
||||
"Server.Proxy",
|
||||
|
|
|
|||
29
server/api/api/_fe/config/index.ts
Normal file
29
server/api/api/_fe/config/index.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { jsonResponse } from "@response";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
ratelimits: {
|
||||
max: 60,
|
||||
duration: 120,
|
||||
},
|
||||
route: "/api/_fe/config",
|
||||
auth: {
|
||||
required: false,
|
||||
},
|
||||
});
|
||||
|
||||
export default apiRoute(async (req, matchedRoute, extraData) => {
|
||||
const config = await extraData.configManager.getConfig();
|
||||
|
||||
return jsonResponse({
|
||||
http: {
|
||||
bind: config.http.bind,
|
||||
bind_port: config.http.bind_port,
|
||||
base_url: config.http.base_url,
|
||||
url: config.http.bind.includes("http")
|
||||
? `${config.http.bind}:${config.http.bind_port}`
|
||||
: `http://${config.http.bind}:${config.http.bind_port}`,
|
||||
},
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue