New: フロントエンドにL.jsを導入 / Fix: 初期設定前にserver-infoが利用できない問題 / Feat: manifest.json / Chg: isOwnerをisAdminに戻しました / Fix: UserRepositoryのschemaの記述順序を統一 / Feat: server-infoにサーバー名とサーバー説明を記載 / New: manifest.jsonをフロントエンドで読み込み / New: スクロールバーのスタイルを指定 / New: フォントを指定 / New: line-heightを指定 / New: tab-sizeを指定 / New: <label>のwidthをfit-contentとして指定 / New: CSS変数にアクセントカラーなどを追加 / New: <a>のcolorをaccent-colorとして指定 / Feat: ページのレイアウトを作成 / Feat: 各ページのヘッダーでタイトルを表示 / Feat: スマホUI / Feat: セットアップウィザードをフロントエンドに実装 / Feat: NotFoundページ / New: Button,Input,InputPassword,Toggle,Textareaコンポーネントを作成 / Feat: modal機能 / Chg: server-infoをrefに変更 / Fix: L.jsのsetup/initializationがsetup/initilizationになっていたtypoを修正

This commit is contained in:
2026-03-27 19:03:30 +09:00
parent 0ac921ac3e
commit d670e5bf0b
30 changed files with 1530 additions and 45 deletions
+1
View File
@@ -22,6 +22,7 @@
"@mikro-orm/postgresql": "^6.6.7",
"@mikro-orm/reflection": "^6.6.7",
"@types/web-push": "^3.6.4",
"lynqchat-js": "workspace:*",
"argon2": "^0.44.0",
"cross-env": "^10.1.0",
"fastify": "^5.7.4",
+20 -1
View File
@@ -11,6 +11,7 @@ import Authorization from "@/lib/auth";
import { RequestContext } from "@mikro-orm/core";
import { DatabaseError, ErrorBase } from "@/errors";
import { ConfigEntity } from "@/modules/entities/Config";
import type ApiMap from "lynqchat-js/1.0.0-alpha.0/map";
process.title = "LynqChat";
@@ -83,7 +84,8 @@ try {
fastify.addHook("onRequest", async (req, res) => {
if (
req.url.startsWith("/api") &&
!req.url.startsWith("/api/setup")
!req.url.startsWith("/api/setup") &&
!req.url.startsWith("/api/server-info")
) {
try {
const configCount = await fastify.orm.em.count(ConfigEntity);
@@ -123,6 +125,23 @@ try {
}
});
fastify.get("/manifest.json", async (req, res) => {
const serverInfo = await (await fastify.inject({
method: "POST",
url: "/api/server-info",
})).json() as ApiMap["server-info"]["response"];
if (!serverInfo.success) {
return res.code(500).send(serverInfo);
}
return res.send({
name: serverInfo.name ?? "LynqChat",
start_url: "/",
display: "standalone",
});
});
await fastify.register(Routes, {
prefix: "/api",
});
@@ -51,7 +51,7 @@ export class UserEntity {
type: "boolean",
default: false,
})
isOwner: boolean = false;
isAdmin: boolean = false;
@Property({
type: "boolean",
@@ -9,7 +9,7 @@ export class UserRepository extends EntityRepository<UserEntity> {
userid: z.string().trim().min(3).max(20),
username: z.string().trim().min(3).max(30),
profile: z.string().max(4096).optional(),
email: z.string().min(6).trim().max(254).regex(EmailRegex),
email: z.string().trim().min(6).max(254).regex(EmailRegex),
password: z.string().trim().min(8),
isAdmin: z.boolean(),
});
@@ -14,8 +14,13 @@ export default async function ServerInfo(fastify: FastifyInstance) {
const configCount = await config.count();
const userCount = await user.count();
const serverName = await config.findOne({ name: "name" });
const serverDescription = await config.findOne({ name: "description" });
return res.send({
success: true,
name: serverName?.value ?? null,
description: serverDescription?.value ?? null,
isInitialized: configCount > 0,
isFirstAdminExists: userCount > 0,
userCount,