4.1 KiB
4.1 KiB
Microsoft OAuth Token Management - Fixes Applied
Issues Fixed
✅ Fix #1: Refresh Tokens Now Persisted to Prisma Database
Problem: Refresh tokens were only stored in Redis (24-hour TTL), risking permanent loss.
Solution:
- Refresh tokens are now saved to
MailCredentials.refresh_tokenin Prisma - Access tokens and expiry also persisted to database
- Database acts as source of truth for long-term token storage
Files Modified:
lib/services/email-service.ts-saveUserEmailCredentials()now saves OAuth tokens to Prisma
✅ Fix #2: Database Updated on Token Refresh
Problem: When tokens were refreshed, only Redis was updated, leaving database stale.
Solution:
- Token refresh now updates both Redis AND Prisma
- New refresh tokens (if provided by Microsoft) are persisted
- Token expiry timestamp updated in database
Files Modified:
lib/services/token-refresh.ts-ensureFreshToken()now updates Prisma after refresh
✅ Fix #3: Fallback to Database if Redis Missing
Problem: If Redis cache was empty, system couldn't recover refresh tokens.
Solution:
- If Redis cache miss, system checks Prisma database
- Retrieves refresh token from database
- Re-populates Redis cache for future use
Files Modified:
lib/services/token-refresh.ts- Added database fallback logic
✅ Fix #4: OAuth Fields Retrieved from Database
Problem: When loading credentials from database, OAuth fields were ignored.
Solution:
- Database queries now include OAuth fields (
access_token,refresh_token,token_expiry,use_oauth) - Credentials object properly populated with OAuth data from database
Files Modified:
lib/services/email-service.ts-getImapConnection()now includes OAuth fields from database
Token Storage Strategy (Current)
Access Tokens
- Primary: Redis (fast access, 24-hour TTL)
- Backup: Prisma Database (persisted)
- Lifespan: ~1 hour (Microsoft default)
Refresh Tokens
- Primary: Prisma Database (persistent, long-term)
- Cache: Redis (24-hour TTL, for fast access)
- Lifespan: Up to 90 days (with
offline_accessscope)
Token Expiry
- Storage: Both Redis and Prisma
- Purpose: Determine when to refresh tokens
Long-Term Viability
✅ NOW VIABLE for Production
Improvements:
- ✅ Refresh tokens persisted to database
- ✅ Database updated on token refresh
- ✅ Fallback mechanism if Redis fails
- ✅ No data loss on Redis restart
- ✅ Recovery mechanism in place
What Happens Now
When Adding Microsoft Account:
- OAuth tokens saved to both Redis and Prisma
- Refresh token stored in database for long-term access
- Access token cached in Redis for fast retrieval
When Token Expires:
- System checks Redis first (fast path)
- If Redis miss, checks Prisma database (fallback)
- Uses refresh token to get new access token
- Updates both Redis and Prisma with new tokens
- Continues normal operation
If Redis is Cleared:
- System detects Redis cache miss
- Retrieves refresh token from Prisma database
- Gets new access token using refresh token
- Re-populates Redis cache
- No user action required ✅
Testing Recommendations
-
Test Token Refresh:
- Wait for access token to expire (~1 hour)
- Verify system automatically refreshes
- Check both Redis and Prisma are updated
-
Test Redis Failure:
- Clear Redis cache
- Try to access email
- Verify system recovers from database
-
Test Long-Term Access:
- Wait several days
- Verify refresh token still works
- Check no re-authentication required
Monitoring
Watch for these log messages:
- ✅
Token for ${email} persisted to Prisma database- Token saved successfully - ✅
Recovered credentials from Prisma and cached in Redis- Fallback working - ⚠️
Error persisting tokens to database- Database update failed (check logs)
Next Steps
- Monitor: Watch logs for token refresh operations
- Verify: Check Prisma database has
refresh_tokenvalues - Test: Verify email access works after Redis restart
- Optional: Consider encrypting tokens at rest (if compliance requires)