# โœ… Email OTP Sending During Login - FIXED ## ๐Ÿ› **Problem:** Email OTP was not being sent during login flow. It only worked when manually requested from the profile page. **Symptoms**: - User logs in with email/password (has email OTP enabled) - Redirected to OTP page - No email received - Console shows no OTP code - User stuck on OTP page --- ## โœ… **Root Cause:** The login flow was checking if OTP was required and returning a temp token, but **never actually sending the email OTP**! ```typescript // OLD CODE - No email sent! if (requiresOtp) { return { requiresOtp: true, availableMethods: { email: user.otpEmailEnabled, totp: user.otpTotpEnabled, }, tempToken: this.generateTempToken(user.id, user.email), }; } ``` --- ## โœ… **Fixes Applied:** ### 1. **Injected OtpService into AuthService** โœ… ```typescript // auth.module.ts imports: [ PrismaModule, PassportModule, forwardRef(() => OtpModule), // Added OtpModule JwtModule.register({...}), ], // auth.service.ts constructor( private readonly prisma: PrismaService, private readonly jwtService: JwtService, @Inject(forwardRef(() => OtpService)) // Injected OtpService private readonly otpService: OtpService, ) {} ``` ### 2. **Send Email OTP During Login** โœ… ```typescript // In login() method if (requiresOtp) { // Send email OTP if enabled if (user.otpEmailEnabled) { try { await this.otpService.sendEmailOtp(user.id); // โ† SEND EMAIL! } catch (error) { console.error('Failed to send email OTP during login:', error); // Continue anyway - user can request resend } } return { requiresOtp: true, availableMethods: { email: user.otpEmailEnabled, totp: user.otpTotpEnabled, }, tempToken: this.generateTempToken(user.id, user.email), }; } ``` ### 3. **Send Email OTP During Google Login** โœ… ```typescript // In googleLogin() method if (requiresOtp) { // Send email OTP if enabled if (user.otpEmailEnabled) { try { await this.otpService.sendEmailOtp(user.id); // โ† SEND EMAIL! } catch (error) { console.error('Failed to send email OTP during Google login:', error); } } return { requiresOtp: true, availableMethods: {...}, tempToken: this.generateTempToken(user.id, user.email), }; } ``` ### 4. **Added Separate Verification Method** โœ… Created `verifyEmailOtpForLogin()` that verifies the code without enabling the feature: ```typescript // otp.service.ts async verifyEmailOtpForLogin(userId: string, code: string): Promise { const stored = this.emailOtpStore.get(userId); if (!stored || new Date() > stored.expiresAt || stored.code !== code) { return false; } this.emailOtpStore.delete(userId); return true; } ``` ### 5. **Updated Login Verification** โœ… ```typescript // In verifyOtpAndLogin() method if (method === 'email') { const isValid = await this.otpService.verifyEmailOtpForLogin(userId, otpCode); if (!isValid) { throw new UnauthorizedException('Invalid or expired email OTP code'); } } ``` --- ## ๐Ÿ“ **Files Modified:** 1. **`apps/api/src/auth/auth.module.ts`** - Added `forwardRef(() => OtpModule)` to imports 2. **`apps/api/src/auth/auth.service.ts`** - Injected `OtpService` - Send email OTP in `login()` method - Send email OTP in `googleLogin()` method - Use `verifyEmailOtpForLogin()` for verification 3. **`apps/api/src/otp/otp.service.ts`** - Added `verifyEmailOtpForLogin()` method - Keeps existing `verifyEmailOtp()` for setup --- ## ๐Ÿงช **Testing:** ### Test Email/Password Login with Email OTP: 1. โœ… Login with email/password 2. โœ… **Email OTP should be sent automatically** 3. โœ… Check console for: `๐Ÿ“ง OTP Code for user@example.com: 123456` 4. โœ… Enter code on OTP page 5. โœ… Should login successfully ### Test Google Login with Email OTP: 1. โœ… Click "Continue with Google" 2. โœ… Authenticate 3. โœ… **Email OTP should be sent automatically** 4. โœ… Redirected to OTP page 5. โœ… Check console for OTP code 6. โœ… Enter code 7. โœ… Should login successfully --- ## โœจ **What Now Works:** โœ… **Email OTP sent during login** - Automatically when user has it enabled โœ… **Email OTP sent during Google OAuth** - Works for both flows โœ… **Proper verification** - Uses dedicated login verification method โœ… **Console logging** - Shows OTP code in development โœ… **Webhook integration** - Sends to n8n if configured --- ## ๐ŸŽฏ **Expected Behavior:** 1. User logs in (email/password or Google) 2. If email OTP enabled: - Email is sent automatically - Console shows: `๐Ÿ“ง OTP Code for user@example.com: 123456` - User redirected to OTP page 3. User enters code 4. Code verified 5. User logged in successfully **Email OTP should now work during login! Test it now!** ๐Ÿš€