eletrotupi / tcc/ api/src/controllers/auth.tsc50ef5d75b90563a411d2101772aeb3b363609ef
2.8 KB | 116 lines Raw
1
import { Request, Response, NextFunction } from 'express';
2
import {
3
  login,
4
  generateToken,
5
  requestPasswordReset,
6
  resetPassword,
7
} from '@app/services/auth.service';
8

9
import {
10
  verifyToken
11
} from '@app/lib/jwt';
12

13
import {
14
  findUserByEmail
15
} from '@app/services/user.service'
16

17
import {
18
  LoginSchema,
19
  PasswordResetSchema,
20
  PasswordResetRequestSchema
21
} from '@app/schemas';
22

23
export const AuthController = {
24
  login: async (req: Request, res: Response, next: NextFunction) => {
25
    try {
26
      const parsed = LoginSchema.safeParse(req.body);
27

28
      if (!parsed.success) {
29
        return res.status(400).json({
30
          errors: parsed.error!.issues
31
        });
32
      }
33

34
      const { user, token } = await login(parsed.data);
35

36
      return res.json({
37
        token,
38
        user
39
      });
40
    } catch (err: any) {
41
      if (err.message === 'Invalid credentials') {
42
        return res.status(401).json({ error: 'Invalid credentials' });
43
      }
44
      next(err);
45
    }
46
  },
47

48
  forgotPassword: async (req: Request, res: Response, next: NextFunction) => {
49
    try {
50

51
      const parsed = PasswordResetRequestSchema.safeParse(req.body);
52

53
      if (!parsed.success) {
54
        return res.status(400).json({
55
          errors: parsed.error!.issues
56
        });
57
      }
58

59
      const result = await requestPasswordReset(parsed.data);
60
      return res.status(200).json(result)
61
    } catch (err) {
62
      next(err);
63
    }
64
  },
65

66
  resetPassword: async (req: Request, res: Response, next: NextFunction) => {
67
    try {
68
      const parsed = PasswordResetSchema.safeParse(req.body);
69

70
      if (!parsed.success) {
71
        return res.status(400).json({
72
          errors: parsed.error!.issues
73
        });
74
      }
75

76
      const result = await resetPassword(parsed.data);
77
      return res.status(200).json(result);
78
    } catch (err: any) {
79
      if (err.message.includes('token')) {
80
        return res.status(400).json({ error: err.message });
81
      }
82
      next(err);
83
    }
84
  },
85

86
  verify: async (req: Request, res: Response, next: NextFunction) => {
87
    try {
88
      const authHeader = req.headers.authorization;
89

90
      if (!authHeader || !authHeader.startsWith('Bearer ')) {
91
        return res.status(401).json({ error: 'No token provided' });
92
      }
93

94
      const token = authHeader.substring(7);
95
      const payload = verifyToken(token);
96
      const user = await findUserByEmail(payload.email);
97

98
      res.json({
99
        valid: true,
100
        userId: payload.userId,
101
        email: payload.email,
102
        user: {
103
          firstName: user?.firstName,
104
          email: user?.email,
105
          lastName: user?.lastName,
106
          updatedAt: user?.updatedAt
107
        }
108
      });
109
    } catch (err: any) {
110
      if (err.name === 'JsonWebTokenError' || err.name === 'TokenExpiredError') {
111
        return res.status(401).json({ error: 'Invalid or expired token' });
112
      }
113
      next(err);
114
    }
115
  }
116
};