Skip to content

Commit f8f7e59

Browse files
add verify route and update Login.jsx and Signup.jsx
Add VerifyOTP.jsx and update Login.jsx and SignUp.jsx so that after login and signup, the user navigates to the verify route, and an OTP is sent to the user's email. After entering the OTP, the user will be logged in
1 parent 3fb45d2 commit f8f7e59

File tree

9 files changed

+192
-41
lines changed

9 files changed

+192
-41
lines changed

client/src/App.jsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Navbar from "./Components/Navbar";
1010
import Footer from "./Components/Footer";
1111
import Login from "./Components/Auth/Login";
1212
import Signup from "./Components/Auth/Signup";
13+
import VeifyOTP from "./Components/Auth/VerifyOTP";//for OTP verification
1314
import Syllbus from "./Components/Syllbus/Syllbus";
1415
import SujectInfo from "./Components/SyllbusInfo/SyllbusInfo";
1516
import ProtectedRoutes from "./Pages/ProtectedRoutes";
@@ -97,6 +98,16 @@ function App() {
9798
</>
9899
}
99100
></Route>
101+
{/* Add verify routes to verify otp */}
102+
<Route
103+
path="/verify"
104+
element={
105+
<>
106+
<Navbar />
107+
<VeifyOTP/>
108+
</>
109+
}
110+
/>
100111

101112
{/* Enter routes from here Yash Suthar */}
102113

client/src/Components/Auth/Login.jsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import userImg from "../../assets/images/user.webp";
99
import { toast } from "react-toastify";
1010

1111
const Login = () => {
12-
const cookies = new Cookies();
13-
const { login } = useContext(AuthContext);
12+
// const cookies = new Cookies();
13+
// const { login } = useContext(AuthContext);
1414

1515
const navigate = useNavigate();
1616
const [inputValue, setInputValue] = useState({
@@ -44,20 +44,22 @@ const Login = () => {
4444
}
4545
);
4646

47-
if (response) {
48-
console.log(response.data.token);
49-
login(response.data.token);
47+
// if (response) {
48+
console.log(response.data);
49+
// login(response.data.token);
5050

51-
cookies.set("TOKEN", response.data.token, {
52-
path: "/",
53-
});
54-
}
55-
console.log(cookies.get("TOKEN"));
51+
// cookies.set("TOKEN", response.data.token, {
52+
// path: "/",
53+
// });
54+
// }
55+
// console.log(cookies.get("TOKEN"));
5656

5757
const { success, message } = response.data;
5858

59+
//if user login successfully then navigate to verify page
5960
if (success) {
60-
navigate("/Home");
61+
navigate("/verify", {state: {email: inputValue.email}});
62+
// navigate("/Home");
6163
} else {
6264
alert(message.message);
6365
console.log(message);

client/src/Components/Auth/Signup.jsx

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import userImg from "../../assets/images/user.webp";
88
import { toast } from "react-toastify";
99

1010
const Signup = () => {
11-
const cookies = new Cookies();
12-
const { login } = useContext(AuthContext);
11+
// const cookies = new Cookies();
12+
// const { login } = useContext(AuthContext);
1313
const navigate = useNavigate();
1414
const [inputValue, setInputValue] = useState({
1515
email: "",
@@ -55,21 +55,23 @@ const Signup = () => {
5555
}
5656
);
5757

58-
if (response) {
59-
console.log(response.data.token);
60-
cookies.set("TOKEN", response.data.token, {
61-
path: "/",
62-
});
63-
}
64-
console.log(cookies.get("TOKEN"));
65-
58+
// if (response) {
59+
// cookies.set("TOKEN", response.data.token, {
60+
// path: "/",
61+
// });
62+
// }
63+
// console.log(cookies.get("TOKEN"));
64+
// console.log(response.data);
65+
6666
const { success, message } = response.data;
67+
//if user login successfully then navigate to verify page
6768
if (success) {
68-
login(response.data.token);
69-
cookies.set("TOKEN", response.data.token, {
70-
path: "/",
71-
});
72-
navigate("/Home");
69+
console.log(message)
70+
// login(response.data.token);
71+
// cookies.set("TOKEN", response.data.token, {
72+
// path: "/",
73+
// });
74+
navigate("/verify", {state: {email: inputValue.email}});
7375
} else {
7476
console.log(message);
7577
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import React, { useContext, useEffect, useState } from "react";
2+
import axios from "axios";
3+
import { toast } from "react-toastify";
4+
import Cookies from "universal-cookie";
5+
import { useLocation, useNavigate } from "react-router-dom";
6+
import { AuthContext } from "./AuthContext";
7+
8+
const VerifyOTP = () => {
9+
const cookies = new Cookies();
10+
const location = useLocation();
11+
const navigate = useNavigate();
12+
const { login } = useContext(AuthContext);
13+
const [otpCode, setOtpCode] = useState("");
14+
const [email, setEmail] = useState(null);
15+
16+
//send otp to users email function
17+
const sendEmail = async(email)=>{
18+
try{
19+
const res = await axios.post(
20+
`${import.meta.env.VITE_API_URL}/auth/send-otp`,
21+
{
22+
email: email
23+
}
24+
)
25+
26+
console.log(res)
27+
}
28+
catch(err){
29+
console.log(err);
30+
}
31+
}
32+
33+
34+
useEffect(()=>{
35+
//send otp
36+
async function send(){
37+
//check that it access only after login and signup
38+
if(location.state){
39+
setEmail(location.state.email)
40+
email && sendEmail(email);
41+
}
42+
else{
43+
//
44+
navigate("/", {replace: true});
45+
}
46+
}
47+
send();
48+
},[email])
49+
50+
const handleSubmit = async (e) => {
51+
e.preventDefault();
52+
53+
if (otpCode.length < 6) {
54+
toast.error("Please enter the otp");
55+
return;
56+
}
57+
58+
try {
59+
const res = await axios.post(
60+
`${import.meta.env.VITE_API_URL}/auth/verify-otp`,
61+
{
62+
email,
63+
otpCode
64+
}
65+
);
66+
67+
console.log(res);
68+
69+
const { success, message, token } = res.data;
70+
if (success) {
71+
console.log(message)
72+
login(token);
73+
cookies.set("TOKEN", token, {
74+
path: "/",
75+
});
76+
navigate("/Home");
77+
} else {
78+
console.log(message);
79+
toast.error("Invalid OTP")
80+
}
81+
}
82+
catch (err) {
83+
toast.error("Invalid OTP")
84+
console.log(err)
85+
}
86+
87+
}
88+
89+
return (
90+
<div className="flex flex-col items-center flex-wrap justify-center h-70-vh bg-gray-900">
91+
<h1 className="text-white text-2xl mb-2">Please enter the One-Time Password</h1>
92+
<h2 className="text-white mb-4">A One-Time Password has been sent to {email}</h2>
93+
<input
94+
type="number"
95+
id="otp-code"
96+
onChange={e => setOtpCode(e.target.value.slice(-6))}
97+
value={otpCode}
98+
className="my-6 outline-none hover:appearance-none text-center p-1 text-xl"
99+
/>
100+
<button onClick={handleSubmit} className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center mb-2">
101+
Submit
102+
</button>
103+
</div>
104+
)
105+
}
106+
107+
export default VerifyOTP;

client/src/index.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44
@tailwind components;
55
@tailwind utilities;
66

7+
/* for removing arrow from input field */
8+
@layer base {
9+
input[type="number"]::-webkit-inner-spin-button,
10+
input[type="number"]::-webkit-outer-spin-button {
11+
-webkit-appearance: none;
12+
margin: 0;
13+
}
14+
}
15+
716
@keyframes bounce-slow {
817
0%,
918
100% {

client/tailwind.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ export default {
5858
"Noto Color Emoji",
5959
],
6060
},
61+
height: {
62+
'70-vh': "70vh" //use for making full screen
63+
}
6164
},
6265
},
6366
plugins: ["flowbite/plugin"],

server/.env.example

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
11
TOKEN_KEY=yourSecretKey
22
MONGO_URL=mongodb://127.0.0.1:27017/ElectiveHub
3-
PORT=4000
3+
PORT=4000
4+
5+
6+
OTP_SECRET=9WfKtNpGy3rVm2HlA8QwXc6o1Bd4Zs7E5uJiR
7+
8+
#email variables
9+
EMAIL_HOST=smtp.gmail.com
10+
EMAIL_SERVICE=gmail
11+
EMAIL_POST=587
12+
EMAIL_SECURE=false
13+
USER_EMAIL="add offical email for sending code"
14+
USER_PASS="add password"

server/Controllers/AuthController.js

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ module.exports.Signup = async (req, res, next) => {
1111
if (existingUser) {
1212
return res.json({ message: "User already exists" });
1313
}
14-
const user = await User.create({ email, password, username,role});
14+
15+
//hash password only when new user created
16+
const hashPassword = await bcrypt.hash(password, 12);
17+
const user = await User.create({ email, password:hashPassword, username,role});
1518
res
1619
.status(201)
1720
.json({ message: "User signed in successfully", success: true });
@@ -45,9 +48,10 @@ module.exports.Login = async (req, res, next) => {
4548

4649
module.exports.sendOTP = async(req, res)=>{
4750
try{
48-
const {userId} = req.body;
49-
const user = await User.findById(userId);
51+
const {email} = req.body;
52+
const user = await User.findOne({email});
5053

54+
//generate otp from otplib
5155
const otp = authenticator.generate(process.env.OTP_SECRET);
5256

5357
user.otpToken = otp;
@@ -56,7 +60,7 @@ module.exports.sendOTP = async(req, res)=>{
5660
await user.save();
5761

5862
await sendEmail({
59-
email: user.email,
63+
email: email,
6064
subject: "OTP Verification",
6165
message: `Your One-Time Password(OTP) is: ${otp}`
6266
});
@@ -65,18 +69,18 @@ module.exports.sendOTP = async(req, res)=>{
6569
}
6670
catch(err){
6771
console.error(err);
68-
return res.status(500).json({error: "Something is wrong. Please try after some time."});
72+
return res.status(500).json({error: "Something is wrong. Please try after some time.", success: false});
6973
}
7074
}
7175

7276
module.exports.verifyOTP = async(req, res)=>{
7377
try{
74-
const {userId, otp} = req.body;
75-
const user = await User.findById(userId);
78+
const {email, otpCode} = req.body;
79+
const user = await User.findOne({email});
7680

7781
const currentTime = Date.now();
7882
//check otp is valid or not
79-
if(otp !== user.otpToken || currentTime > user.optExpiry){
83+
if(otpCode !== user.otpToken || currentTime > user.optExpiry){
8084
return res.status(400).json({error: "Invalid OTP"});
8185
}
8286

@@ -87,10 +91,10 @@ module.exports.verifyOTP = async(req, res)=>{
8791
});
8892
res
8993
.status(200)
90-
.json({ message: "OTP verified", success: true, token });
94+
.json({ message: "OTP verified", success: true, token: token });
9195
}
9296
catch(err){
9397
console.error(err);
94-
return res.status(500).json({error: "Something is wrong. Please try after some time."})
98+
return res.status(500).json({error: "Something is wrong. Please try after some time.", success: false})
9599
}
96100
}

server/Models/UserModel.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@ const userSchema = new mongoose.Schema({
3333
},
3434
});
3535

36-
userSchema.pre("save", async function (next) {
37-
this.password = await bcrypt.hash(this.password, 12);
38-
next()
39-
});
36+
//Its change password every time
37+
38+
// userSchema.pre("save", async function (next) {
39+
// this.password = await bcrypt.hash(this.password, 12);
40+
// next()
41+
// });
4042

4143

4244

0 commit comments

Comments
 (0)