mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-17 18:51:14 +01:00
67 lines
1.5 KiB
TypeScript
67 lines
1.5 KiB
TypeScript
|
|
import { TRPCError } from '@trpc/server';
|
||
|
|
import bcrypt from 'bcrypt';
|
||
|
|
import { z } from 'zod';
|
||
|
|
import { hashPassword } from '~/utils/security';
|
||
|
|
import { signUpFormSchema } from '~/validations/user';
|
||
|
|
|
||
|
|
import { createTRPCRouter, publicProcedure } from '../trpc';
|
||
|
|
|
||
|
|
export const userRouter = createTRPCRouter({
|
||
|
|
register: publicProcedure
|
||
|
|
.input(
|
||
|
|
signUpFormSchema.and(
|
||
|
|
z.object({
|
||
|
|
registerToken: z.string(),
|
||
|
|
})
|
||
|
|
)
|
||
|
|
)
|
||
|
|
.mutation(async ({ ctx, input }) => {
|
||
|
|
const token = await ctx.prisma.registrationToken.findUnique({
|
||
|
|
where: {
|
||
|
|
token: input.registerToken,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
if (!token || token.expires < new Date()) {
|
||
|
|
throw new TRPCError({
|
||
|
|
code: 'FORBIDDEN',
|
||
|
|
message: 'Invalid registration token',
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
const existingUser = await ctx.prisma.user.findFirst({
|
||
|
|
where: {
|
||
|
|
name: input.username,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
if (existingUser) {
|
||
|
|
throw new TRPCError({
|
||
|
|
code: 'CONFLICT',
|
||
|
|
message: 'User already exists',
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
const salt = bcrypt.genSaltSync(10);
|
||
|
|
const hashedPassword = hashPassword(input.password, salt);
|
||
|
|
|
||
|
|
const user = await ctx.prisma.user.create({
|
||
|
|
data: {
|
||
|
|
name: input.username,
|
||
|
|
password: hashedPassword,
|
||
|
|
salt: salt,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
await ctx.prisma.registrationToken.delete({
|
||
|
|
where: {
|
||
|
|
id: token.id,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
return {
|
||
|
|
id: user.id,
|
||
|
|
name: user.name,
|
||
|
|
};
|
||
|
|
}),
|
||
|
|
});
|