# โœ… Final Fixes - Change Password & Resend OTP ## ๐Ÿ› **Issues Fixed:** ### 1. โœ… **Change Password Not Functioning** ### 2. โœ… **Resend OTP Email Error** --- ## ๐Ÿ”ง **Fix 1: Change Password Implementation** ### **Backend Changes:** #### **Added Endpoint** (`auth.controller.ts`): ```typescript @Post('change-password') @UseGuards(JwtAuthGuard) async changePassword( @Req() req: RequestWithUser, @Body() body: { currentPassword: string; newPassword: string }, ) { return this.authService.changePassword( req.user.userId, body.currentPassword, body.newPassword, ); } ``` #### **Added Service Method** (`auth.service.ts`): ```typescript async changePassword( userId: string, currentPassword: string, newPassword: string, ) { // Get user with password hash const user = await this.prisma.user.findUnique({ where: { id: userId }, select: { passwordHash: true }, }); if (!user || !user.passwordHash) { throw new BadRequestException('Cannot change password for this account'); } // Verify current password const isValid = await bcrypt.compare(currentPassword, user.passwordHash); if (!isValid) { throw new UnauthorizedException('Current password is incorrect'); } // Hash new password const newPasswordHash = await bcrypt.hash(newPassword, 10); // Update password await this.prisma.user.update({ where: { id: userId }, data: { passwordHash: newPasswordHash }, }); return { success: true, message: 'Password changed successfully', }; } ``` ### **Frontend Changes:** #### **Added States** (`Profile.tsx`): ```typescript const [currentPassword, setCurrentPassword] = useState("") const [newPassword, setNewPassword] = useState("") const [confirmPassword, setConfirmPassword] = useState("") const [passwordLoading, setPasswordLoading] = useState(false) const [passwordError, setPasswordError] = useState("") const [passwordSuccess, setPasswordSuccess] = useState("") ``` #### **Added Handler**: ```typescript const handleChangePassword = async () => { // Validation if (!currentPassword || !newPassword || !confirmPassword) { setPasswordError("All fields are required") return } if (newPassword !== confirmPassword) { setPasswordError("New passwords do not match") return } if (newPassword.length < 6) { setPasswordError("New password must be at least 6 characters") return } // Call API await axios.post(`${API}/auth/change-password`, { currentPassword, newPassword }) setPasswordSuccess("Password changed successfully!") // Clear fields } ``` #### **Updated UI**: - Connected inputs to state - Added onClick handler to button - Added loading state - Added error/success alerts - Added validation --- ## ๐Ÿ”ง **Fix 2: Resend OTP Email** ### **Problem:** The resend endpoint required a full JWT token, but during OTP verification we only have a temp token. ### **Solution:** Created a special resend endpoint that accepts temp tokens. ### **Backend Changes:** #### **Added Endpoint** (`otp.controller.ts`): ```typescript @Post('email/resend') async resendEmailOtp(@Body() body: { tempToken: string }) { try { // Verify temp token const payload = this.jwtService.verify(body.tempToken); if (!payload.temp) { throw new UnauthorizedException('Invalid token type'); } const userId = payload.userId || payload.sub; // Send OTP return this.otpService.sendEmailOtp(userId); } catch (error) { throw new UnauthorizedException('Invalid or expired token'); } } ``` ### **Frontend Changes:** #### **Updated Resend Handler** (`OtpVerification.tsx`): ```typescript // OLD - Used wrong endpoint await axios.post(`${API_URL}/api/otp/email/send`, {}, { headers: { Authorization: `Bearer ${tempToken}` } }) // NEW - Use resend endpoint with temp token await axios.post(`${API_URL}/api/otp/email/resend`, { tempToken }) ``` --- ## ๐Ÿ“ **Files Modified:** ### Backend: 1. **`apps/api/src/auth/auth.controller.ts`** - Added `change-password` endpoint 2. **`apps/api/src/auth/auth.service.ts`** - Added `changePassword()` method 3. **`apps/api/src/otp/otp.controller.ts`** - Added `email/resend` endpoint - Injected `JwtService` ### Frontend: 1. **`apps/web/src/components/pages/Profile.tsx`** - Added password change states - Added `handleChangePassword()` handler - Updated UI with inputs, validation, alerts 2. **`apps/web/src/components/pages/OtpVerification.tsx`** - Updated `handleResendEmail()` to use new endpoint --- ## ๐Ÿงช **Testing:** ### **Test Change Password:** 1. โœ… Go to Profile page 2. โœ… Enter current password 3. โœ… Enter new password 4. โœ… Confirm new password 5. โœ… Click "Update Password" 6. โœ… See success message 7. โœ… Logout and login with new password ### **Test Resend OTP:** 1. โœ… Login with email OTP enabled 2. โœ… On OTP page, wait 30 seconds 3. โœ… Click "Resend Code" 4. โœ… Check console for new OTP code 5. โœ… Enter new code 6. โœ… Login successfully --- ## โœจ **What Works Now:** โœ… **Change Password**: Full implementation with validation โœ… **Resend OTP**: Works with temp token โœ… **Error Handling**: Proper error messages โœ… **Success Feedback**: Clear success indicators โœ… **Loading States**: Shows loading during operations โœ… **Validation**: Client-side validation before API call --- **Both features are now fully functional! Test them out!** ๐Ÿš€