diff --git a/backend/.env b/backend/.env index 2b89305..62594a4 100755 --- a/backend/.env +++ b/backend/.env @@ -1,4 +1,6 @@ DB_HOST=mysql DB_USER=root DB_PASSWORD=D7Ze0lwV9hMrNQHdz1Q8yi0MIQuOO8 -DB_NAME=bikelane \ No newline at end of file +DB_NAME=bikelane + +SECRET_KEY=vFzEmezKz5GAwVaaf02xHoSnk8toDikTgWyqwdBa2LIHORPevHDHf72eL4ylCfrDxQ2wFN5CtXj12KTTJmCg7q0kGaPeEbfDE1MxofcsEjYKCD5WsJsdKNGegx2qALgy \ No newline at end of file diff --git a/backend/server.js b/backend/server.js index 2e780ab..5736b15 100644 --- a/backend/server.js +++ b/backend/server.js @@ -9,35 +9,35 @@ import { updateUser, deleteUser, getAllUsers, -} from "./database.js"; +} from "./services/database.js"; +import { generateToken, authenticate } from "./services/tokenService.js"; import cookieParser from "cookie-parser"; -import bodyParser from "body-parser"; -import jose from "jose"; //view engine ejs app.set("view engine", "ejs"); app.use(express.json()); - app.use(cors()); +app.use(cookieParser()); app.post("/api/login", async (req, res) => { console.log(req.body); - loginUser(req.body.username, req.body.password) - .then((result) => { - if (result.success) { - res.status(200).json(result, { message: "Login successful" }); // Here send the jwt token - } else { - res.status(401).json(result, { message: "Invalid credentials" }); - } - }) - .catch((err) => { - console.error("Error logging in:", err); - res - .status(500) - .json({ success: false, message: "Internal server error" }); - }); + try { + const result = await loginUser(req.body.username, req.body.password); + if (result.success) { + const userToken = await generateToken({ username: req.body.username }); + res.status(200).json( + result, // This is the user data that logged in + { message: "Login successful", token: userToken } + ); + } else { + res.status(401).json(result, { message: "Invalid credentials" }); + } + } catch (err) { + console.error("Error logging in:", err); + res.status(500).json({ success: false, message: "Internal server error" }); + } }); app.get("/api/getAllUsers", async (req, res) => { @@ -47,7 +47,9 @@ app.get("/api/getAllUsers", async (req, res) => { }) .catch((err) => { console.error("Error fetching users:", err); - res.status(500).json({ success: false, message: "Internal server error" }); + res + .status(500) + .json({ success: false, message: "Internal server error" }); }); }); @@ -60,4 +62,4 @@ app.use((err, req, res, next) => { // Log the error stack and send a generic error response console.error(err.stack); res.status(500).send("Something broke!"); -}); \ No newline at end of file +}); diff --git a/backend/database.js b/backend/services/database.js similarity index 100% rename from backend/database.js rename to backend/services/database.js diff --git a/backend/services/tokenService.js b/backend/services/tokenService.js new file mode 100644 index 0000000..e0bcfd2 --- /dev/null +++ b/backend/services/tokenService.js @@ -0,0 +1,28 @@ +import cookieParser from "cookie-parser"; +import bodyParser from "body-parser"; +import { SignJWT, jwtVerify } from "jose"; +import env from "dotenv"; +env.config(); +const secret = new TextEncoder().encode(process.env.SECRET_KEY); + +export async function generateToken(payload) { + return await new SignJWT(payload) + .setProtectedHeader({ alg: "HS256" }) + .setIssuedAt() + .setExpirationTime("2h") // Token valid for 2 hours + .sign(secret); +} + +export async function authenticate(req, res, next) { + const token = req.cookies.token; + + if (!token) return res.status(401).send("No token provided"); + + try { + const { payload } = await jwtVerify(token, secret); + req.user = payload; + next(); + } catch (e) { + return res.status(403).send("Invalid or expired token"); + } +} diff --git a/backend/views/index.ejs b/backend/views/index.ejs deleted file mode 100644 index 30d74d2..0000000 --- a/backend/views/index.ejs +++ /dev/null @@ -1 +0,0 @@ -test \ No newline at end of file diff --git a/client/src/components/LoginCard.tsx b/client/src/components/LoginCard.tsx index d81f989..f13ae78 100644 --- a/client/src/components/LoginCard.tsx +++ b/client/src/components/LoginCard.tsx @@ -34,6 +34,7 @@ const LoginCard: React.FC = ({ onClose }) => { .then(async (response) => { if (response.ok) { const data = await response.json(); + Cookies.set("token", data.token, { expires: 7 }); onClose(); Cookies.set("name", data.user.first_name, { expires: 7 }); await fetch("http://localhost:5002/api/getAllUsers")