New: LICENSEファイル / Del: package.json.license / Feat: setup/initializationでVAPIDを生成 / Fix: 全てのエンドポイントでsuccessをレスポンス / Chg: input_noneエラーを廃止。入力がない場合は{}として解決する / Feat: フロントエンドでserver-infoを読み込む
This commit is contained in:
@@ -14,7 +14,6 @@
|
||||
"email": "info@last2014.com",
|
||||
"url": "https://about.last2014.com"
|
||||
},
|
||||
"license": "AGPL-3.0-only",
|
||||
"packageManager": "pnpm@10.29.1",
|
||||
"dependencies": {
|
||||
"@fastify/static": "^9.0.0",
|
||||
@@ -22,6 +21,7 @@
|
||||
"@mikro-orm/migrations": "^6.6.7",
|
||||
"@mikro-orm/postgresql": "^6.6.7",
|
||||
"@mikro-orm/reflection": "^6.6.7",
|
||||
"@types/web-push": "^3.6.4",
|
||||
"argon2": "^0.44.0",
|
||||
"cross-env": "^10.1.0",
|
||||
"fastify": "^5.7.4",
|
||||
@@ -33,6 +33,7 @@
|
||||
"typescript": "^5.9.3",
|
||||
"util": "^0.12.5",
|
||||
"uuid": "^13.0.0",
|
||||
"web-push": "^3.6.7",
|
||||
"yaml": "^2.8.2",
|
||||
"zod": "^4.3.6"
|
||||
},
|
||||
|
||||
@@ -32,14 +32,6 @@ try {
|
||||
fastify.setErrorHandler((err, req, res) => {
|
||||
res.header("Content-Type", "application/json");
|
||||
|
||||
if (err instanceof SyntaxError && /JSON/.test(err.message)) {
|
||||
return res.status(400).send(ErrorBase({
|
||||
bad: "client",
|
||||
code: "input_none",
|
||||
message: "入力がありません。",
|
||||
}));
|
||||
}
|
||||
|
||||
const customLogger = new Logger("Unknown(Error handler)");
|
||||
customLogger.error("Unknown error:", err);
|
||||
|
||||
@@ -127,12 +119,7 @@ try {
|
||||
|
||||
done(null, json);
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
(err as any).statusCode = 400;
|
||||
done(err, undefined);
|
||||
} else {
|
||||
done(new Error("Invalid JSON"), undefined);
|
||||
}
|
||||
done(null, {});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ export default async function ServerInfo(fastify: FastifyInstance) {
|
||||
const userCount = await user.count();
|
||||
|
||||
return res.send({
|
||||
success: true,
|
||||
isInitialized: configCount > 0,
|
||||
isFirstAdminExists: userCount > 0,
|
||||
userCount,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { DatabaseError, ErrorBase, InputError } from "@/errors";
|
||||
import Logger from "@/lib/logger";
|
||||
import { ConfigEntity } from "@/modules/entities/Config";
|
||||
import type { FastifyInstance } from "fastify";
|
||||
import { generateVAPIDKeys } from "web-push";
|
||||
import z from "zod/v3";
|
||||
|
||||
export default function SetupInitialization(fastify: FastifyInstance) {
|
||||
@@ -46,6 +47,10 @@ export default function SetupInitialization(fastify: FastifyInstance) {
|
||||
|
||||
try {
|
||||
const entries = Object.entries(result.data).filter(([key]) => key !== "force");
|
||||
|
||||
const vapid = generateVAPIDKeys();
|
||||
entries.push(["VAPID_PUBLIC", vapid.publicKey]);
|
||||
entries.push(["VAPID_PRIVATE", vapid.privateKey]);
|
||||
|
||||
for (const [key, value] of entries) {
|
||||
const entity = await fastify.orm.em.getRepository(ConfigEntity).set(
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"name": "frontend",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"license": "AGPL-3.0-only",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc -b && vite build",
|
||||
|
||||
@@ -24,10 +24,12 @@
|
||||
import { RouterView } from "vue-router";
|
||||
import routerStatus from "@/lib/router";
|
||||
import Progress from "@/components/Progress.vue";
|
||||
/*import LynqChat from "lynqchat-js";
|
||||
import type ApiMap from "lynqchat-js/1.0.0-alpha.0/map"
|
||||
import { ref } from "vue";
|
||||
import serverInfo from "@/lib/account";
|
||||
|
||||
const client = new LynqChat<ApiMap>({
|
||||
origin: window.origin,
|
||||
});*/
|
||||
const isBootFailed = ref<boolean>(false);
|
||||
|
||||
if (!serverInfo.success) {
|
||||
isBootFailed.value = true;
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,5 @@
|
||||
import client from "@/lib/client";
|
||||
|
||||
const serverInfo = await client.request("server-info");
|
||||
|
||||
export default serverInfo;
|
||||
@@ -0,0 +1,8 @@
|
||||
import LynqChat from "lynqchat-js";
|
||||
import type ApiMap from "lynqchat-js/1.0.0-alpha.0/map";
|
||||
|
||||
const client = new LynqChat<ApiMap>({
|
||||
origin: window.origin,
|
||||
});
|
||||
|
||||
export default client;
|
||||
@@ -16,10 +16,9 @@ const router = createRouter({
|
||||
},
|
||||
],
|
||||
});
|
||||
// @ts-ignore 余分な引数の警告
|
||||
router.beforeEach((to, from, next) => {
|
||||
router.beforeEach(() => {
|
||||
routerStatus.isLoad = true;
|
||||
next();
|
||||
return;
|
||||
});
|
||||
router.afterEach(() => {
|
||||
routerStatus.isLoad = false;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"license": "AGPL-3.0-only",
|
||||
"author": {
|
||||
"name": "Last2014",
|
||||
"email": "info@last2014.com",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { InputError, InputNoneError } from "../../modules/error/input";
|
||||
import InputError from "../../modules/error/input";
|
||||
import ErrorBase from "../../modules/error";
|
||||
import DatabaseError from "../../modules/error/database";
|
||||
import Success from "../../modules/response/success";
|
||||
@@ -10,6 +10,6 @@ export default interface Me {
|
||||
"me": {
|
||||
body: never;
|
||||
response: (Success & Omit<UserSchema, "password" | "email">)
|
||||
| DatabaseError | InputError | InputNoneError | YetInitializationError | UnknownError;
|
||||
| DatabaseError | InputError | YetInitializationError | UnknownError;
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { InputError, InputNoneError } from "../../modules/error/input";
|
||||
import InputError from "../../modules/error/input";
|
||||
import ErrorBase from "../../modules/error";
|
||||
import DatabaseError from "../../modules/error/database";
|
||||
import Success from "../../modules/response/success";
|
||||
@@ -15,6 +15,6 @@ export default interface PrimarySignin {
|
||||
bad: "client",
|
||||
code: "auth_input_wrong",
|
||||
message: "ユーザー名かパスワードが違います。",
|
||||
}> | InputError | InputNoneError | YetInitializationError | UnknownError;
|
||||
}> | InputError | YetInitializationError | UnknownError;
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { InputError, InputNoneError } from "../../modules/error/input";
|
||||
import InputError from "../../modules/error/input";
|
||||
import ErrorBase from "../../modules/error";
|
||||
import DatabaseError from "../../modules/error/database";
|
||||
import Success from "../../modules/response/success";
|
||||
@@ -9,6 +9,6 @@ import UnknownError from "../../modules/error/unknown";
|
||||
export default interface PrimarySignup {
|
||||
"primary/signup": {
|
||||
body: Pick<UserSchema, "userid" | "email" | "password">;
|
||||
response: Success | DatabaseError | InputError | InputNoneError | YetInitializationError | UnknownError;
|
||||
response: Success | DatabaseError | InputError | YetInitializationError | UnknownError;
|
||||
};
|
||||
}
|
||||
+11
-11
@@ -1,16 +1,16 @@
|
||||
import { InputError, InputNoneError } from "../../modules/error/input";
|
||||
import ErrorBase from "../../modules/error";
|
||||
import DatabaseError from "../../modules/error/database";
|
||||
import UnknownError from "../../modules/error/unknown";
|
||||
import { InputError, InputNoneError } from "../modules/error/input";
|
||||
import ErrorBase from "../modules/error";
|
||||
import DatabaseError from "../modules/error/database";
|
||||
import UnknownError from "../modules/error/unknown";
|
||||
import Success from "../modules/response/success";
|
||||
|
||||
export default interface ServerInfo {
|
||||
"server-info": {
|
||||
body: {
|
||||
name: string;
|
||||
description: string;
|
||||
requiredInvitationCode: boolean;
|
||||
force?: "use_force_initialization";
|
||||
};
|
||||
response: Success | DatabaseError | UnknownError;
|
||||
body: never;
|
||||
response: (Success & {
|
||||
isInitialized: boolean;
|
||||
isFirstAdminExists: boolean;
|
||||
userCount: number;
|
||||
}) | DatabaseError | UnknownError;
|
||||
};
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import { InputError, InputNoneError } from "../../modules/error/input";
|
||||
import InputError from "../../modules/error/input";
|
||||
import ErrorBase from "../../modules/error";
|
||||
import DatabaseError from "../../modules/error/database";
|
||||
import Success from "../../modules/response/success";
|
||||
import YetInitializationError from "../../modules/error/yet_init";
|
||||
import { UserSchema } from "../primary/signup";
|
||||
import UnknownError from "../../modules/error/unknown";
|
||||
import UserSchema from "../../modules/user";
|
||||
|
||||
export default interface SetupCreateAdmin {
|
||||
"setup/create-admin": {
|
||||
@@ -13,6 +13,6 @@ export default interface SetupCreateAdmin {
|
||||
bad: "client",
|
||||
code: "first_admin_already_exists",
|
||||
message: "最初の管理者ユーザーは既に存在します。",
|
||||
}> | InputError | InputNoneError | YetInitializationError | UnknownError;
|
||||
}> | InputError | YetInitializationError | UnknownError;
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { InputError, InputNoneError } from "../../modules/error/input";
|
||||
import InputError from "../../modules/error/input";
|
||||
import ErrorBase from "../../modules/error";
|
||||
import DatabaseError from "../../modules/error/database";
|
||||
import Success from "../../modules/response/success";
|
||||
@@ -16,6 +16,6 @@ export default interface SetupInitialization {
|
||||
bad: "client",
|
||||
code: "already_initialization",
|
||||
message: "既に初期設定が行われています。",
|
||||
}> | InputError | InputNoneError | UnknownError;
|
||||
}> | InputError | UnknownError;
|
||||
};
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import ErrorBase from ".";
|
||||
|
||||
export type InputError = ErrorBase<{
|
||||
type InputError = ErrorBase<{
|
||||
bad: "client";
|
||||
code: "input_wrong";
|
||||
message: "入力に問題があります。";
|
||||
@@ -11,8 +11,4 @@ export type InputError = ErrorBase<{
|
||||
}[];
|
||||
}>;
|
||||
|
||||
export type InputNoneError = ErrorBase<{
|
||||
bad: "client",
|
||||
code: "input_none",
|
||||
message: "入力がありません。",
|
||||
}>;
|
||||
export default InputError;
|
||||
@@ -1,3 +1,5 @@
|
||||
import ErrorBase from ".";
|
||||
|
||||
type YetInitializationError = ErrorBase<{
|
||||
bad: "client";
|
||||
code: "yet_initialization";
|
||||
|
||||
Reference in New Issue
Block a user