diff --git a/src/handlers/user.ts b/src/handlers/user.ts index 7708db752b86c2d435dbd7c76e1c226f58d5e229..9db8f91033353581b03030fb00f96858b283b5ec 100644 --- a/src/handlers/user.ts +++ b/src/handlers/user.ts @@ -1,200 +1,199 @@ -import { type Request, type Response } from 'express'; -import { userSchema, updateUserSchema } from "@/validators/userValidator"; -import { db } from "@/db"; -import { eq } from 'drizzle-orm'; -import { usersTable } from "@/db/schema"; -import bcrypt from "bcrypt"; -import jwt from 'jsonwebtoken'; - -export default class User{ - static userRequestValidation (req: Request, update: boolean){ //valida a requisição do usuário - let validation; - if (update) - validation = updateUserSchema.safeParse(req.body); - else - validation = userSchema.safeParse(req.body); - - return validation.success; +import { type Request, type Response } from 'express' +import { userSchema, updateUserSchema } from '@/validators/userValidator' +import { db } from '@/db' +import { eq } from 'drizzle-orm' +import { usersTable } from '@/db/schema' +import bcrypt from 'bcrypt' +import jwt from 'jsonwebtoken' + +export default class User { + static userRequestValidation(req: Request, update: boolean) { + //valida a requisição do usuário + let validation + if (update) validation = updateUserSchema.safeParse(req.body) + else validation = userSchema.safeParse(req.body) + + return validation.success + } + + static userUpdateValidation(req: Request) { + const validation = updateUserSchema.safeParse(req.body) + if (!validation.success) { + console.error('Erro de validação:', validation.error.format()) + } + return validation.success + } + + static async userExistenceValidation(id: number) { + //verifica se o usuário existe + const user = await db.select().from(usersTable).where(eq(usersTable.id, id)).limit(1) + return user.length > 0 + } + + static async getUser(id: number) { + //retorna o usuário presente no db + var user = await db.select().from(usersTable).where(eq(usersTable.id, id)).limit(1) + return user[0] || null + } + + static async updateUser(req: Request, res: Response): Promise<any> { + if (!User.userRequestValidation(req, true)) { + return res.status(400).json({ erro: 'Invalid Request' }) } - static userUpdateValidation(req: Request) { - const validation = updateUserSchema.safeParse(req.body); - if (!validation.success) { - console.error("Erro de validação:", validation.error.format()); - } - return validation.success; + const { id } = req.params + const parsedId = parseInt(id, 10) + if (isNaN(parsedId)) { + return res.status(400).json({ error: 'ID inválido' }) + } + + if (!(await User.userExistenceValidation(parsedId))) { + return res.status(404).json({ error: 'Not Found ' }) } - - static async userExistenceValidation (id: number){ //verifica se o usuário existe - const user = await db.select().from(usersTable).where(eq(usersTable.id, id)).limit(1); - return user.length > 0; + + let hashedPassword = req.body.password + if (req.body.password) { + hashedPassword = await bcrypt.hash(req.body.password, 10) } - static async getUser(id: number){ //retorna o usuário presente no db - var user = await db.select().from(usersTable).where(eq(usersTable.id, id)).limit(1); - return user[0] || null; + const user_updated = await User.getUser(parsedId) + + const updates: Partial<typeof usersTable.$inferInsert> = { + name: req.body.name || user_updated.name, + password: hashedPassword || user_updated.password, + email: req.body.email || user_updated.email, + birthday: req.body.birthday || user_updated.birthday, + cpf: req.body.cpf || user_updated.cpf, + money: req.body.money || user_updated.money, + cyberpsychosis: req.body.cyberpsychosis || user_updated.cyberpsychosis, + cyberLimit: req.body.cyberLimit || user_updated.cyberLimit, } + await db.update(usersTable).set(updates).where(eq(usersTable.id, parsedId)) + + return res.status(200).json({ message: 'User Updated Successfully ' }) + } + + static async deleteUser(req: Request, res: Response): Promise<any> { + const { id } = req.params + const parsedId = parseInt(id, 10) + if (isNaN(parsedId)) { + return res.status(400).json({ error: 'ID inválido' }) + } - static async updateUser (req: Request, res:Response): Promise<any>{ - if (!User.userRequestValidation(req, true)) - { - return res.status(400).json({ erro: "Invalid Request" }); - } - - const { id } = req.params; - const parsedId = parseInt(id, 10); - if (isNaN(parsedId)) { - return res.status(400).json({ error: "ID inválido" }); - } - - if (!(await User.userExistenceValidation(parsedId))) - { - return res.status(404).json({ error: "Not Found "}); - } - - let hashedPassword = req.body.password; - if (req.body.password) - { - hashedPassword = await bcrypt.hash(req.body.password, 10); - } - - const user_updated = await User.getUser(parsedId); - - const updates: Partial<typeof usersTable.$inferInsert> = { - name: req.body.name || user_updated.name, - password: hashedPassword || user_updated.password, - email: req.body.email || user_updated.email, - birthday: req.body.birthday || user_updated.birthday, - cpf: req.body.cpf || user_updated.cpf, - money: req.body.money || user_updated.money, - cyberpsychosis: req.body.cyberpsychosis || user_updated.cyberpsychosis, - cyberLimit: req.body.cyberLimit || user_updated.cyberLimit, - }; - - await db.update(usersTable).set(updates).where(eq(usersTable.id, parsedId)); - - return res.status(200).json({ message: "User Updated Successfully "}); + if (!(await User.userExistenceValidation(parsedId))) { + return res.status(404).json({ error: 'Not Found' }) } - static async deleteUser (req: Request, res: Response): Promise<any>{ - const { id } = req.params; - const parsedId = parseInt(id, 10); - if (isNaN(parsedId)) { - return res.status(400).json({ error: "ID inválido" }); - } - - if (!(await User.userExistenceValidation(parsedId))) - { - return res.status(404).json({ error: "Not Found"}); - } - - try{ - await db.delete(usersTable).where(eq(usersTable.id, parsedId)); - return res.status(200).json({ message: "User removed successfully! "}); - } catch (error){ - return res.status(408).json({ error: "Error during user deletion" }); - } - } - static createUser = async (req: Request, res: Response): Promise<any> => { - try { - - // validar com o Zod - const parsedData = userSchema.safeParse(req.body); - if (!parsedData.success) { - console.error("Erro de validação:", parsedData.error.format()); - return res.status(400).json({ error: "Dados Inválidos", details: parsedData.error.errors }); - } - - // desestruturação dos dados para inserir no banco - const { name, email, password, birthday, cpf, money, cyberpsychosis, cyberLimit } = parsedData.data; - - const hashedPassword = await bcrypt.hash(password, 10); - - const result = await db.insert(usersTable).values({ - name, + try { + await db.delete(usersTable).where(eq(usersTable.id, parsedId)) + return res.status(200).json({ message: 'User removed successfully! ' }) + } catch (error) { + return res.status(408).json({ error: 'Error during user deletion' }) + } + } + static createUser = async (req: Request, res: Response): Promise<any> => { + try { + // validar com o Zod + const parsedData = userSchema.safeParse(req.body) + if (!parsedData.success) { + console.error('Erro de validação:', parsedData.error.format()) + return res.status(400).json({ error: 'Dados Inválidos', details: parsedData.error.errors }) + } + + // desestruturação dos dados para inserir no banco + const { name, email, password, birthday, cpf, money, cyberpsychosis, cyberLimit } = parsedData.data + + const hashedPassword = await bcrypt.hash(password, 10) + + const result = await db + .insert(usersTable) + .values({ + name, email, - password: hashedPassword, + password: hashedPassword, birthday, cpf, money, cyberpsychosis, cyberLimit, - }).returning(); - - res.status(201).json({ message: "Usuário criado com sucesso", user: result }); - - } catch (error) { - console.error(error); - return res.status(500).json({ error: "Erro ao inserir o usuário." }); + }) + .returning() + + res.status(201).json({ message: 'Usuário criado com sucesso', user: result }) + } catch (error) { + console.error(error) + return res.status(500).json({ error: 'Erro ao inserir o usuário.' }) + } + } + + static readUser = async (req: Request, res: Response): Promise<any> => { + try { + // extrair id da requisição + const { id } = req.params + + // converter id para número + const parsedId = parseInt(id, 10) + if (isNaN(parsedId)) { + return res.status(400).json({ error: 'ID inválido' }) + } + + // validar com o Zod + const parsedData = updateUserSchema.safeParse({ id: parsedId }) + if (!parsedData.success) { + return res.status(400).json({ error: 'Dados Inválidos', details: parsedData.error.errors }) } + + const result = await db.select().from(usersTable).where(eq(usersTable.id, parsedId)).limit(1) + if (result.length === 0) { + // array vazio + return res.status(404).json({ error: 'Usuário não encontrado' }) + } + + // desestruturar result e remover password + const { password, ...userWithoutPassword } = result[0] + + return res.status(200).json(userWithoutPassword) + } catch (error) { + console.error(error) + return res.status(500).json({ error: 'Erro ao buscar o usuário.' }) } - - static readUser = async (req: Request, res: Response): Promise<any> => { - try { - // extrair id da requisição - const { id } = req.params; - - // converter id para número - const parsedId = parseInt(id, 10); - if (isNaN(parsedId)) { - return res.status(400).json({ error: "ID inválido" }); - } - - // validar com o Zod - const parsedData = updateUserSchema.safeParse({ id: parsedId }); - if (!parsedData.success) { - return res.status(400).json({ error: "Dados Inválidos", details: parsedData.error.errors }); - } - - const result = await db.select().from(usersTable) - .where( eq(usersTable.id, parsedId) ).limit(1); - if (result.length === 0) { // array vazio - return res.status(404).json({ error: "Usuário não encontrado" }); - } - - // desestruturar result e remover password - const { password, ...userWithoutPassword } = result[0]; - - return res.status(200).json(userWithoutPassword); - - } catch (error) { - console.error(error); - return res.status(500).json({ error: "Erro ao buscar o usuário." }); + } + + static loginUser = async (req: Request, res: Response): Promise<any> => { + try { + const { email, password } = req.body + + // buscar usuário + const user = await db.select().from(usersTable).where(eq(usersTable.email, email)).limit(1) + if (user.length === 0) { + // array vazio + return res.status(404).json({ message: 'Usuário não encontrado' }) } - } - - static loginUser = async (req: Request, res: Response): Promise<any> => { - try { - - const { email, password } = req.body; - - // buscar usuário - const user = await db.select().from(usersTable).where(eq(usersTable.email, email)).limit(1); - if (user.length === 0) { // array vazio - return res.status(404).json({ message: 'Usuário não encontrado' }); - } - - // validar senha - const isPasswordValid = await bcrypt.compare(password, user[0].password); - if (!isPasswordValid) { - return res.status(401).json({ message: 'Senha incorreta' }); - } - - // acessar no .env a chave secreta para assinar e validar tokens - const jwtSecret = process.env["APP_SECRET"]; - if (!jwtSecret) { - return res.status(500).json({ error: "Chave secreta do JWT não configurada" }); - } - - //gerar token - const token = jwt.sign({ id: user[0].id, email: user[0].email }, jwtSecret, { expiresIn: '1h' }); - - return res.status(200).json({ message: 'Login bem-sucedido', token }); - - } catch (error) { - console.error(error); - return res.status(500).json({ error: "Erro ao realizar login" }); + + // validar senha + const isPasswordValid = await bcrypt.compare(password, user[0].password) + if (!isPasswordValid) { + return res.status(401).json({ message: 'Senha incorreta' }) } + + // acessar no .env a chave secreta para assinar e validar tokens + const jwtSecret = process.env['APP_SECRET'] + if (!jwtSecret) { + return res.status(500).json({ error: 'Chave secreta do JWT não configurada' }) + } + + //gerar token + const token = jwt.sign({ id: user[0].id, email: user[0].email }, jwtSecret, { expiresIn: '1h' }) + + return res.status(200).json({ + message: 'Login bem-sucedido', + token, + user_id: user[0].id, + }) + } catch (error) { + console.error(error) + return res.status(500).json({ error: 'Erro ao realizar login' }) } + } }