Feat: #10 サインアップ / Chg: server-infoでconfigの取得にconfigRepo.get()を使うように / Fix: アカウントが無効でもコミュニティを作成ボタンがある問題

This commit is contained in:
2026-06-01 18:31:05 +09:00
parent 45a682b6ca
commit c725ae41bf
7 changed files with 288 additions and 21 deletions
@@ -1,8 +1,10 @@
import { EntityRepository } from "@mikro-orm/postgresql";
import { UserEntity } from "@/modules/entities/User";
import { ConfigEntity } from "@/modules/entities/Config";
import { hash, argon2id, verify as argon2Verify } from "argon2";
import z from "zod/v3";
import EmailRegex from "@/regexs/email";
import { ErrorBase } from "@/errors";
export class UserRepository extends EntityRepository<UserEntity> {
public static schema = z.object({
@@ -15,7 +17,18 @@ export class UserRepository extends EntityRepository<UserEntity> {
isAdmin: z.boolean(),
});
async createUser(data: Pick<z.infer<typeof UserRepository.schema>, "userid" | "email" | "password" | "isAdmin">) {
async createUser(data: Pick<z.infer<typeof UserRepository.schema>, "userid" | "email" | "password" | "isAdmin"> & {
invitationCode?: string;
}) {
const requiredInvitationCode = await this.em.getRepository(ConfigEntity).get("requiredInvitationCode", "true") as string;
if (requiredInvitationCode && !data.invitationCode) {
return ErrorBase({
bad: "client",
code: "invitation_code_invalid",
message: "招待コードが無効です。",
});
}
const hashed = await hash(data.password, {
type: argon2id,
memoryCost: 2 ** 16,
+30 -13
View File
@@ -3,6 +3,8 @@ import Logger from "@/lib/logger";
import type { FastifyInstance } from "fastify";
import { UserRepository } from "@/modules/repositories/User";
import { DatabaseError, InputError } from "@/errors";
import { ConfigEntity } from "@/modules/entities/Config";
import z, { ZodObject } from "zod/v3";
export default function PrimarySignUp(fastify: FastifyInstance) {
const logger = new Logger("Endpoint | primary/signup");
@@ -10,23 +12,38 @@ export default function PrimarySignUp(fastify: FastifyInstance) {
fastify.post("/", async (req, res) => {
res.header("Content-Type", "application/json");
const result = UserRepository.schema.pick({
userid: true,
email: true,
password: true,
}).safeParse(req.body);
if (!result.success) {
console.log(result.error.issues)
return res.code(400).send(InputError(result.error.issues));
}
try {
await fastify.orm.em.getRepository(UserEntity).createUser({
...result.data,
const requiredInvitationCode = await fastify.orm.em.getRepository(ConfigEntity).get("requiredInvitationCode", "true") as string;
let reqInvCodeSchema: ZodObject<any>;
if (requiredInvitationCode !== "true") {
reqInvCodeSchema = z.object({});
} else {
reqInvCodeSchema = z.object({
invitationCode: z.string().trim().min(1),
});
}
const result = UserRepository.schema.pick({
userid: true,
email: true,
password: true,
}).merge(reqInvCodeSchema).safeParse(req.body);
if (!result.success) {
console.log(result.error.issues)
return res.code(400).send(InputError(result.error.issues));
}
const error = await fastify.orm.em.getRepository(UserEntity).createUser({
...(result.data as any),
isAdmin: false,
});
if (error) {
return res.code(400).send(error);
}
return res.code(200).send({
success: true,
});
+6 -6
View File
@@ -15,15 +15,15 @@ export default async function ServerInfo(fastify: FastifyInstance) {
const configCount = await configRepo.count();
const userCount = await userRepo.count();
const serverName = await configRepo.findOne({ name: "name" });
const serverDescription = await configRepo.findOne({ name: "description" });
const serverIcon = await configRepo.findOne({ name: "icon" });
const serverName = await configRepo.get("name");
const serverDescription = await configRepo.get("description");
const serverIcon = await configRepo.get("icon");
return res.send({
success: true,
name: serverName?.value ?? null,
description: serverDescription?.value ?? null,
icon: serverIcon?.value ?? null,
name: serverName ?? null,
description: serverDescription ?? null,
icon: serverIcon ?? null,
isInitialized: configCount > 0,
isFirstAdminExists: userCount > 0,
userCount,