Skip to content

Commit 715bcf7

Browse files
authored
Merge pull request #2680 from codervivek5/backend
Bug: Update login with google
2 parents 8cd38db + 1175a26 commit 715bcf7

File tree

7 files changed

+216
-153
lines changed

7 files changed

+216
-153
lines changed

backend/routes/ContactRoute.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { createTransport } from 'nodemailer';
44
import { json as _json, urlencoded as _urlencoded } from 'body-parser';
55
import { send } from 'vite';
66
const app = express();
7-
const PORT = process.env.PORT || 3001;
7+
const PORT = process.env.PORT || 3000;
88

99
//Middleware to parse JSON bodies
1010
app.use(_json());
@@ -53,6 +53,8 @@ app.post('/send-email', async (req, res) => {
5353

5454
// Start server
5555
app.listen(PORT, () => {
56-
console.log(`Server is running on http://localhost:${PORT}`);
56+
const serverAddress = process.env.SERVER_URL || `http://localhost:${PORT}`;
57+
58+
console.log(`🚀 Server is live and running on: ${serverAddress}`);
5759
});
5860

backend/routes/authRoutes.js

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,65 @@
11
const express = require("express");
22
const router = express.Router();
33
const passport = require("passport");
4+
const jwt = require("jsonwebtoken");
45
const authController = require("../controllers/authController.js");
56

7+
// HIGHLIGHT: .env file se secret aur expiry time load karein
8+
const ACCESS_TOKEN_SECRET = process.env.ACCESS_TOKEN_SECRET;
9+
const ACCESS_TOKEN_EXPIRES = process.env.ACCESS_TOKEN_EXPIRES;
10+
11+
// --- Standard Auth Routes ---
12+
router.post("/signup", authController.signup);
13+
router.post("/login", authController.login);
14+
router.post("/send-otp", authController.otp);
15+
router.post("/verify-otp", authController.verifyOtp);
16+
17+
// --- Google OAuth Routes ---
618
router.get(
719
"/google",
20+
821
passport.authenticate("google", {
922
scope: ["profile", "email"],
1023
})
1124
);
1225

1326
router.get(
1427
"/google/callback",
15-
passport.authenticate("google", { failureRedirect: "/login" }),
28+
passport.authenticate("google", {
29+
failureRedirect: "https://vigy-bag.vercel.app/login",
30+
session: false,
31+
}),
1632
(req, res) => {
17-
const email = req.user.email;
33+
// HIGHLIGHT: DEBUGGING KE LIYE LOGS ADD KIYE GAYE HAIN
34+
console.log("\n✅ [Google Callback] Route hit successfully.");
35+
console.log("👤 Google user authenticated:", req.user?._id);
36+
37+
const payload = {
38+
sub: req.user._id,
39+
role: req.user.role || 0,
40+
};
41+
42+
const accessToken = jwt.sign(payload, ACCESS_TOKEN_SECRET, {
43+
expiresIn: ACCESS_TOKEN_EXPIRES,
44+
});
45+
46+
console.log("🔑 Generated Access Token:", accessToken);
1847
const username = req.user.username;
19-
res.redirect(
20-
`https://vigy-bag.vercel.app/dashboard?email=${email}&username=${username}`
21-
);
48+
49+
// Set secure HttpOnly cookie
50+
res.cookie('accessToken', accessToken, {
51+
httpOnly: true,
52+
secure: process.env.NODE_ENV === 'production',
53+
sameSite: 'lax',
54+
maxAge: 24 * 60 * 60 * 1000 // 24 hours
55+
});
56+
57+
const frontendUrl = process.env.FRONTEND_URL || 'https://vigy-bag.vercel.app';
58+
const redirectUrl = `${frontendUrl}/auth/success?username=${username}`;
59+
60+
console.log(`🚀 Redirecting to frontend: ${redirectUrl}`);
61+
res.redirect(redirectUrl);
2262
}
2363
);
2464

25-
router.post("/signup", authController.signup);
26-
router.post("/login", authController.login);
27-
router.post("/send-otp", authController.otp);
28-
router.post("/verify-otp", authController.verifyOtp);
29-
3065
module.exports = router;

backend/server.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ const config = require("./config/config");
66
connectDB();
77

88
// Start the server
9-
const PORT = config.port;
9+
const PORT = config.port || 30000;
1010
app.listen(PORT, () => {
11-
console.log(`Server is running on http://localhost:${PORT}`);
11+
12+
const serverAddress = process.env.SERVER_URL || `http://localhost:${PORT}`;
13+
console.log(`🚀 Server is live and running on: ${serverAddress}`);
1214
});
Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,34 @@
1-
import React from "react";
1+
import React from 'react';
2+
3+
// HIGHLIGHT: handleLogout prop ko yahan receive karein
4+
const Header = ({ handleLogout }) => {
5+
// localStorage se username nikalein
6+
const username = localStorage.getItem("username");
27

3-
function Header() {
48
return (
5-
<>
6-
<header className="flex justify-between items-center mb-6">
7-
<a href="dashboard" className="text-3xl text-green-700 font-bold">
8-
Dashboard
9-
</a>
10-
</header>
11-
</>
9+
<header className="flex flex-col sm:flex-row justify-between items-start sm:items-center mb-6 gap-4">
10+
11+
{/* Welcome Message Section */}
12+
<div>
13+
{/* HIGHLIGHT: User ka naam aur welcome message */}
14+
<h1 className="text-3xl font-bold text-gray-800">Welcome, {username || 'User'}!</h1>
15+
<p className="text-gray-500">Here's what's new and trending today.</p>
16+
</div>
17+
18+
{/* Logout Button Section */}
19+
<div>
20+
{/* HIGHLIGHT: Logout button jo Dashboard se pass kiye gaye function ko call karta hai */}
21+
<button
22+
onClick={handleLogout}
23+
className="bg-red-500 text-white px-5 py-2 rounded-lg font-semibold hover:bg-red-600 transition shadow-md"
24+
>
25+
Logout
26+
</button>
27+
</div>
28+
29+
</header>
1230
);
13-
}
31+
};
1432

1533
export default Header;
34+

src/User/pages/Dashboard/Dashboard.jsx

Lines changed: 67 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { useState, useEffect } from "react";
2-
import { useNavigate } from "react-router-dom";
2+
import { useNavigate, useSearchParams } from "react-router-dom";
3+
import Swal from "sweetalert2";
34
import granola from "../../../assets/granola.jpg";
45
import cuttery from "../../../assets/cuttery-set.jpg";
56
import basket from "../../../assets/basket.png";
@@ -22,19 +23,53 @@ import Dropdown from "../../components/Dashboard/Dropdown";
2223

2324
const Dashboard = () => {
2425
const navigate = useNavigate();
26+
const [searchParams] = useSearchParams();
2527

28+
// HIGHLIGHT: Yeh useEffect Google se redirect hokar aaye token ko handle karega
2629
useEffect(() => {
27-
const params = new URLSearchParams(window.location.search);
28-
const email = params.get("email");
29-
const username = params.get("username");
30+
const token = searchParams.get("token");
31+
const usernameFromUrl = searchParams.get("username");
3032

31-
if (email && username) {
32-
localStorage.setItem("email", email);
33+
// Skip if already logged in
34+
const isLoggedIn = localStorage.getItem("isLoggedIn");
35+
if (isLoggedIn === "true") {
36+
return;
37+
}
38+
39+
// Agar URL mein token hai, to yeh Google se login hokar aaya hai
40+
if (token && usernameFromUrl) {
41+
// Data ko localStorage mein save karein
42+
localStorage.setItem("accessToken", token);
43+
localStorage.setItem("username", usernameFromUrl);
3344
localStorage.setItem("isLoggedIn", "true");
34-
localStorage.setItem("username", username);
45+
46+
try {
47+
const base64Url = token.split(".")[1];
48+
const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
49+
const padded = base64 + "=".repeat((4 - (base64.length % 4)) % 4);
50+
const payload = JSON.parse(atob(padded));
51+
const role = payload?.role ?? 0;
52+
localStorage.setItem("role", String(role));
53+
} catch (error) {
54+
console.warn("Unable to decode role from token.", error);
55+
localStorage.setItem("role", "0");
56+
}
57+
58+
// Success message dikhayein
59+
Swal.fire({
60+
title: "Login Successful!",
61+
text: `Welcome, ${usernameFromUrl}!`,
62+
icon: "success",
63+
timer: 2000,
64+
showConfirmButton: false,
65+
});
66+
67+
// URL ko saaf karein taaki token dikhna band ho jaye
68+
navigate("/dashboard", { replace: true });
3569
}
36-
}, [location]);
70+
}, [searchParams, navigate]);
3771

72+
// Aapka baaki ka code...
3873
const initialProducts = [
3974
{
4075
image: granola,
@@ -48,39 +83,19 @@ const Dashboard = () => {
4883
price: 1200,
4984
rating: 4,
5085
},
51-
{
52-
image: basket,
53-
title: "Jute Cotton Basket",
54-
price: 399,
55-
rating: 4,
56-
},
57-
{
58-
image: shawls,
59-
title: "Premium Woolen Shawls",
60-
price: 5000,
61-
rating: 5,
62-
},
86+
{ image: basket, title: "Jute Cotton Basket", price: 399, rating: 4 },
87+
{ image: shawls, title: "Premium Woolen Shawls", price: 5000, rating: 5 },
6388
];
6489

6590
const moreProducts = [
66-
{
67-
image: notebooks,
68-
title: "Eco-Friendly Notebook",
69-
price: 250,
70-
rating: 4,
71-
},
91+
{ image: notebooks, title: "Eco-Friendly Notebook", price: 250, rating: 4 },
7292
{
7393
image: toothbrushes,
7494
title: "Bamboo Toothbrush Set",
7595
price: 150,
7696
rating: 5,
7797
},
78-
{
79-
image: towels,
80-
title: "Organic Cotton Towels",
81-
price: 600,
82-
rating: 4,
83-
},
98+
{ image: towels, title: "Organic Cotton Towels", price: 600, rating: 4 },
8499
{
85100
image: shoppingBags,
86101
title: "Reusable Shopping Bags",
@@ -99,18 +114,8 @@ const Dashboard = () => {
99114
price: 200,
100115
rating: 4,
101116
},
102-
{
103-
image: waterBottle,
104-
title: "Glass Water Bottle",
105-
price: 350,
106-
rating: 5,
107-
},
108-
{
109-
image: teaSet,
110-
title: "Organic Tea Set",
111-
price: 750,
112-
rating: 5,
113-
},
117+
{ image: waterBottle, title: "Glass Water Bottle", price: 350, rating: 5 },
118+
{ image: teaSet, title: "Organic Tea Set", price: 750, rating: 5 },
114119
];
115120

116121
const [products] = useState([...initialProducts, ...moreProducts]);
@@ -140,22 +145,27 @@ const Dashboard = () => {
140145
setShowViewLess(false);
141146
};
142147

148+
// HIGHLIGHT: Logout function ko Swal se update kiya gaya hai
143149
const handleLogout = () => {
144-
try {
145-
let confirmed = confirm("Are you sure you want to logout?");
146-
if (confirmed) {
150+
Swal.fire({
151+
title: "Are you sure you want to logout?",
152+
icon: "warning",
153+
showCancelButton: true,
154+
confirmButtonColor: "#3085d6",
155+
cancelButtonColor: "#d33",
156+
confirmButtonText: "Yes, logout!",
157+
}).then((result) => {
158+
if (result.isConfirmed) {
159+
// Saare login-related items ko clear karein
147160
localStorage.removeItem("isLoggedIn");
148161
localStorage.removeItem("email");
149162
localStorage.removeItem("username");
150-
alert("Logout Successfully and safely.");
151-
navigate("/login");
152-
} else {
153-
return;
163+
localStorage.removeItem("accessToken");
164+
localStorage.removeItem("role");
165+
166+
navigate("/home");
154167
}
155-
} catch (error) {
156-
alert("Logout Failed. Try Again later");
157-
console.log(error);
158-
}
168+
});
159169
};
160170

161171
return (
@@ -166,11 +176,10 @@ const Dashboard = () => {
166176
{/* Main Content */}
167177
<main className="flex-1 p-6 mt-10">
168178
{/* Header */}
169-
<Header />
170-
179+
<Header handleLogout={handleLogout} />{" "}
180+
{/* Pass handleLogout to Header */}
171181
{/* Search Bar */}
172182
<SearchBar searchTerm={searchTerm} handleSearch={handleSearch} />
173-
174183
{/* New Today Section */}
175184
<section>
176185
<div className="flex justify-between">

0 commit comments

Comments
 (0)