eletrotupi / tcc/ api/src/controllers/users.ts4cbb518a275506db4d3fac4d5cfe87608f489f44
3.5 KB | 150 lines Raw
1
import { Request, Response, NextFunction } from 'express';
2
import {
3
  generateToken
4
} from '@app/services/auth.service';
5

6
import { getQueue, MailJobName } from '@app/lib/queue';
7
import {
8
  CreateUserSchema,
9
  UpdateUserSchema
10
} from '@app/schemas';
11

12
import {
13
  createUser,
14
  findUserById,
15
  findUserByEmail,
16
  updateUser
17
} from '@app/services/user.service';
18

19
import {
20
  AuthenticatedRequest
21
} from '@app/middleware/auth';
22

23
import { prisma } from '@app/lib/prisma';
24
import s3 from '@app/lib/s3';
25
import { DeleteObjectCommand } from '@aws-sdk/client-s3';
26

27
// XXX: I've regreted already
28
interface SingleFileRequest extends AuthenticatedRequest {
29
  file?: any;
30
}
31

32
export const UsersController = {
33
  create: async (req: Request, res: Response, next: NextFunction) => {
34
    try {
35
      const parsed = CreateUserSchema.safeParse(req.body.user);
36

37
      if (!parsed.success) {
38
        return res.status(422).json({
39
          errors: parsed.error!.issues
40
        })
41
      }
42

43
      const user = await createUser(parsed.data);
44
      const jwtToken = generateToken(user.id, user.email);
45

46
      const mailQueue = getQueue('mail');
47
      const job = await mailQueue.add(MailJobName.WelcomeEmail, { userId: user.id });
48

49
      res.status(201).json({
50
        token: jwtToken
51
      });
52
    } catch (err) {
53
      next(err);
54
    }
55
  },
56

57
  update: async (req: Request, res: Response, next: NextFunction) => {
58
    try {
59
      const { id } = req.params;
60

61
      const parsed = UpdateUserSchema.safeParse(req.body.user);
62
      if (!parsed.success) {
63
        return res.status(400).json({
64
          errors: parsed.error!.issues
65
        });
66
      }
67

68
      const user = await findUserById(Number(id));
69

70
      if (!user) {
71
        return res.status(404).json({
72
          error: "Usuário não encontrado"
73
        });
74
      }
75

76
      const updated = await updateUser(parsed.data);
77

78
      // TODO: Drop encrypted password & token here
79
      return res.status(200).json({
80
        user: updated
81
      });
82
    } catch (err) {
83
      next(err);
84
    }
85
  },
86

87
  updateAvatar: async (req: SingleFileRequest, res: Response, next: NextFunction) => {
88
    try {
89
      if (!req.file) {
90
        return res.status(400).json({ error: 'No file uploaded' });
91
      }
92

93
      const currentUser = await findUserById(Number(req.userId));
94
      if (currentUser?.avatarKey) {
95
        await s3.send(
96
          new DeleteObjectCommand({
97
            Bucket: process.env.S3_BUCKET!, Key: currentUser?.avatarKey!
98
          })
99
        );
100
      }
101

102
      const user = await prisma.user.update({
103
        where: {
104
          id: currentUser?.id
105
        }, data: {
106
          avatarURL: req.file.location,
107
          avatarKey: req.file.key
108
        }
109
      });
110

111
      res.json({
112
        message: 'File uploaded successfully',
113
        fileLocation: req.file.location,
114
        key: req.file.key,
115
        filename: req.file.originalname,
116
        size: req.file.size,
117
        user: user
118
      });
119
    } catch (err) {
120
      next(err);
121
    }
122
  },
123

124
  removeAvatar: async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
125
    const currentUser = await findUserById(Number(req.userId));
126

127
    if (currentUser && currentUser?.avatarKey == null) {
128
      return res.json({ user: currentUser })
129
    }
130

131
    await s3.send(
132
      new DeleteObjectCommand({
133
        Bucket: process.env.S3_BUCKET!, Key: currentUser?.avatarKey!
134
      })
135
    );
136

137
    const user = await prisma.user.update({
138
      where: {
139
        id: req.userId
140
      }, data: {
141
        avatarURL: null,
142
        avatarKey: null
143
      }
144
    });
145

146
    return res.json({
147
      user
148
    })
149
  }
150
}