Merge remote-tracking branch 'origin/main'

This commit is contained in:
IM23a-cernik
2025-04-17 14:03:25 +02:00
9 changed files with 138 additions and 26 deletions
+18 -1
View File
@@ -1,3 +1,20 @@
[ [
{
"username": "jerome",
"password": "Sigma",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb3dlcl91c2VybmFtZSI6Implcm9tZSIsImlhdCI6MTc0NDg4OTY3MSwiZXhwIjoxNzQ0ODkxNDcxfQ.zYg3uxh_iNZ2xdEma8p3p-URT3Xa7wnYiQyOx0-QTac",
"money": 200
},
{
"username": "Gianimon",
"password": "gianimon",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IkdpYW5pbW9uIiwiaWF0IjoxNzQ0ODc0NTczLCJleHAiOjE3NDQ4NzYzNzN9.dGp5WTKIDVhomKZ8J7nevz8O7PqwRhR9wEgeyDtL_XE",
"money": 200
},
{
"username": "any",
"password": "any",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFueSIsImlhdCI6MTc0NDg4OTk1OSwiZXhwIjoxNzQ0ODkxNzU5fQ.TA6BA09DQlmUqEzQxD_wF0r-VyqCMccoxq8SxPnB9-4",
"money": 200
}
] ]
+26 -10
View File
@@ -62,8 +62,10 @@ function authenticateToken(request, response, next) {
} }
app.post("/register", (request, response) => { app.post("/register", (request, response) => {
const { username, password } = request.body; let { username, password } = request.body;
if (!username && !password) username = username.toLowerCase();
if (!username || !password)
return response.status(400).json({ error: "Username and password are required" }); return response.status(400).json({ error: "Username and password are required" });
const users = get_data(); const users = get_data();
@@ -71,19 +73,19 @@ app.post("/register", (request, response) => {
return response.status(400).json({ error: "Username already exists" }); return response.status(400).json({ error: "Username already exists" });
} }
const token = generateAccessToken({ username }); const token = generateAccessToken({ username });
saveUser({ username, password, token, "money": 200 }); saveUser({ username, password, token, "money": 200 });
response.json({ username, token }); response.json({ lower_username, token });
}); });
app.get("/login", (request, response) => { app.get("/login", (request, response) => {
response.sendFile(path.join(__dirname, ".\\public\\login.html")); response.sendFile(path.join(__dirname, ".\\public\\login.html"));
}) })
app.post("/login", (request, response) => { app.post("/login", (request, response) => {
const { username, password } = request.body; let { username, password } = request.body;
if (!username && !password) username = username.toLowerCase();
if (!username || !password)
return response.status(400).json({ error: "Username and password are required" }); return response.status(400).json({ error: "Username and password are required" });
const users = get_data(); const users = get_data();
@@ -105,15 +107,15 @@ app.get("/", authenticateToken, (request, response) => {
/* #swagger.security = [{ /* #swagger.security = [{
"bearerAuth": [] "bearerAuth": []
}] */ }] */
response.sendFile(path.join(__dirname, "structure.png")); response.sendFile(path.join(__dirname, ".\\public\\home.html"));
}); });
app.post("/balance", authenticateToken, (request, response) => { app.get("/balance", authenticateToken, (request, response) => {
/* #swagger.security = [{ /* #swagger.security = [{
"bearerAuth": [] "bearerAuth": []
}] */ }] */
const username = request.user.username; const username = request.user.username;
console.log(username);
const allUsers = get_data(); const allUsers = get_data();
const me = allUsers.find(u => u.username === username); const me = allUsers.find(u => u.username === username);
@@ -121,7 +123,7 @@ app.post("/balance", authenticateToken, (request, response) => {
return response.status(404).json({ error: "User not found" }); return response.status(404).json({ error: "User not found" });
} }
response.json({ balance: me.money }); response.json({ balance: me.money }).status(200);
}); });
app.post("/verify", authenticateToken, (request, response) => { app.post("/verify", authenticateToken, (request, response) => {
@@ -129,13 +131,27 @@ app.post("/verify", authenticateToken, (request, response) => {
}); });
app.delete("/logout", authenticateToken, (request, response) => { app.delete("/logout", authenticateToken, (request, response) => {
/* #swagger.security = [{
"bearerAuth": []
}] */
const username = request.user.username; const username = request.user.username;
const users = get_data(); const users = get_data();
const user = users.find(u => u.username === username); const user = users.find(u => u.username === username);
// 1) Clear the HttpOnly cookie in the browser
response.clearCookie("token", {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "Strict"
});
// 2) Delete the token from your JSON store
if (user) { if (user) {
delete user.token; delete user.token;
save_data(users); save_data(users);
} }
// 3) Send final response
response.json({ message: "Logged out successfully." }); response.json({ message: "Logged out successfully." });
}); });
+19
View File
@@ -0,0 +1,19 @@
document.addEventListener("DOMContentLoaded", async () => {
const logoutButton = document.getElementById("logout");
const balance = document.getElementById("balance");
try {
const balanceRes = await fetch('/balance', {
method: "GET",
headers: {
"Content-Type": "application/json",
}
});
if (balanceRes.ok) {
const balanceData = await balanceRes.json();
console.log(balanceData);
balance.innerHTML = balanceData.balance;
}
} catch (error) {
console.log(error);
}
});
@@ -1,5 +1,4 @@
const TokenHeader = new Headers(); document.addEventListener("DOMContentLoaded", () => {
document.addEventListener("DOMContentLoaded", () => {
const form = document.querySelector("form"); const form = document.querySelector("form");
form.addEventListener("submit", async (e) => { form.addEventListener("submit", async (e) => {
@@ -20,6 +19,7 @@ document.addEventListener("DOMContentLoaded", () => {
const loginData = await loginRes.json(); const loginData = await loginRes.json();
alert(`Welcome back, ${loginData.username}!`); alert(`Welcome back, ${loginData.username}!`);
document.cookie = `authorization=${loginData.token}` document.cookie = `authorization=${loginData.token}`
window.location.href = "/";
return; return;
} }
@@ -33,6 +33,7 @@ document.addEventListener("DOMContentLoaded", () => {
const registerData = await registerRes.json(); const registerData = await registerRes.json();
alert(`Account created! Welcome, ${registerData.username}`); alert(`Account created! Welcome, ${registerData.username}`);
document.cookie = `authorization=${registerData.token}` document.cookie = `authorization=${registerData.token}`
window.location.href = "/";
} else { } else {
const error = await registerRes.json(); const error = await registerRes.json();
alert("Register failed: " + (error.error || "Unknown error")); alert("Register failed: " + (error.error || "Unknown error"));
+16
View File
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home</title>
<link rel="stylesheet" href="styles_home.css">
<script src="frontend_home.js" defer></script> <!-- make sure this is included -->
</head>
<body>
<button class="logout" id="logout">Logout</button>
<div class="balance">
Balance: $<span id="balance">0</span>
</div>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Login</title> <title>Login</title>
<link rel="stylesheet" href="styles.css"> <link rel="stylesheet" href="styles_login.css">
</head> </head>
<body> <body>
<form method="post" action="/login"> <form method="post" action="/login">
@@ -12,5 +12,5 @@
<button type="submit">Login</button> <button type="submit">Login</button>
</form> </form>
</body> </body>
<script src="frontend.js"></script> <script src="frontend_login.js"></script>
</html> </html>
-10
View File
@@ -1,10 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>I am a Nogger Glace</title>
</head>
<body>
</body>
</html>
+53
View File
@@ -0,0 +1,53 @@
body {
background: radial-gradient(circle at top, #111, #000);
color: #0f0;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
height: 100vh;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
body::before {
content: "♠ ♥ Welcome to Gambling API ♦ ♣";
font-size: 24px;
color: #0f0;
margin-bottom: 40px;
display: block;
text-shadow: 0 0 5px #0f0, 0 0 10px #0f0;
}
button {
background-color: #0f0;
color: #000;
border: none;
padding: 15px 30px;
font-size: 16px;
font-weight: bold;
border-radius: 12px;
cursor: pointer;
box-shadow: 0 0 10px #0f0, 0 0 5px #0f0 inset;
transition: background 0.2s ease-in-out, transform 0.2s;
}
button:hover {
background-color: #1f1;
transform: scale(1.05);
}
button.logout {
position: absolute;
top: 20px;
right: 20px;
padding: 10px 20px;
font-size: 14px;
}
.balance {
margin-top: 20px;
color: #0f0;
text-shadow: 0 0 5px #0f0, 0 0 10px #0f0;
}