Skip to content
Snippets Groups Projects
Commit d71bbb1e authored by Federico Hurtado's avatar Federico Hurtado
Browse files

Set up user identification from the JWT token.

parent 86152a40
No related branches found
No related tags found
1 merge request!12Merge request with Backend for sprint 3/4
......@@ -35,11 +35,16 @@ const casLogin = async function (req, res, next) {
// sign the token with secret key
const token = jwt.sign(payload, JWT_SECRET, { expiresIn: "1h" });
console.log("sending token for use in localhost");
// Set the token as an HTTP-only cookie
res.cookie("auth_token", token, {
maxAge: 3600000, // 1 hour in milliseconds
});
console.log("sent token for use in localhost");
console.log("Frontend: ", process.env.FRONTEND_URL);
res.redirect(`${process.env.FRONTEND_URL}/home?token=${token}`);
res.redirect(`${process.env.FRONTEND_URL}/home`);
return;
}
......@@ -79,6 +84,10 @@ const casLogin = async function (req, res, next) {
// sign the token with secret key
const token = jwt.sign(payload, JWT_SECRET, { expiresIn: "1h" });
res.cookie("auth_token", token, {
maxAge: 3600000, // 1 hour in milliseconds
});
// document a successful login
try {
const timestamp = new Date(); // Current timestamp
......@@ -89,7 +98,7 @@ const casLogin = async function (req, res, next) {
// Send the JWT token to the frontend
console.log("sending JWT To: ", process.env.FRONTEND_URL);
res.redirect(`${process.env.FRONTEND_URL}/home?token=${token}`);
res.redirect(`${process.env.FRONTEND_URL}/home`);
console.log("Successfully authenticated and generated token.");
});
......
......@@ -77,9 +77,10 @@ class DatabaseInitializer {
try {
await addRoleIfNotExists(1, "guest", "Guest access");
await addRoleIfNotExists(2, "admin", "Admin access");
await addRoleIfNotExists(3, "classChampion", "Class champion access");
await addRoleIfNotExists(4, "orgLeader", "Org leader access");
await addRoleIfNotExists(2, "user", "Basic user access");
await addRoleIfNotExists(3, "admin", "Admin access");
await addRoleIfNotExists(4, "classChampion", "Class champion access");
await addRoleIfNotExists(5, "orgLeader", "Org leader access");
console.log("Roles initialized successfully.");
} catch (error) {
console.log("error initializing roles: ", error);
......
......@@ -131,7 +131,4 @@ CREATE TABLE IF NOT EXISTS changeLog (
oldValues TEXT, -- JSON format for previous values
newValues TEXT, -- JSON format for new values
FOREIGN KEY (userId) REFERENCES users(userID)
);
INSERT INTO countryLookup (countryId, name)
VALUES (1, 'United States');
);
\ No newline at end of file
This diff is collapsed.
......@@ -8,56 +8,44 @@ import { jwtDecode } from "jwt-decode";
Home page where users will be redirected after log in or continuing as a guest
*/
function Home() {
// username and privilage to be extracted from JWT token
const [username, setUsername] = useState("");
const [privilege, setPrivilege] = useState("");
const extractTokenFromUrl = () => {
const params = new URLSearchParams(window.location.search);
const token = params.get("token");
// no token found
if (!token) {
// user will be seen as a guest
setUsername("guest");
setPrivilege("guest");
}
// when the page mounts check for auth tokens
useEffect(() => {
const readLoginCookie = () => {
try {
// find the auth cookie sent from the backend
const cookies = document.cookie;
const cookieArray = cookies.split("; ");
const authCookie = cookieArray.find((cookie) =>
cookie.startsWith("auth_token=")
);
// decode the token and set the user info
try {
const decoded = jwtDecode(token);
setUsername(decoded.username);
setPrivilege(decoded.role);
} catch (error) {
console.error("Error decoding token: ", error);
}
};
// return early if no cookie found
if (!authCookie) {
console.log("cannot find auth cookie.");
return;
}
// useEffect to make the API call
useEffect(() => {
extractTokenFromUrl(); // extract the username and role from the token
}, []);
// extract the token from the cookie
const token = authCookie.split("=")[1];
return (
// <div>
// <h1>Home Page</h1>
// decode the token
const decoded = jwtDecode(token);
// <p>
// Below are the results of calling the backend server. The API URL should
// be localhost in development and be
// http://corpsdirectory.discovery.cs.vt.edu/api in the cluster.
// </p>
console.log("decoded token: ", decoded);
// {/* Display data if it exists */}
// <p>
// Data: {data ? <span>{JSON.stringify(data)}</span> : <span>&nbsp;</span>}
// </p>
// extract details from token and store them in memory
localStorage.setItem("userId", decoded.id);
localStorage.setItem("peopleId", decoded.peopleId);
localStorage.setItem("role", decoded.role);
} catch (error) {
console.log("error reading cookie: ", error);
}
};
// <p>API URL: {process.env.REACT_APP_API_URL}</p>
readLoginCookie();
}, []);
// {/* display error if there is an error*/}
// <p>Error: {error ? <span>{error}</span> : <span>&nbsp;</span>}</p>
// </div>
return (
<>
<div className="text-center">
<h1 className="thin-veranda">VT Cadet Directory</h1>
......@@ -70,16 +58,7 @@ function Home() {
Virginia Tech Corps of Cadets Directory
</h1>
{/*Adding this here so you guys see how to access but feel free to change it*/}
{username && (
<div>
<h2>
Welcome, <strong>{username}</strong>!
</h2>
<p>
Your role: <strong>{privilege}</strong>
</p>
</div>
)}
<h1 className="description-font">
Lorem ipsum odor amet, consectetuer adipiscing elit. Primis quam
vel posuere lobortis inceptos. Nostra sociosqu tristique sagittis
......@@ -105,28 +84,6 @@ function Home() {
<img src={logo} alt="Corps Logo" className="logo" width={400} />
</div>
</div>
<div className="selection-section">
<div className="button-container">
{/* <div className="button-wrapper">
<button className="action-button">
<img src={logo} width={70} alt="Browse" className="icon" />
</button>
<span>Browse</span>
</div> */}
{/* <div className="button-wrapper">
<button className="action-button">
<img src={logo} alt="Search" className="icon" />
</button>
<span>Search</span>
</div> */}
{/* <div className="button-wrapper">
<button className="action-button">
<img src={logo} alt="Message" className="icon" />
</button>
<span>Message</span>
</div> */}
</div>
</div>
</>
);
}
......
......@@ -36,29 +36,67 @@ const Navbar = () => {
<ul className={styles.navList}>
{/* Common Links */}
<li>
<Link to="/home">Home</Link>
<Link
to="/home"
className={({ isActive }) => (isActive ? "active" : "")}
>
Home
</Link>
</li>
<li>
<Link to="/browse">Browse</Link>
<Link
to="/browse"
className={({ isActive }) => (isActive ? "active" : "")}
>
Browse
</Link>
</li>
<li>
<Link to="/search">Search</Link>
<Link
to="/search"
className={({ isActive }) => (isActive ? "active" : "")}
>
Search
</Link>
</li>
{/* Links for logged-out users */}
{!isLoggedIn && (
<>
<li>
<Link
to="/login"
className={({ isActive }) => (isActive ? "active" : "")}
>
Login
</Link>
</li>
)}
{/* Admin-specific Links */}
{isLoggedIn &&
(role === "admin" ||
role === "classChampion" ||
role === "orgLeader") && (
<li>
<Link to="/login">Login</Link>
<Link
to="/admin/dashboard"
className={({ isActive }) => (isActive ? "active" : "")}
>
Admin
</Link>
</li>
</>
)}
)}
{/* Links for logged-in users */}
{isLoggedIn && (
<>
<li>
<Link to="/my-profile">My Profile</Link>
<Link
to="/my-profile"
className={({ isActive }) => (isActive ? "active" : "")}
>
My Profile
</Link>
</li>
<li>
<button onClick={handleLogout} className={styles.logoutButton}>
......@@ -67,16 +105,6 @@ const Navbar = () => {
</li>
</>
)}
{/* Admin-specific Link */}
{isLoggedIn &&
(role === "admin" ||
role === "classChampion" ||
role === "orgLeader") && (
<li>
<Link to="/admin/dashboard">Admin</Link>
</li>
)}
</ul>
</nav>
);
......
......@@ -18,7 +18,7 @@
/* Navbar links */
.navList li a {
margin: 0 80px; /* Increase margin to space out links */
margin: 0 80px; /* Space out links */
color: white;
text-decoration: none;
font-size: 20px;
......@@ -28,7 +28,7 @@
/* Hover effect for navbar links */
.navList li a:hover {
color: rgb(13, 28, 84); /* Changes text color on hover */
color: rgb(13, 28, 84); /* Hover color */
}
/* Underline effect on hover */
......@@ -44,5 +44,29 @@
}
.navList li a:hover::after {
width: 100%; /* Expands underline on hover */
width: 100%; /* Expands underline */
}
/* Active link styling */
.navList li a.activeLink {
font-weight: bold;
color: rgb(0, 47, 255); /* Same as underline color */
}
/* Logout button styles */
.logoutButton {
background-color: white;
color: black;
border: none;
padding: 8px 15px;
font-size: 16px;
font-weight: 500;
border-radius: 5px;
cursor: pointer;
transition: all 0.3s ease-in-out;
}
.logoutButton:hover {
background-color: rgb(0, 47, 255); /* Matches underline hover */
color: white;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment