This repository has been archived on 2024-10-29. You can view files and clone it, but cannot push or open issues or pull requests.
Files
api/src/services/users/signup/post.ts

91 lines
2.7 KiB
TypeScript

import { randomUUID } from "node:crypto"
import type { Static } from "@sinclair/typebox"
import { Type } from "@sinclair/typebox"
import bcrypt from "bcryptjs"
import type { FastifyPluginAsync, FastifySchema } from "fastify"
import prisma from "#src/tools/database/prisma.js"
import { fastifyErrors } from "#src/models/utils.js"
import type { BodyUserSchemaType } from "#src/models/User.js"
import { bodyUserSchema, userPublicSchema } from "#src/models/User.js"
import { sendEmail } from "#src/tools/email/sendEmail.js"
import { API_URL } from "#src/tools/configurations.js"
const queryPostSignupSchema = Type.Object({
redirectURI: Type.Optional(Type.String({ format: "uri-reference" })),
})
type QueryPostSignupSchemaType = Static<typeof queryPostSignupSchema>
const postSignupSchema: FastifySchema = {
description:
"Allows a new user to signup, if success he would need to confirm his email.",
tags: ["users"] as string[],
body: bodyUserSchema,
querystring: queryPostSignupSchema,
response: {
201: Type.Object({ user: Type.Object(userPublicSchema) }),
400: fastifyErrors[400],
500: fastifyErrors[500],
},
} as const
export const postSignupUser: FastifyPluginAsync = async (fastify) => {
await fastify.route<{
Body: BodyUserSchemaType
Querystring: QueryPostSignupSchemaType
}>({
method: "POST",
url: "/users/signup",
schema: postSignupSchema,
handler: async (request, reply) => {
const { name, email, password, theme, language } = request.body
const { redirectURI } = request.query
const userValidation = await prisma.user.findFirst({
where: {
OR: [{ email }, { name }],
},
})
if (userValidation != null) {
throw fastify.httpErrors.badRequest(
"body.email or body.name already taken.",
)
}
const hashedPassword = await bcrypt.hash(password, 12)
const temporaryToken = randomUUID()
const user = await prisma.user.create({
data: {
name,
email,
password: hashedPassword,
temporaryToken,
},
})
const userSettings = await prisma.userSetting.create({
data: {
userId: user.id,
theme,
language,
},
})
const redirectQuery =
redirectURI != null ? `&redirectURI=${redirectURI}` : ""
await sendEmail({
type: "confirm-email",
email,
url: `${API_URL}/users/confirm-email?temporaryToken=${temporaryToken}${redirectQuery}`,
language,
theme,
})
reply.statusCode = 201
return {
user: {
...user,
settings: { ...userSettings },
},
}
},
})
}