Feature/api 9/email validation resend#31
Conversation
| @@ -0,0 +1,82 @@ | |||
| import { | |||
There was a problem hiding this comment.
movamos todo lo del modulo de email-template al modulo email
| import { EmailTemplate } from './entities/email-template.entity'; | ||
|
|
||
| @ApiTags('Email Templates') | ||
| @Controller('email-templates') |
There was a problem hiding this comment.
Cuando lo muevas al controlador cada endpoint le pones template en singular
| @Post() | ||
| @ApiOperation({ summary: 'Create an email template' }) | ||
| @ApiResponse({ | ||
| status: 201, | ||
| description: 'Template created successfully', | ||
| type: EmailTemplate, | ||
| }) | ||
| async create( | ||
| @Body() createTemplateDto: { name: string; html: string }, | ||
| ): Promise<EmailTemplate> { | ||
| return await this.emailTemplateService.create(createTemplateDto); | ||
| } |
There was a problem hiding this comment.
Recuerda que este endpoint debe pedir authorization con el guard Access Token, ademas verificar que solo los admin puedan crear un template
| @Get() | ||
| @ApiOperation({ summary: 'Get all email templates' }) | ||
| @ApiResponse({ | ||
| status: 200, | ||
| description: 'List of templates', | ||
| type: [EmailTemplate], | ||
| }) | ||
| async findAll(): Promise<EmailTemplate[]> { | ||
| return await this.emailTemplateService.findAll(); | ||
| } | ||
|
|
||
| @Get(':name') | ||
| @ApiOperation({ summary: 'Get a template by name' }) | ||
| @ApiResponse({ | ||
| status: 200, | ||
| description: 'Template found', | ||
| type: EmailTemplate, | ||
| }) | ||
| @ApiNotFoundResponse({ description: 'Template not found' }) | ||
| async findByName(@Param('name') name: string): Promise<EmailTemplate> { | ||
| return await this.emailTemplateService.findByName(name); | ||
| } | ||
|
|
||
| @Put(':id') | ||
| @ApiOperation({ summary: 'Update an email template' }) | ||
| @ApiResponse({ | ||
| status: 200, | ||
| description: 'Updated template', | ||
| type: EmailTemplate, | ||
| }) | ||
| async update( | ||
| @Param('id') id: string, | ||
| @Body() updateData: Partial<EmailTemplate>, | ||
| ): Promise<EmailTemplate> { | ||
| return await this.emailTemplateService.update(id, updateData); | ||
| } | ||
|
|
||
| @Delete(':id') | ||
| @HttpCode(204) | ||
| @ApiOperation({ summary: 'Delete an email template' }) | ||
| @ApiResponse({ status: 204, description: 'Template removed' }) | ||
| async remove(@Param('id') id: string): Promise<void> { | ||
| return await this.emailTemplateService.remove(id); | ||
| } |
There was a problem hiding this comment.
Igual todos estos endpoints deben pedit authorization y validar que un admin pueda usarlos, cuando el que hace el request es un customer o un delivery debe retornar un error 403 que significa que esta autenticado pero no tiene permiso
| @PrimaryGeneratedColumn('uuid') | ||
| @ApiProperty({ | ||
| description: 'ID del template', | ||
| example: '123e4567-e89b-12d3-a456-426614174000', | ||
| }) | ||
| id: string; |
| @Post(':userId/validate') | ||
| @ApiOperation({ summary: 'Validate OTP to verify email' }) | ||
| @ApiResponse({ status: 204, description: 'OTP validated successfully' }) | ||
| @ApiResponse({ status: 400, description: 'OTP code has expired' }) | ||
| @ApiResponse({ status: 404, description: 'Invalid or not found OTP code' }) | ||
| async validateEmail( | ||
| @Param('userId') userId: string, | ||
| @Body() otpDto: OtpDTO, | ||
| ): Promise<void> { | ||
| await this.userService.validateEmail(userId, otpDto); | ||
| } |
There was a problem hiding this comment.
Este endpoint tambien debe estar protegido, se debe validar es al usuario que hace la peticion, que coincida el user con el que esta relacionado con el otp para validarlo. Renombremos este endpoint para que sea solo POST /user/otp
| async validateEmail(userId: string, otpDto: OtpDTO): Promise<void> { | ||
| const { otp } = otpDto; | ||
|
|
||
| const userOtp = await this.userOTPRepository.findOne({ | ||
| where: { user: { id: userId }, code: otp }, | ||
| relations: ['user'], | ||
| }); | ||
|
|
||
| if (!userOtp) { | ||
| throw new NotFoundException('Invalid or not found OTP code'); | ||
| } | ||
| if (userOtp.expiresAt < new Date()) { | ||
| throw new BadRequestException('OTP code has expired'); | ||
| } | ||
| await this.userRepository.update(userId, { isValidated: true }); | ||
| await this.userOTPRepository.remove(userOtp); | ||
| } |
There was a problem hiding this comment.
Este metodo realiza demasiadas funciones, apliquemos el principio de single responsability. El controlador se debe encargar de buscar el userOtp llamando al metodo findOne y realizar la validacion de no encontrar al otp. Este metodo validateEmail debe recibir la entidad del userOtp, verificar la fecha y realizar el update del usuario y eliminar el otp
andres15alvarez
left a comment
There was a problem hiding this comment.
buenisimo el ajuste Eliza, el crear el decorador para validar el rol 1000/10
No description provided.