-
Notifications
You must be signed in to change notification settings - Fork 125
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
465 additions
and
221 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,17 @@ | ||
import User from '../models/User.js'; | ||
import crypto from 'crypto'; // For generating OTP | ||
import nodemailer from 'nodemailer'; | ||
import { hashPassword, comparePassword, generateToken, verifyToken, addCookie, getCookies, removeCookie } from '../utils/authFunctions.js'; | ||
|
||
|
||
const transporter = nodemailer.createTransport({ | ||
service: 'gmail', | ||
auth: { | ||
user: process.env.EMAIL_USER, | ||
pass: process.env.EMAIL_PASS, | ||
}, | ||
}); | ||
|
||
export const registerUser = async (req, res) => { | ||
try { | ||
const { name, email, phoneNumber, password, isGoogle } = req.body; | ||
|
@@ -19,45 +30,111 @@ export const registerUser = async (req, res) => { | |
return res.status(400).json({ error: 'User already exists' }); | ||
} | ||
|
||
const otp = crypto.randomInt(100000, 999999).toString(); // Generate OTP (6 digits) | ||
|
||
if (isGoogle == true) { | ||
const newUser = new User({ | ||
name, | ||
email, | ||
phoneNumber: phoneNumber ? phoneNumber : '', | ||
password: '' | ||
password: '', | ||
otp: otp, | ||
otpExpiry: Date.now() + 3600000, // OTP expires in 1 hour | ||
}); | ||
|
||
await newUser.save(); | ||
|
||
const token = await generateToken(newUser._id); | ||
await sendOtpEmail(email, otp); // Send OTP to the user's email | ||
|
||
const token = await generateToken(newUser._id); | ||
addCookie(res, 'token', token); | ||
|
||
return res.status(201).json({ message: 'User registered successfully', userId: newUser._id , token: token }); | ||
return res.status(201).json({ | ||
message: 'User registered successfully. Please check your email for the OTP to verify your email.', | ||
userId: newUser._id, | ||
token: token, | ||
}); | ||
} else { | ||
const hashedPassword = await hashPassword(password); | ||
|
||
const newUser = new User({ | ||
name, | ||
email, | ||
phoneNumber: phoneNumber ? phoneNumber : '', | ||
password: hashedPassword | ||
password: hashedPassword, | ||
otp: otp, | ||
otpExpiry: Date.now() + 3600000, // OTP expires in 1 hour | ||
}); | ||
|
||
await newUser.save(); | ||
|
||
const token = await generateToken(newUser._id); | ||
await sendOtpEmail(email, otp); // Send OTP to the user's email | ||
|
||
const token = await generateToken(newUser._id); | ||
addCookie(res, 'token', token); | ||
|
||
res.status(201).json({ message: 'User registered successfully', userId: newUser._id, token: token }); | ||
res.status(201).json({ | ||
message: 'User registered successfully. Please check your email for the OTP to verify your email.', | ||
userId: newUser._id, | ||
token: token, | ||
}); | ||
} | ||
} catch (error) { | ||
console.error(error); | ||
res.status(500).json({ error: error.message || 'Internal Server Error' }); | ||
} | ||
}; | ||
|
||
const sendOtpEmail = async (userEmail, otp) => { | ||
try { | ||
|
||
const mailOptions = { | ||
from: process.env.EMAIL_USER, | ||
to: userEmail, | ||
subject: 'Email Verification - Station Sarthi', | ||
text: `Your OTP for email verification is: ${otp}`, | ||
}; | ||
|
||
await transporter.sendMail(mailOptions); | ||
} catch (error) { | ||
console.error('Error sending email:', error); | ||
throw new Error('Failed to send OTP'); | ||
} | ||
}; | ||
|
||
export const verifyOtp = async (req, res) => { | ||
try { | ||
const { email, otp } = req.body; | ||
|
||
const user = await User.findOne({ email }); | ||
if (!user) { | ||
return res.status(404).json({ error: 'User not found' }); | ||
} | ||
|
||
// Check if OTP has expired | ||
if (Date.now() > user.otpExpiry) { | ||
return res.status(400).json({ error: 'OTP has expired' }); | ||
} | ||
|
||
// Check if OTP is correct | ||
if (user.otp !== otp) { | ||
return res.status(400).json({ error: 'Invalid OTP' }); | ||
} | ||
|
||
// OTP is correct, mark user as verified | ||
user.isVerified = true; | ||
user.otp = null; // Clear OTP after verification | ||
user.otpExpiry = null; // Clear OTP expiry after verification | ||
await user.save(); | ||
|
||
res.status(200).json({ message: 'Email verified successfully' }); | ||
} catch (error) { | ||
console.error(error); | ||
res.status(500).json({ error: error.message || 'Internal Server Error' }); | ||
} | ||
}; | ||
|
||
|
||
export const loginUser = async (req, res) => { | ||
try { | ||
const { email, password } = req.body; | ||
|
@@ -90,6 +167,77 @@ export const loginUser = async (req, res) => { | |
} | ||
}; | ||
|
||
async function sendResetOtpEmail(email, otp) { | ||
await transporter.sendMail({ | ||
from: 'Station Sarthi <[email protected]>', | ||
to: email, | ||
subject: 'Password Reset OTP - Station Sarti', | ||
text: `Your OTP for password reset is ${otp}. It will expire in 1 hour.` | ||
}); | ||
} | ||
|
||
// Route 1: Request Password Reset (Sends OTP) | ||
export const requestPasswordReset = async (req, res) => { | ||
try { | ||
const { email } = req.body; | ||
|
||
if (!email) { | ||
return res.status(400).json({ error: 'Email is required' }); | ||
} | ||
|
||
const user = await User.findOne({ email }); | ||
|
||
if (!user) { | ||
return res.status(400).json({ error: 'User with this email does not exist' }); | ||
} | ||
|
||
const otp = crypto.randomInt(100000, 999999).toString(); // Generate OTP | ||
user.otp = otp; | ||
user.otpExpiry = Date.now() + 3600000; // OTP expires in 1 hour | ||
await user.save(); | ||
|
||
await sendResetOtpEmail(email, otp); | ||
|
||
res.status(200).json({ message: 'OTP sent to email for password reset' }); | ||
} catch (error) { | ||
console.error(error); | ||
res.status(500).json({ error: error.message || 'Internal Server Error' }); | ||
} | ||
}; | ||
|
||
// Route 2: Verify OTP and Reset Password | ||
export const resetPassword = async (req, res) => { | ||
try { | ||
const { email, otp, newPassword } = req.body; | ||
|
||
if (!email || !otp || !newPassword) { | ||
return res.status(400).json({ error: 'Email, OTP, and new password are required' }); | ||
} | ||
|
||
const user = await User.findOne({ email }); | ||
|
||
if (!user) { | ||
return res.status(400).json({ error: 'User does not exist' }); | ||
} | ||
|
||
// Check if OTP is valid | ||
if (user.otp !== otp || user.otpExpiry < Date.now()) { | ||
return res.status(400).json({ error: 'Invalid or expired OTP' }); | ||
} | ||
|
||
// Hash the new password and reset OTP fields | ||
user.password = await hashPassword(newPassword); | ||
user.otp = null; | ||
user.otpExpiry = null; | ||
await user.save(); | ||
|
||
res.status(200).json({ message: 'Password has been reset successfully' }); | ||
} catch (error) { | ||
console.error(error); | ||
res.status(500).json({ error: error.message || 'Internal Server Error' }); | ||
} | ||
}; | ||
|
||
export const logoutUser = async (req, res) => { | ||
try { | ||
removeCookie(res, 'token'); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import mongoose from 'mongoose'; | ||
const contactUsSchema = new mongoose.Schema( | ||
{ | ||
mail: { | ||
type: String, | ||
required: true, | ||
match: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, // Email format validation | ||
}, | ||
subject: { | ||
type: String, | ||
required: true, | ||
}, | ||
message: { | ||
type: String, | ||
required: true, | ||
}, | ||
dateSubmitted: { | ||
type: Date, | ||
default: Date.now, // Automatically set the current date when the form is submitted | ||
}, | ||
}, | ||
{ timestamps: true } // Automatically add createdAt and updatedAt fields | ||
); | ||
|
||
// Create a model based on the schema | ||
const ContactUs = mongoose.model('Contact', contactUsSchema); | ||
|
||
|
||
export default ContactUs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
import express from 'express'; | ||
const router = express.Router(); | ||
import { createContactUs } from "../controllers/contactusController.js"; | ||
import { createContactUs} from "../controllers/contactusController.js"; | ||
|
||
router.post("/contactus", createContactUs); | ||
|
||
export default router; |
Oops, something went wrong.