@hedhog/admin 0.46.36 → 0.46.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +960 -960
  2. package/dist/auth/auth.service.d.ts.map +1 -1
  3. package/dist/auth/auth.service.js +22 -2
  4. package/dist/auth/auth.service.js.map +1 -1
  5. package/dist/auth/consts/body.js +24 -24
  6. package/dist/emails/index.d.ts +3 -0
  7. package/dist/emails/index.d.ts.map +1 -0
  8. package/dist/emails/index.js +19 -0
  9. package/dist/emails/index.js.map +1 -0
  10. package/dist/emails/lib.d.ts +6 -0
  11. package/dist/emails/lib.d.ts.map +1 -0
  12. package/dist/emails/lib.js +43 -0
  13. package/dist/emails/lib.js.map +1 -0
  14. package/dist/emails/templates.d.ts +13 -0
  15. package/dist/emails/templates.d.ts.map +1 -0
  16. package/dist/emails/templates.js +63 -0
  17. package/dist/emails/templates.js.map +1 -0
  18. package/frontend/menu/components/create-panel.tsx.ejs +55 -55
  19. package/frontend/menu/components/update-panel.tsx.ejs +67 -67
  20. package/frontend/menu/locales/en/admin.menu.json +11 -11
  21. package/frontend/menu/locales/pt/admin.menu.json +11 -11
  22. package/frontend/menu/react-query/handlers.ts.ejs +28 -28
  23. package/frontend/menu/react-query/requests.ts.ejs +56 -56
  24. package/frontend/menu-locale/locales/en/admin.menu-locale.json +11 -11
  25. package/frontend/menu-locale/locales/pt/admin.menu-locale.json +11 -11
  26. package/frontend/menu-screen/locales/en/admin.menu-screen.json +11 -11
  27. package/frontend/menu-screen/locales/pt/admin.menu-screen.json +11 -11
  28. package/frontend/multifactor/components/create-panel.tsx.ejs +55 -55
  29. package/frontend/multifactor/components/update-panel.tsx.ejs +70 -70
  30. package/frontend/multifactor/locales/en/admin.multifactor.json +11 -11
  31. package/frontend/multifactor/locales/pt/admin.multifactor.json +11 -11
  32. package/frontend/multifactor/react-query/handlers.ts.ejs +28 -28
  33. package/frontend/multifactor/react-query/requests.ts.ejs +59 -59
  34. package/frontend/multifactor-locale/locales/en/admin.multifactor-locale.json +11 -11
  35. package/frontend/multifactor-locale/locales/pt/admin.multifactor-locale.json +11 -11
  36. package/frontend/screen/components/create-panel.tsx.ejs +55 -55
  37. package/frontend/screen/components/update-panel.tsx.ejs +67 -67
  38. package/frontend/screen/locales/en/admin.screen.json +11 -11
  39. package/frontend/screen/locales/pt/admin.screen.json +11 -11
  40. package/frontend/screen/react-query/handlers.ts.ejs +28 -28
  41. package/frontend/screen/react-query/requests.ts.ejs +56 -56
  42. package/frontend/screen-locale/locales/en/admin.screen-locale.json +11 -11
  43. package/frontend/screen-locale/locales/pt/admin.screen-locale.json +11 -11
  44. package/frontend/translation/components/create-panel.tsx.ejs +52 -52
  45. package/frontend/translation/components/update-panel.tsx.ejs +67 -67
  46. package/frontend/translation/locales/en/admin.translation.json +11 -11
  47. package/frontend/translation/locales/pt/admin.translation.json +11 -11
  48. package/frontend/translation/react-query/handlers.ts.ejs +28 -28
  49. package/frontend/translation/react-query/requests.ts.ejs +58 -58
  50. package/frontend/translation-namespace/components/create-panel.tsx.ejs +53 -53
  51. package/frontend/translation-namespace/components/update-panel.tsx.ejs +70 -70
  52. package/frontend/translation-namespace/locales/en/admin.translation-namespace.json +11 -11
  53. package/frontend/translation-namespace/locales/pt/admin.translation-namespace.json +11 -11
  54. package/frontend/translation-namespace/react-query/handlers.ts.ejs +28 -28
  55. package/frontend/translation-namespace/react-query/requests.ts.ejs +60 -60
  56. package/frontend/user/components/create-panel.tsx.ejs +52 -52
  57. package/frontend/user/components/update-panel.tsx.ejs +64 -64
  58. package/frontend/user/locales/en/admin.user.json +11 -11
  59. package/frontend/user/locales/pt/admin.user.json +11 -11
  60. package/frontend/user/react-query/handlers.ts.ejs +28 -28
  61. package/frontend/user/react-query/requests.ts.ejs +55 -55
  62. package/hedhog.yaml +783 -783
  63. package/package.json +45 -43
  64. package/src/admin.module.ts +39 -39
  65. package/src/auth/auth.controller.ts +88 -88
  66. package/src/auth/auth.module.ts +41 -41
  67. package/src/auth/auth.service.spec.ts +196 -196
  68. package/src/auth/auth.service.ts +349 -323
  69. package/src/auth/consts/body.ts +27 -27
  70. package/src/auth/dto/change.dto.ts +19 -19
  71. package/src/auth/dto/email.dto.ts +15 -15
  72. package/src/auth/dto/forget.dto.ts +6 -6
  73. package/src/auth/dto/login.dto.ts +21 -21
  74. package/src/auth/dto/otp.dto.ts +11 -11
  75. package/src/auth/dto/reset.dto.ts +14 -14
  76. package/src/auth/enums/multifactor-type.enum.ts +4 -4
  77. package/src/auth/guards/auth.guard.ts +54 -54
  78. package/src/auth/types/user.type.ts +8 -8
  79. package/src/dto/delete.dto.ts +8 -8
  80. package/src/dto/update-ids.dto.ts +9 -9
  81. package/src/emails/index.ts +2 -0
  82. package/src/emails/lib.ts +40 -0
  83. package/src/emails/templates.ts +60 -0
  84. package/src/index.ts +20 -20
  85. package/src/menu/dto/create.dto.ts +25 -25
  86. package/src/menu/dto/order.dto.ts +8 -8
  87. package/src/menu/dto/update.dto.ts +19 -19
  88. package/src/menu/menu.controller.ts +105 -105
  89. package/src/menu/menu.module.ts +18 -18
  90. package/src/menu/menu.service.spec.ts +247 -247
  91. package/src/menu/menu.service.ts +263 -263
  92. package/src/role/dto/create.dto.ts +7 -7
  93. package/src/role/dto/update.dto.ts +4 -4
  94. package/src/role/guards/role.guard.ts +121 -121
  95. package/src/role/role.controller.ts +126 -126
  96. package/src/role/role.module.ts +28 -28
  97. package/src/role/role.service.spec.ts +417 -417
  98. package/src/role/role.service.ts +289 -289
  99. package/src/route/dto/create.dto.ts +13 -13
  100. package/src/route/dto/update.dto.ts +15 -15
  101. package/src/route/route.controller.ts +91 -91
  102. package/src/route/route.module.ts +18 -18
  103. package/src/route/route.service.spec.ts +300 -300
  104. package/src/route/route.service.ts +164 -164
  105. package/src/screen/dto/create.dto.ts +11 -11
  106. package/src/screen/dto/update.dto.ts +19 -19
  107. package/src/screen/screen.controller.ts +93 -93
  108. package/src/screen/screen.module.ts +18 -18
  109. package/src/screen/screen.service.spec.ts +298 -298
  110. package/src/screen/screen.service.ts +179 -179
  111. package/src/types/http-method.ts +8 -8
  112. package/src/user/constants/user.constants.ts +1 -1
  113. package/src/user/dto/create.dto.ts +24 -24
  114. package/src/user/dto/update.dto.ts +41 -41
  115. package/src/user/user.controller.ts +75 -75
  116. package/src/user/user.module.ts +18 -18
  117. package/src/user/user.service.spec.ts +294 -294
  118. package/src/user/user.service.ts +129 -129
  119. package/tsconfig.lib.json +9 -9
  120. package/tsconfig.production.json +20 -20
@@ -1,323 +1,349 @@
1
- import { MailService } from '@hedhog/mail';
2
- import { PrismaService } from '@hedhog/prisma';
3
- import {
4
- BadRequestException,
5
- ConflictException,
6
- forwardRef,
7
- Inject,
8
- Injectable,
9
- NotFoundException,
10
- } from '@nestjs/common';
11
- import { ConfigService } from '@nestjs/config';
12
- import { JwtService } from '@nestjs/jwt';
13
- import { compare, genSalt, hash } from 'bcrypt';
14
- import { getBody } from './consts/body';
15
- import { ChangeDTO } from './dto/change.dto';
16
- import { EmailDTO } from './dto/email.dto';
17
- import { ForgetDTO } from './dto/forget.dto';
18
- import { LoginDTO } from './dto/login.dto';
19
- import { OtpDTO } from './dto/otp.dto';
20
- import { ResetDTO } from './dto/reset.dto';
21
- import { MultifactorType } from './enums/multifactor-type.enum';
22
-
23
- @Injectable()
24
- export class AuthService {
25
- constructor(
26
- private readonly configService: ConfigService,
27
- @Inject(forwardRef(() => PrismaService))
28
- private readonly prisma: PrismaService,
29
- @Inject(forwardRef(() => JwtService))
30
- private readonly jwt: JwtService,
31
- @Inject(forwardRef(() => MailService))
32
- private readonly mail: MailService,
33
- ) {}
34
-
35
- async verifyToken(token: string) {
36
- return this.jwt.verifyAsync(token, {
37
- secret: String(process.env.JWT_SECRET),
38
- });
39
- }
40
-
41
- generateRandomString(length: number): string {
42
- const characters =
43
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
44
- let result = '';
45
- for (let i = 0; i < length; i++) {
46
- const randomIndex = Math.floor(Math.random() * characters.length);
47
- result += characters.charAt(randomIndex);
48
- }
49
- return result;
50
- }
51
-
52
- generateRandomNumber(): number {
53
- const min = 100000;
54
- const max = 999999;
55
- return Math.floor(Math.random() * (max - min + 1)) + min;
56
- }
57
-
58
- async loginWithEmailAndPassword(email: string, password: string) {
59
- const user = await this.prisma.user.findFirst({
60
- where: {
61
- email,
62
- },
63
- });
64
-
65
- if (!user) {
66
- throw new BadRequestException('Acesso negado');
67
- }
68
-
69
- const isPasswordValid = await compare(password, user.password);
70
- if (!isPasswordValid) {
71
- throw new BadRequestException('Acesso negado');
72
- }
73
-
74
- if (!user.multifactor_id) {
75
- return this.getToken(user);
76
- } else {
77
- if (user.multifactor_id === MultifactorType.EMAIL) {
78
- const code = this.generateRandomNumber();
79
-
80
- await this.prisma.user.update({
81
- where: {
82
- id: user.id,
83
- },
84
- data: {
85
- code: String(code),
86
- },
87
- });
88
-
89
- await this.mail.send({
90
- to: user.email,
91
- subject: 'Código de Login',
92
- body: `Seu código de login é ${code}`,
93
- });
94
- }
95
-
96
- return {
97
- name: user.name,
98
- email: user.email,
99
- token: this.jwt.sign({
100
- id: user.id,
101
- mfa: user.multifactor_id,
102
- }),
103
- mfa: true,
104
- };
105
- }
106
- }
107
-
108
- async getToken(user) {
109
- delete user.password;
110
-
111
- const payload = { user };
112
-
113
- return {
114
- token: this.jwt.sign(payload),
115
- };
116
- }
117
-
118
- async forget({ email }: ForgetDTO) {
119
- const appUrl =
120
- process.env.APP_URL ?? this.configService.get<string>('APP_URL');
121
-
122
- const user = await this.prisma.user.findFirst({
123
- where: {
124
- email,
125
- },
126
- select: {
127
- id: true,
128
- },
129
- });
130
-
131
- if (user) {
132
- const payload = {
133
- ...user,
134
- };
135
-
136
- const code = this.jwt.sign(payload);
137
-
138
- await this.prisma.user.update({
139
- where: {
140
- id: user.id,
141
- },
142
- data: {
143
- code,
144
- },
145
- });
146
-
147
- await this.mail.send({
148
- to: email,
149
- subject: `Recuperação de Senha`,
150
- body: getBody(`${appUrl}/login?mode=reset-password&code=${code}`),
151
- });
152
- }
153
-
154
- return {
155
- message:
156
- 'Se este e-mail estiver cadastrado, você receberá instruções para redefinir sua senha.',
157
- };
158
- }
159
-
160
- async changePassword({
161
- email,
162
- currentPassword,
163
- newPassword,
164
- confirmNewPassword,
165
- }: ChangeDTO) {
166
- if (newPassword !== confirmNewPassword) {
167
- throw new BadRequestException('Senhas não conferem');
168
- }
169
-
170
- const user = await this.prisma.user.findFirst({
171
- where: { email },
172
- });
173
-
174
- if (!(await compare(currentPassword, user.password))) {
175
- throw new NotFoundException('Não foi possível alterar a senha.');
176
- }
177
-
178
- const salt = await genSalt();
179
- const password = await hash(newPassword, salt);
180
-
181
- const newUser = await this.prisma.user.update({
182
- where: {
183
- id: user.id,
184
- },
185
- data: {
186
- password,
187
- },
188
- });
189
-
190
- return this.getToken(newUser);
191
- }
192
-
193
- async changeEmail({ currentEmail, password, newEmail }: EmailDTO) {
194
- const user = await this.prisma.user.findFirst({
195
- where: { email: currentEmail },
196
- });
197
-
198
- if (!user) {
199
- throw new BadRequestException('Não foi possível atualizar o e-mail.');
200
- }
201
-
202
- if (!(await compare(password, user.password))) {
203
- throw new BadRequestException('Não foi possível atualizar o e-mail.');
204
- }
205
-
206
- const existingUser = await this.prisma.user.findFirst({
207
- where: { email: newEmail },
208
- });
209
-
210
- if (existingUser) {
211
- throw new ConflictException('Não foi possível atualizar o e-mail.');
212
- }
213
-
214
- const newUser = await this.prisma.user.updateMany({
215
- where: { email: currentEmail },
216
- data: { email: newEmail },
217
- });
218
-
219
- const personUser = await this.prisma.person_user.findFirst({
220
- where: { user_id: user.id },
221
- select: { person_id: true },
222
- });
223
-
224
- if (!personUser) {
225
- throw new NotFoundException('Erro ao atualizar os dados do usuário.');
226
- }
227
-
228
- const { id: emailContactTypeId } =
229
- await this.prisma.person_contact_type.findFirst({
230
- where: { slug: 'EMAIL' },
231
- });
232
-
233
- await this.prisma.person_contact.updateMany({
234
- where: {
235
- person_id: personUser.person_id,
236
- type_id: emailContactTypeId,
237
- },
238
- data: { value: newEmail },
239
- });
240
-
241
- return this.getToken(newUser);
242
- }
243
-
244
- async resetPassword({ code, newPassword, confirmNewPassword }: ResetDTO) {
245
- if (newPassword !== confirmNewPassword) {
246
- throw new BadRequestException('Senhas não conferem');
247
- }
248
-
249
- try {
250
- const decodedCode = this.jwt.decode(code);
251
-
252
- console.log({ decodedCode });
253
-
254
- const { id } = decodedCode;
255
-
256
- const user = await this.prisma.user.findFirst({
257
- where: {
258
- id,
259
- code,
260
- },
261
- });
262
-
263
- if (user) {
264
- const salt = await genSalt();
265
- const password = await hash(confirmNewPassword, salt);
266
-
267
- await this.prisma.user.update({
268
- where: {
269
- id: user.id,
270
- },
271
- data: {
272
- password,
273
- code: null,
274
- },
275
- });
276
-
277
- return this.getToken(user);
278
- }
279
-
280
- return false;
281
- } catch (error: any) {
282
- throw new BadRequestException(
283
- `Invalid code. ${error?.message ?? String(error)}`,
284
- );
285
- }
286
- }
287
-
288
- async otp({ token, code }: OtpDTO) {
289
- const data = this.jwt.decode(token);
290
-
291
- const user = await this.prisma.user.findFirst({
292
- where: {
293
- id: data['id'],
294
- code: String(code),
295
- },
296
- });
297
-
298
- if (!user) {
299
- throw new NotFoundException('Código inválido');
300
- }
301
-
302
- await this.prisma.user.update({
303
- where: {
304
- id: user.id,
305
- },
306
- data: {
307
- code: null,
308
- },
309
- });
310
-
311
- return this.getToken(user);
312
- }
313
-
314
- async login({ email, password }: LoginDTO) {
315
- return this.loginWithEmailAndPassword(email, password);
316
- }
317
-
318
- async verify(id: number) {
319
- return this.prisma.user.findUnique({
320
- where: { id },
321
- });
322
- }
323
- }
1
+ import { MailService } from '@hedhog/mail';
2
+ import { PrismaService } from '@hedhog/prisma';
3
+ import {
4
+ BadRequestException,
5
+ ConflictException,
6
+ forwardRef,
7
+ Inject,
8
+ Injectable,
9
+ NotFoundException,
10
+ } from '@nestjs/common';
11
+ import { ConfigService } from '@nestjs/config';
12
+ import { JwtService } from '@nestjs/jwt';
13
+ import { compare, genSalt, hash } from 'bcrypt';
14
+ import { getBody } from './consts/body';
15
+ import { ChangeDTO } from './dto/change.dto';
16
+ import { EmailDTO } from './dto/email.dto';
17
+ import { ForgetDTO } from './dto/forget.dto';
18
+ import { LoginDTO } from './dto/login.dto';
19
+ import { OtpDTO } from './dto/otp.dto';
20
+ import { ResetDTO } from './dto/reset.dto';
21
+ import { MultifactorType } from './enums/multifactor-type.enum';
22
+ import { getChangeEmailEmail, getChangePasswordEmail, getForgetPasswordEmail, getResetPasswordEmail, getUserLoginEmail } from '../emails';
23
+
24
+ @Injectable()
25
+ export class AuthService {
26
+ constructor(
27
+ private readonly configService: ConfigService,
28
+ @Inject(forwardRef(() => PrismaService))
29
+ private readonly prisma: PrismaService,
30
+ @Inject(forwardRef(() => JwtService))
31
+ private readonly jwt: JwtService,
32
+ @Inject(forwardRef(() => MailService))
33
+ private readonly mail: MailService,
34
+ ) { }
35
+
36
+ async verifyToken(token: string) {
37
+ return this.jwt.verifyAsync(token, {
38
+ secret: String(process.env.JWT_SECRET),
39
+ });
40
+ }
41
+
42
+ generateRandomString(length: number): string {
43
+ const characters =
44
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
45
+ let result = '';
46
+ for (let i = 0; i < length; i++) {
47
+ const randomIndex = Math.floor(Math.random() * characters.length);
48
+ result += characters.charAt(randomIndex);
49
+ }
50
+ return result;
51
+ }
52
+
53
+ generateRandomNumber(): number {
54
+ const min = 100000;
55
+ const max = 999999;
56
+ return Math.floor(Math.random() * (max - min + 1)) + min;
57
+ }
58
+
59
+ async loginWithEmailAndPassword(email: string, password: string) {
60
+ const user = await this.prisma.user.findFirst({
61
+ where: {
62
+ email,
63
+ },
64
+ });
65
+
66
+ if (!user) {
67
+ throw new BadRequestException('Acesso negado');
68
+ }
69
+
70
+ const isPasswordValid = await compare(password, user.password);
71
+ if (!isPasswordValid) {
72
+ throw new BadRequestException('Acesso negado');
73
+ }
74
+
75
+ if (!user.multifactor_id) {
76
+ return this.getToken(user);
77
+ } else {
78
+ if (user.multifactor_id === MultifactorType.EMAIL) {
79
+ const code = this.generateRandomNumber();
80
+
81
+ await this.prisma.user.update({
82
+ where: {
83
+ id: user.id,
84
+ },
85
+ data: {
86
+ code: String(code),
87
+ },
88
+ });
89
+
90
+ await this.mail.send({
91
+ to: user.email,
92
+ subject: 'Código de Login',
93
+ body: `Seu código de login é ${code}`,
94
+ });
95
+ }
96
+
97
+ return {
98
+ name: user.name,
99
+ email: user.email,
100
+ token: this.jwt.sign({
101
+ id: user.id,
102
+ mfa: user.multifactor_id,
103
+ }),
104
+ mfa: true,
105
+ };
106
+ }
107
+ }
108
+
109
+ async getToken(user) {
110
+ delete user.password;
111
+
112
+ const payload = { user };
113
+
114
+ return {
115
+ token: this.jwt.sign(payload),
116
+ };
117
+ }
118
+
119
+ async forget({ email }: ForgetDTO) {
120
+ const appUrl =
121
+ process.env.APP_URL ?? this.configService.get<string>('APP_URL');
122
+
123
+ const user = await this.prisma.user.findFirst({
124
+ where: {
125
+ email,
126
+ },
127
+ select: {
128
+ id: true,
129
+ },
130
+ });
131
+
132
+ if (user) {
133
+ const payload = {
134
+ ...user,
135
+ };
136
+
137
+ const code = this.jwt.sign(payload);
138
+
139
+ await this.prisma.user.update({
140
+ where: {
141
+ id: user.id,
142
+ },
143
+ data: {
144
+ code,
145
+ },
146
+ });
147
+
148
+ await this.mail.send({
149
+ to: email,
150
+ subject: `Recuperação de Senha`,
151
+ body: getForgetPasswordEmail(`${appUrl}/login?mode=reset-password&code=${code}`),
152
+ });
153
+ }
154
+
155
+ return {
156
+ message:
157
+ 'Se este e-mail estiver cadastrado, você receberá instruções para redefinir sua senha.',
158
+ };
159
+ }
160
+
161
+ async changePassword({
162
+ email,
163
+ currentPassword,
164
+ newPassword,
165
+ confirmNewPassword,
166
+ }: ChangeDTO) {
167
+ if (newPassword !== confirmNewPassword) {
168
+ throw new BadRequestException('Senhas não conferem');
169
+ }
170
+
171
+ const user = await this.prisma.user.findFirst({
172
+ where: { email },
173
+ });
174
+
175
+ if (!(await compare(currentPassword, user.password))) {
176
+ throw new NotFoundException('Não foi possível alterar a senha.');
177
+ }
178
+
179
+ const salt = await genSalt();
180
+ const password = await hash(newPassword, salt);
181
+
182
+ const newUser = await this.prisma.user.update({
183
+ where: {
184
+ id: user.id,
185
+ },
186
+ data: {
187
+ password,
188
+ },
189
+ });
190
+
191
+ await this.mail.send({
192
+ to: email,
193
+ subject: `Senha alterada`,
194
+ body: getChangePasswordEmail(),
195
+ });
196
+
197
+ return this.getToken(newUser);
198
+ }
199
+
200
+ async changeEmail({ currentEmail, password, newEmail }: EmailDTO) {
201
+ const user = await this.prisma.user.findFirst({
202
+ where: { email: currentEmail },
203
+ });
204
+
205
+ if (!user) {
206
+ throw new BadRequestException('Não foi possível atualizar o e-mail.');
207
+ }
208
+
209
+ if (!(await compare(password, user.password))) {
210
+ throw new BadRequestException('Não foi possível atualizar o e-mail.');
211
+ }
212
+
213
+ const existingUser = await this.prisma.user.findFirst({
214
+ where: { email: newEmail },
215
+ });
216
+
217
+ if (existingUser) {
218
+ throw new ConflictException('Não foi possível atualizar o e-mail.');
219
+ }
220
+
221
+ const newUser = await this.prisma.user.updateMany({
222
+ where: { email: currentEmail },
223
+ data: { email: newEmail },
224
+ });
225
+
226
+ const personUser = await this.prisma.person_user.findFirst({
227
+ where: { user_id: user.id },
228
+ select: { person_id: true },
229
+ });
230
+
231
+ if (!personUser) {
232
+ throw new NotFoundException('Erro ao atualizar os dados do usuário.');
233
+ }
234
+
235
+ const { id: emailContactTypeId } =
236
+ await this.prisma.person_contact_type.findFirst({
237
+ where: { slug: 'EMAIL' },
238
+ });
239
+
240
+ await this.prisma.person_contact.updateMany({
241
+ where: {
242
+ person_id: personUser.person_id,
243
+ type_id: emailContactTypeId,
244
+ },
245
+ data: { value: newEmail },
246
+ });
247
+
248
+ await this.mail.send({
249
+ to: newEmail,
250
+ subject: `Email alterado`,
251
+ body: getChangeEmailEmail(),
252
+ });
253
+
254
+ return this.getToken(newUser);
255
+ }
256
+
257
+ async resetPassword({ code, newPassword, confirmNewPassword }: ResetDTO) {
258
+ if (newPassword !== confirmNewPassword) {
259
+ throw new BadRequestException('Senhas não conferem');
260
+ }
261
+
262
+ try {
263
+ const decodedCode = this.jwt.decode(code);
264
+
265
+ console.log({ decodedCode });
266
+
267
+ const { id } = decodedCode;
268
+
269
+ const user = await this.prisma.user.findFirst({
270
+ where: {
271
+ id,
272
+ code,
273
+ },
274
+ });
275
+
276
+ if (user) {
277
+ const salt = await genSalt();
278
+ const password = await hash(confirmNewPassword, salt);
279
+
280
+ await this.prisma.user.update({
281
+ where: {
282
+ id: user.id,
283
+ },
284
+ data: {
285
+ password,
286
+ code: null,
287
+ },
288
+ });
289
+
290
+ await this.mail.send({
291
+ to: user.email,
292
+ subject: `Senha recuperada`,
293
+ body: getResetPasswordEmail(),
294
+ });
295
+
296
+ return this.getToken(user);
297
+ }
298
+
299
+ return false;
300
+ } catch (error: any) {
301
+ throw new BadRequestException(
302
+ `Invalid code. ${error?.message ?? String(error)}`,
303
+ );
304
+ }
305
+ }
306
+
307
+ async otp({ token, code }: OtpDTO) {
308
+ const data = this.jwt.decode(token);
309
+
310
+ const user = await this.prisma.user.findFirst({
311
+ where: {
312
+ id: data['id'],
313
+ code: String(code),
314
+ },
315
+ });
316
+
317
+ if (!user) {
318
+ throw new NotFoundException('Código inválido');
319
+ }
320
+
321
+ await this.prisma.user.update({
322
+ where: {
323
+ id: user.id,
324
+ },
325
+ data: {
326
+ code: null,
327
+ },
328
+ });
329
+
330
+ return this.getToken(user);
331
+ }
332
+
333
+ async login({ email, password }: LoginDTO) {
334
+
335
+ await this.mail.send({
336
+ to: email,
337
+ subject: `Novo login no CoinBitClub`,
338
+ body: getUserLoginEmail(),
339
+ });
340
+
341
+ return this.loginWithEmailAndPassword(email, password);
342
+ }
343
+
344
+ async verify(id: number) {
345
+ return this.prisma.user.findUnique({
346
+ where: { id },
347
+ });
348
+ }
349
+ }