From b108eb35a2a9a498b18dd82e2bbd478c2e7f1907 Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Wed, 8 Apr 2026 10:32:35 +0530 Subject: [PATCH] feat: add public endpoint to resend user verification email by email address --- src/auth/auth.controller.ts | 22 ++++++++++++++++++++++ src/auth/auth.service.ts | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts index 8998688..37cc1bd 100644 --- a/src/auth/auth.controller.ts +++ b/src/auth/auth.controller.ts @@ -282,6 +282,28 @@ export class AuthController { return this.authService.resendVerificationEmail(userId); } + // ========================================== + // RESEND VERIFICATION EMAIL BY EMAIL (PUBLIC) + // ========================================== + @Public() + @Post('resend-verification-public') + @HttpCode(HttpStatus.OK) + @ApiOperation({ summary: 'Resend verification email (public, by email)' }) + @ApiBody({ + schema: { + type: 'object', + properties: { email: { type: 'string', example: 'user@example.com' } }, + required: ['email'], + }, + }) + @ApiResponse({ status: 200, description: 'If account exists, verification email sent' }) + async resendVerificationPublic(@Body() body: { email: string }) { + if (!body?.email) { + return { message: 'Email is required' }; + } + return this.authService.resendVerificationByEmail(body.email); + } + // ========================================== // REFRESH TOKEN // ========================================== diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index 214db94..914e23b 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -620,6 +620,41 @@ export class AuthService { }; } + // ========================================== + // RESEND VERIFICATION EMAIL BY EMAIL (PUBLIC) + // ========================================== + async resendVerificationByEmail(email: string) { + // Always return success to prevent email enumeration attacks + const successResponse = { + message: 'If an account with this email exists and is not yet verified, a verification email has been sent.', + }; + + const user = await this.prisma.user.findUnique({ + where: { email: email.toLowerCase() }, + include: { + userProfile: true, + agentProfile: true, + }, + }); + + if (!user || user.emailVerified) { + return successResponse; + } + + const profile = user.role === UserRole.AGENT ? user.agentProfile : user.userProfile; + + // Emit event for email service to send verification + this.eventEmitter.emit('user.registered', { + userId: user.id, + email: user.email, + role: user.role, + firstName: profile?.firstName, + lastName: profile?.lastName, + }); + + return successResponse; + } + // ========================================== // REFRESH TOKEN // ==========================================