added emailService.js that successfully sends otp and added a couple of routes to manage it #1
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR corrects the forgot password feature, which previously behaved like a change password flow. It introduces an OTP-first reset flow across both backend and frontend. Users now receive a 6-digit code via email (sent via Nodemailer/Gmail App Password), verify it, and then receive a short-lived reset token to set a new password.
What I Changed
Backend
Fixed forgot password route to generate and email a 6-digit OTP instead of immediately allowing password change.
Integrated Nodemailer to send OTP using Gmail App Passwords (2FA-compatible).
Added backend OTP verification endpoint (POST /auth/password/verify-otp) to return reset token on successful verification.
Updated data model to store OTP metadata (hashed OTP, expiry, attempt limits).
Preserved existing secure token-based reset after OTP verification.
Frontend
src/pages/ForgotPassword.jsx:
Updated UI to request OTP after email submission.
Added OTP input form with verification step.
On success, navigates to /reset-password/:token.
src/utils/apiConfig.js: Added VERIFY_OTP endpoint.
API Overview
POST /auth/password/forgot → sends OTP to user’s email.
POST /auth/password/verify-otp → validates OTP, returns { resetToken }.
POST /auth/password/reset/:token → sets new password.
Environment Variables (.env)
EMAIL_USER → Gmail address used for sending OTP.
EMAIL_PASS → Gmail App Password (generated with 2FA).
.env must not be committed.
How to Test
Go to /forgot-password.
Enter registered email → click Send Code.
Check inbox for OTP.
Enter OTP → verify → redirected to /reset-password/:token.
Set new password → confirm login works.
Error cases to test:
Wrong OTP → 400 error.
Expired OTP (~10 mins) → 400 error.
Too many failed attempts → 429 error.
This is the structure of .env below
Server
PORT=7777
Database
MONGODB_STRING=mongodb+srv://:@/?retryWrites=true&w=majority
Cross-app URL (used to construct reset URL if needed)
FRONTEND_URL=http://localhost:5173
Email (Gmail recommended with App Password)
EMAIL_USER=your.email@gmail.com
EMAIL_PASS=your_gmail_app_password # 16-char App Password from Google
EMAIL_FROM="DevTinder your.email@gmail.com"
(Follow-up recommended) JWT secret for tokens, to replace hardcoded value in user model
JWT_SECRET=change_this_to_a_long_random_secret
NOTE
How to set EMAIL_PASS using Gmail 2FA (App Password)
Enable 2‑Step Verification on your Google account.
Go to Google Account → Security → “App passwords”.
Create a new app password:
App: Mail
Device: Other (or pick an available device)
Google will show a 16‑character app password. Copy it.
Paste it into .env as EMAIL_PASS.
EMAIL_USER should be the same Gmail address.
Keep both values secret; do not commit .env.