feat: add authentication and admin features
- Added `jose` library for JWT token generation and verification. - Implemented login functionality with token storage using cookies. - Created `HeaderAdmin` component for admin panel with login/logout capabilities. - Developed `LoginForm` component for user authentication. - Added `Table` component to display data with caching from localStorage. - Introduced `SubHeaderAdmin` for additional admin actions. - Enhanced `database.js` with functions for admin login and fetching table data. - Updated `server.js` to handle new routes for login and table data retrieval. - Modified `package.json` and `package-lock.json` to include new dependencies.
This commit is contained in:
10
backend/package-lock.json
generated
10
backend/package-lock.json
generated
@@ -13,6 +13,7 @@
|
||||
"dotenv": "^17.2.1",
|
||||
"ejs": "^3.1.10",
|
||||
"express": "^5.1.0",
|
||||
"jose": "^6.0.12",
|
||||
"mysql2": "^3.14.3"
|
||||
}
|
||||
},
|
||||
@@ -563,6 +564,15 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/jose": {
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-6.0.12.tgz",
|
||||
"integrity": "sha512-T8xypXs8CpmiIi78k0E+Lk7T2zlK4zDyg+o1CZ4AkOHgDg98ogdP2BeZ61lTFKFyoEwJ9RgAgN+SdM3iPgNonQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/panva"
|
||||
}
|
||||
},
|
||||
"node_modules/long": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
|
||||
|
@@ -15,6 +15,7 @@
|
||||
"dotenv": "^17.2.1",
|
||||
"ejs": "^3.1.10",
|
||||
"express": "^5.1.0",
|
||||
"jose": "^6.0.12",
|
||||
"mysql2": "^3.14.3"
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
import express from "express";
|
||||
import cors from "cors";
|
||||
import env from "dotenv";
|
||||
import { query } from "./services/database.js";
|
||||
import { query, loginAdmin, getTableData } from "./services/database.js";
|
||||
import { generateToken, authenticate } from "./services/tokenService.js";
|
||||
env.config();
|
||||
const app = express();
|
||||
const port = 8002;
|
||||
@@ -24,6 +25,26 @@ app.post("/lose", async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/table-data", authenticate, async (req, res) => {
|
||||
const result = await getTableData();
|
||||
if (result.success) {
|
||||
res.status(200).json(result.data);
|
||||
} else {
|
||||
res.status(500);
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/login", async (req, res) => {
|
||||
const { username, password } = req.body;
|
||||
const result = await loginAdmin(username, password);
|
||||
if (result.success) {
|
||||
const token = await generateToken({ username });
|
||||
res.status(200).json({ success: true, token });
|
||||
} else {
|
||||
res.status(401).json({ success: false });
|
||||
}
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Server is running on port: ${port}`);
|
||||
});
|
||||
|
@@ -2,7 +2,7 @@ import mysql from "mysql2";
|
||||
import dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
// Create a MySQL connection pool using environment variables for configuration
|
||||
// Ein einzelner Pool reicht; der zweite Pool benutzte fälschlich DB_TABLE als Datenbank
|
||||
const pool = mysql
|
||||
.createPool({
|
||||
host: process.env.DB_HOST,
|
||||
@@ -32,3 +32,21 @@ export async function query(params) {
|
||||
return { success: false };
|
||||
}
|
||||
}
|
||||
|
||||
export async function loginAdmin(username, password) {
|
||||
const [rows] = await pool.query(
|
||||
"SELECT * FROM admin_user WHERE username = ? AND password = ?",
|
||||
[username, password]
|
||||
);
|
||||
if (rows.length > 0) return { success: true };
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
export async function getTableData() {
|
||||
const [result] = await pool.query("SELECT * FROM lose");
|
||||
|
||||
if (result.length > 0) {
|
||||
return { success: true, data: result };
|
||||
}
|
||||
return { success: false };
|
||||
}
|
||||
|
26
backend/services/tokenService.js
Normal file
26
backend/services/tokenService.js
Normal file
@@ -0,0 +1,26 @@
|
||||
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) {
|
||||
const newToken = await new SignJWT(payload)
|
||||
.setProtectedHeader({ alg: "HS256" })
|
||||
.setIssuedAt()
|
||||
.setExpirationTime("2h") // Token valid for 2 hours
|
||||
.sign(secret);
|
||||
console.log("Generated token: ", newToken);
|
||||
return newToken;
|
||||
}
|
||||
|
||||
export async function authenticate(req, res, next) {
|
||||
const authHeader = req.headers["authorization"];
|
||||
const token = authHeader && authHeader.split(" ")[1]; // Bearer <token>
|
||||
|
||||
if (token == null) return res.sendStatus(401); // No token present
|
||||
|
||||
const { payload } = await jwtVerify(token, secret);
|
||||
req.user = payload;
|
||||
|
||||
next();
|
||||
}
|
Reference in New Issue
Block a user