eletrotupi / tcc/ commit / 090c04d

api: update user and drop old create-app

Pedro Lucas Porcellis porcellis@eletrotupi.com · 6 months ago 090c04dfa3141e1224b12a76d3c2aaee605a1e88 Browse files
Parents cc08a06
Changed files
5
Additions
+64
Deletions
-7
api/src/controllers/users.ts
1 1
import { Request, Response, NextFunction } from 'express';
2 2
import {
3 3
  createUser,
4 +
  findUserById,
5 +
  findUserByEmail,
6 +
  updateUser,
4 7
  generateToken
5 8
} from '@app/models/user';
6 9

7 10
import {
8 11
  validateRequiredFields
9 12
} from '@app/utils/validators'
10 13

11 14
export const UsersController = {
12 15
  create: async (req: Request, res: Response, next: NextFunction) => {
13 16
    try {
14 -
      const { email, password, first_name: firstName, last_name: lastName } = req.body;
17 +
      const { email, password, firstName, lastName } = req.body;
15 18

16 19
      // Validate required fields
17 20
      const requiredValidation = validateRequiredFields(req.body, [
18 -
        'email', 'password', 'first_name'
21 +
        'email', 'password', 'firstName'
19 22
      ]);
20 23

21 24
      if (!requiredValidation.valid) {
22 25
        return res.status(400).json({
23 26
          error: "Campos faltantes",
30 33
      );
31 34

32 35
      const jwtToken = generateToken(user.id, user.email);
33 36

34 37
      res.status(201).json({ token: jwtToken });
38 +
    } catch (err) {
39 +
      next(err);
40 +
    }
41 +
  },
42 +

43 +
  update: async (req: Request, res: Response, next: NextFunction) => {
44 +
    try {
45 +
      const { id } = req.params
46 +
      const { email, password, firstName, lastName } = req.body;
47 +

48 +
      const user = await findUserById(Number(id));
49 +

50 +
      if (!user) {
51 +
        return res.status(404).json({
52 +
          error: "Usuário não encontrado"
53 +
        })
54 +
      }
55 +

56 +
      if (email || password || firstName || lastName) {
57 +
        const response = await updateUser(user, {
58 +
          email, firstName, lastName
59 +
        })
60 +
      }
61 +

62 +
      const updated = await findUserById(Number(id))
63 +

64 +
      // TODO: Drop encrypted password & token here
65 +
      return res.status(200).json({
66 +
        user: updated
67 +
      })
35 68
    } catch (err) {
36 69
      next(err);
37 70
    }
38 71
  }
39 72
};
api/src/create-app.ts → api/src/createApp.ts
1 1
import express from 'express';
2 2
import cors from 'cors';
3 +
import bodyParser from 'body-parser';
3 4
import morgan from 'morgan';
4 5
import userRouter from '@app/routes/users';
5 6
import authRouter from '@app/routes/auth';
6 7
import { errorHandler } from '@app/middleware/errorHandler';
7 8
import { PrismaClient } from '@prisma/client';
14 15
    origin: process.env.FRONTEND_URL || '*',
15 16
    credentials: true
16 17
  }));
17 18

18 19
  app.use(express.json());
20 +
  app.use(bodyParser.json());
19 21

20 22
  // Only use morgan in non-test environments
21 23
  if (process.env.NODE_ENV !== 'test') {
22 24
    app.use(morgan('combined'));
23 25
  }
31 33
  app.use("/auth", authRouter);
32 34

33 35
  app.use(errorHandler); // always last
34 36

35 37
  return app;
36 -
}
38 +
}
api/src/index.ts modified+1 -1
api/src/index.ts
1 -
import { createApp } from '@app/create-app';
1 +
import { createApp } from '@app/createApp';
2 2

3 3
const port = process.env.PORT || 3000;
4 4

5 5
const app = createApp();
6 6

7 7
app.listen(port, () => {
8 8
  console.log(`Server booted on port ${port}`)
9 9
})
10 10

api/src/models/user.ts modified+24 -4
api/src/models/user.ts
1 1
import bcrypt from "bcryptjs";
2 2
import { prisma } from '../lib/prisma'
3 3
import {
4 4
  generateToken as createJWT,
5 5
  generatePasswordResetToken,
14 14
  validateRequiredFields
15 15
} from "@app/utils/validators";
16 16

17 17
import { InvalidEmailError, ShortPasswordError } from '@app/lib/errors/UserErrors'
18 18

19 +
type UserOptions = {
20 +
  email: string;
21 +
  firstName: string;
22 +
  lastName: string;
23 +
};
24 +

19 25
const createUser = async (email: string, firstName: string, lastName: string, password: string) => {
20 26
  // Validate email format
21 27
  if (!isValidEmail(email)) {
22 28
    throw new InvalidEmailError()
23 29
  }
24 30

25 31
  // Validate password strength
26 32
  if (!isValidPassword(password)) {
27 33
    throw new ShortPasswordError()
28 34
  }
29 -
  
35 +

30 36
  const encryptedPassword = bcrypt.hashSync(password, 10);
31 37

32 38
  try {
33 39
    const user = await prisma.user.create({
34 40
      data: {
39 45
      }
40 46
    });
41 47

42 48
    return user;
43 49
  } catch (err: any) {
44 -
    console.log(err)
45 -
    throw new Error("Something was off when creating user")
50 +
    throw err;
46 51
  }
47 52
}
48 53

49 54
const generateToken = (userId: number, email: string) => {
50 55
  return createJWT(userId, email);
51 56
}
57 +

58 +
const findUserById = async (id: number) => {
59 +
  return await prisma.user.findUnique({
60 +
    where: { id }
61 +
  });
62 +
};
52 63

53 64
const findUserByEmail = async (email: string) => {
54 65
  return await prisma.user.findUnique({
55 66
    where: { email }
56 67
  });
132 143
  });
133 144

134 145
  return { success: true };
135 146
};
136 147

148 +
const updateUser = async (user: any, data: UserOptions) => {
149 +
  return await prisma.user.update({
150 +
    where: { id: user.id },
151 +
    data
152 +
  });
153 +
}
154 +

137 155
export {
138 156
  createUser,
157 +
  findUserById,
139 158
  generateToken,
140 159
  findUserByEmail,
141 160
  authenticateUser,
142 161
  initiatePasswordReset,
143 -
  resetPassword
162 +
  resetPassword,
163 +
  updateUser
144 164
}
api/src/routes/users.ts
1 1
import { Router } from "express";
2 2
import { UsersController } from '@app/controllers/users'
3 3

4 4
const router = Router();
5 5

6 6
router.post('/', UsersController.create);
7 +
router.put('/:id', UsersController.update);
7 8

8 9
export default router;