Chg: exactOptionalPropertyTypesをfalseに変更 / Chg(Security): トークンが不正な場合のエラーを全てtoken_invalidに変更 / New: channelテーブル・リポジトリ / Chg: configテーブルのvalueをstringに / Chg: configテーブルのlengthを4096に / New: messageテーブル / Chg: 安全のためuserテーブルのOptionalPropsにidを追加 / New: channel/createエンドポイント / New: channel/listエンドポイント / New: channel/editエンドポイント / Enhance: primary/signupエンドポイントの重複エラーの実装で末尾カンマなどの改善 / Chg: setup/initializationのdescriptionに最大文字数4096を制定 / Chg: serverInfoをdefault exportからexportに変更 / New: フロントエンドでmeを読み込み / New: フロントエンドでchannelを読み込み / New: client.tsでトークンがある場合はトークンを指定 / Chg: clientをrefに / Del: IndexedDBからserverテーブルを削除 / Fix: Dexieのclassに命名 / Feat: フロントエンドでのサインインページ / Fix: L.jsで任意のbodyがあるエンドポイントが定義できない問題を修正 / Del: L.jsのserver-infoでの不要なimportを削除 / Fix: L.jsでトークンのエラーを追加 / Fix: L.jsのUserSchemaにlastUsedAtを追加
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import { DatabaseError, InputError } from "@/errors";
|
||||
import Logger from "@/lib/logger";
|
||||
import { ChannelEntity } from "@/modules/entities/Channel";
|
||||
import { ChannelRepository } from "@/modules/repositories/Channel";
|
||||
import type { FastifyInstance } from "fastify";
|
||||
|
||||
export default async function ChannelCreate(fastify: FastifyInstance) {
|
||||
const logger = new Logger("Endpoint | channel/create");
|
||||
|
||||
fastify.post("/", async (req, res) => {
|
||||
res.header("Content-Type", "application/json");
|
||||
|
||||
if ("error" in req.token)
|
||||
return res.code(400).send(req.token);
|
||||
|
||||
const result = ChannelRepository.schema.safeParse({
|
||||
...req.body as any,
|
||||
userid: req.token.user.userid,
|
||||
});
|
||||
|
||||
if (!result.success) {
|
||||
return res.code(400).send(InputError(result.error.issues));
|
||||
}
|
||||
|
||||
try {
|
||||
const channelRepo = fastify.orm.em.getRepository(ChannelEntity);
|
||||
|
||||
const id = await channelRepo.createChannel(result.data);
|
||||
|
||||
return res.send({
|
||||
success: true,
|
||||
id,
|
||||
});
|
||||
} catch (err: any) {
|
||||
if (err.name === "UniqueConstraintViolationException") {
|
||||
const duplicate = err.constraint.replace("channel_", "").replace("_unique", "");
|
||||
|
||||
if (duplicate !== "id") {
|
||||
return res.code(400).send(InputError([
|
||||
{
|
||||
validation: "regex",
|
||||
code: "invalid_string",
|
||||
message: "Duplicate",
|
||||
path: [duplicate],
|
||||
},
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
logger.error("Database Error:", err);
|
||||
|
||||
return res.code(500).send(DatabaseError());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import { DatabaseError, ErrorBase, InputError } from "@/errors";
|
||||
import Logger from "@/lib/logger";
|
||||
import { ChannelEntity } from "@/modules/entities/Channel";
|
||||
import { ChannelRepository } from "@/modules/repositories/Channel";
|
||||
import type { FastifyInstance } from "fastify";
|
||||
import z from "zod/v3";
|
||||
|
||||
export default async function ChannelEdit(fastify: FastifyInstance) {
|
||||
const logger = new Logger("Endpoint | channel/edit");
|
||||
|
||||
fastify.post("/", async (req, res) => {
|
||||
res.header("Content-Type", "application/json");
|
||||
|
||||
if ("error" in req.token)
|
||||
return res.code(400).send(req.token);
|
||||
|
||||
const result = ChannelRepository.schema
|
||||
.omit({ userid: true }).partial()
|
||||
.merge(z.object({ id: z.string().length(10) }))
|
||||
.refine(data =>
|
||||
!Object.keys(data).length
|
||||
).safeParse(req.body);
|
||||
|
||||
if (!result.success) {
|
||||
return res.code(400).send(InputError(result.error.issues));
|
||||
}
|
||||
|
||||
try {
|
||||
const channelRepo = fastify.orm.em.getRepository(ChannelEntity);
|
||||
const itChannel = await channelRepo.findOne({ id: result.data.id });
|
||||
|
||||
if (!itChannel) {
|
||||
return res.code(400).send(ErrorBase({
|
||||
bad: "client",
|
||||
code: "channel_not_found",
|
||||
message: "対象のチャンネルが見つかりませんでした。",
|
||||
}));
|
||||
}
|
||||
|
||||
const id = await channelRepo.editChannel(itChannel, result.data);
|
||||
|
||||
return res.send({
|
||||
success: true,
|
||||
id,
|
||||
});
|
||||
} catch (err) {
|
||||
logger.error("Database Error:", err);
|
||||
|
||||
return res.code(500).send(DatabaseError());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { FastifyInstance } from "fastify";
|
||||
import ChannelList from "./list";
|
||||
import ChannelCreate from "./create";
|
||||
import ChannelEdit from "./edit";
|
||||
|
||||
export default async function Setup(fastify: FastifyInstance) {
|
||||
await fastify.register(ChannelList, {
|
||||
prefix: "/list",
|
||||
});
|
||||
|
||||
await fastify.register(ChannelCreate, {
|
||||
prefix: "/create",
|
||||
});
|
||||
|
||||
await fastify.register(ChannelEdit, {
|
||||
prefix: "/edit",
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import { DatabaseError, InputError } from "@/errors";
|
||||
import Logger from "@/lib/logger";
|
||||
import { ChannelEntity } from "@/modules/entities/Channel";
|
||||
import type { FastifyInstance } from "fastify";
|
||||
import z from "zod/v3";
|
||||
|
||||
export default async function ChannelList(fastify: FastifyInstance) {
|
||||
const logger = new Logger("Endpoint | channel/list");
|
||||
|
||||
fastify.post("/", async (req, res) => {
|
||||
res.header("Content-Type", "application/json");
|
||||
|
||||
if ("error" in req.token)
|
||||
return res.code(400).send(req.token);
|
||||
|
||||
const bodySchema = z.object({
|
||||
limit: z.number().optional(),
|
||||
since: z.string().optional(),
|
||||
});
|
||||
|
||||
const result = bodySchema.safeParse(req.body);
|
||||
|
||||
if (!result.success) {
|
||||
return res.code(400).send(InputError(result.error.issues));
|
||||
}
|
||||
|
||||
try {
|
||||
const channelRepo = fastify.orm.em.getRepository(ChannelEntity);
|
||||
|
||||
const findResult = await channelRepo.findChannel(
|
||||
result.data.limit,
|
||||
result.data.since,
|
||||
) ?? [];
|
||||
|
||||
if ("error" in findResult) {
|
||||
return res.code(400).send(findResult);
|
||||
}
|
||||
|
||||
return res.send({
|
||||
success: true,
|
||||
channels: findResult,
|
||||
});
|
||||
} catch (err) {
|
||||
logger.error("Database Error:", err);
|
||||
|
||||
return res.code(500).send(DatabaseError());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -40,9 +40,9 @@ export default function PrimarySignUp(fastify: FastifyInstance) {
|
||||
validation: "regex",
|
||||
code: "invalid_string",
|
||||
message: "Duplicate",
|
||||
path: [duplicate]
|
||||
}
|
||||
]))
|
||||
path: [duplicate],
|
||||
},
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ export default function SetupInitialization(fastify: FastifyInstance) {
|
||||
|
||||
const bodySchema = z.object({
|
||||
name: z.string().trim().min(1).max(20),
|
||||
description: z.string().trim().min(1),
|
||||
description: z.string().trim().min(1).max(4096),
|
||||
requiredInvitationCode: z.boolean(),
|
||||
force: z.literal("use_force_initialization").refine(() => process.env.NODE_ENV !== "production").optional(),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user