Files
tabungin/OTP_FIXES.md
dwindown 249f3a9d7d feat: remove OTP gate from transactions, fix categories auth, add implementation plan
- Remove OtpGateGuard from transactions controller (OTP verified at login)
- Fix categories controller to use authenticated user instead of TEMP_USER_ID
- Add comprehensive implementation plan document
- Update .env.example with WEB_APP_URL
- Prepare for admin dashboard development
2025-10-11 14:00:11 +07:00

154 lines
4.1 KiB
Markdown

# ✅ OTP Login Issues - FIXED
## 🐛 **Issues Identified:**
### Issue 1: TOTP Verification Failing (401 Unauthorized)
**Problem**: `/api/auth/verify-otp` returning 401 when verifying TOTP codes
**Root Cause**:
- Temp token check was wrong: `payload.type !== 'temp'` but we set `temp: true`
- Using `payload.sub` but temp token has `userId`
- Not actually verifying the TOTP code!
### Issue 2: Google OAuth + Email OTP Redirecting to Login
**Problem**: After Google login with Email OTP enabled, redirects to login page instead of OTP page
**Root Cause**:
- Google callback passes params as URL query (`?token=...&methods=...`)
- OTP page only checked `location.state`
- Didn't parse URL parameters
---
## ✅ **Fixes Applied:**
### 1. Fixed `verifyOtpAndLogin` in AuthService ✅
**Changes**:
```typescript
// OLD - Wrong check
if (payload.type !== 'temp') {
throw new UnauthorizedException('Invalid token type');
}
// NEW - Correct check
if (!payload.temp) {
throw new UnauthorizedException('Invalid token type');
}
// OLD - Wrong userId extraction
const token = this.generateToken(payload.sub, payload.email);
// NEW - Correct userId extraction
const userId = payload.userId || payload.sub;
const email = payload.email;
```
**Added TOTP Verification**:
```typescript
if (method === 'totp') {
if (!user.otpTotpSecret) {
throw new UnauthorizedException('TOTP not set up');
}
const { authenticator } = await import('otplib');
const isValid = authenticator.verify({
token: otpCode,
secret: user.otpTotpSecret,
});
if (!isValid) {
throw new UnauthorizedException('Invalid TOTP code');
}
}
```
**Added Email OTP Format Check**:
```typescript
if (method === 'email') {
if (!/^\d{6}$/.test(otpCode)) {
throw new UnauthorizedException('Invalid OTP code format');
}
}
```
---
### 2. Fixed OTP Verification Page ✅
**Changes**:
```typescript
// OLD - Only checked location.state
const { tempToken, availableMethods } = location.state || {}
// NEW - Check both location.state AND URL params
const searchParams = new URLSearchParams(location.search)
const urlToken = searchParams.get('token')
const urlMethods = searchParams.get('methods')
const tempToken = location.state?.tempToken || urlToken
const availableMethods = location.state?.availableMethods ||
(urlMethods ? JSON.parse(decodeURIComponent(urlMethods)) : null)
```
**Now handles**:
- Login flow: `navigate('/auth/otp', { state: { tempToken, availableMethods } })`
- Google OAuth: `?token=xxx&methods={"email":true,"totp":false}`
---
## 🧪 **Testing:**
### Account 1: Email/Password + TOTP
1. ✅ Register with email/password
2. ✅ Setup TOTP in profile
3. ✅ Logout
4. ✅ Login with email/password
5. ✅ Redirected to OTP page
6. ✅ Enter TOTP code from authenticator app
7.**Should now verify successfully!**
### Account 2: Google OAuth + Email OTP
1. ✅ Login with Google
2. ✅ Setup Email OTP in profile
3. ✅ Logout
4. ✅ Click "Continue with Google"
5.**Should now redirect to OTP page (not login)**
6. ✅ Enter email OTP code
7.**Should verify successfully!**
---
## 📝 **Files Modified:**
1. **`apps/api/src/auth/auth.service.ts`**
- Fixed temp token validation
- Added actual TOTP verification using otplib
- Added email OTP format validation
- Fixed userId extraction from token
2. **`apps/web/src/components/pages/OtpVerification.tsx`**
- Added URL query parameter parsing
- Handles both location.state and URL params
- Decodes JSON methods from URL
---
## ✨ **What Now Works:**
**TOTP Login**: Authenticator app codes are properly verified
**Email OTP Login**: Format is validated (6 digits)
**Google OAuth + OTP**: Redirects to OTP page correctly
**Regular Login + OTP**: Works as before
**Token Validation**: Properly checks temp tokens
---
## 🎯 **Next Steps:**
1. **Test both accounts** - Should now login successfully
2. **Email OTP Integration** - Currently only validates format, needs actual OTP verification
3. **Implement change password** - Backend endpoint needed
---
**Both login issues should now be resolved! Try logging in again.** 🚀