Mehrfachlogin nicht mehr möglich
This commit is contained in:
parent
4d8681ac86
commit
fd116db132
31
middleware/auth.js
Normal file
31
middleware/auth.js
Normal file
@ -0,0 +1,31 @@
|
||||
const db = require("../database/database");
|
||||
|
||||
async function auth(req, res, next) {
|
||||
if (!req.session.user) {
|
||||
return res.redirect("/");
|
||||
}
|
||||
|
||||
try {
|
||||
const [rows] = await db.query(
|
||||
"SELECT session_token FROM accounts WHERE id = ?",
|
||||
[req.session.user.id],
|
||||
);
|
||||
|
||||
if (!rows.length) {
|
||||
req.session.destroy();
|
||||
return res.redirect("/");
|
||||
}
|
||||
|
||||
if (rows[0].session_token !== req.session.user.token) {
|
||||
req.session.destroy();
|
||||
return res.redirect("/");
|
||||
}
|
||||
|
||||
next();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.redirect("/");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = auth;
|
||||
@ -1,5 +1,10 @@
|
||||
fetch("/api/buildings")
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
if (!res.ok) {
|
||||
throw new Error("API Fehler");
|
||||
}
|
||||
return res.json();
|
||||
})
|
||||
.then((buildings) => {
|
||||
buildings.forEach((building) => {
|
||||
const element = document.querySelector(
|
||||
@ -10,7 +15,6 @@ fetch("/api/buildings")
|
||||
|
||||
let title = element.querySelector("title");
|
||||
|
||||
// Falls kein title existiert → erstellen
|
||||
if (!title) {
|
||||
title = document.createElementNS("http://www.w3.org/2000/svg", "title");
|
||||
element.prepend(title);
|
||||
@ -18,4 +22,7 @@ fetch("/api/buildings")
|
||||
|
||||
title.textContent = building.name;
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Buildings API Fehler:", error);
|
||||
});
|
||||
|
||||
@ -2,6 +2,10 @@ const popup = document.getElementById("building-popup");
|
||||
const title = document.getElementById("popup-title");
|
||||
const tooltip = document.getElementById("map-tooltip");
|
||||
|
||||
/* ================================
|
||||
Tabs zurücksetzen
|
||||
================================ */
|
||||
|
||||
function resetTabs() {
|
||||
document
|
||||
.querySelectorAll(".tab")
|
||||
@ -10,7 +14,6 @@ function resetTabs() {
|
||||
.querySelectorAll(".tab-content")
|
||||
.forEach((c) => c.classList.remove("active"));
|
||||
|
||||
// erster Tab aktiv
|
||||
const firstTab = document.querySelector(".tab");
|
||||
const firstContent = document.querySelector(".tab-content");
|
||||
|
||||
@ -18,57 +21,67 @@ function resetTabs() {
|
||||
if (firstContent) firstContent.classList.add("active");
|
||||
}
|
||||
|
||||
document.querySelectorAll(".building").forEach((b) => {
|
||||
b.addEventListener("click", async (e) => {
|
||||
/* ================================
|
||||
Gebäude Popup öffnen
|
||||
================================ */
|
||||
|
||||
document.querySelectorAll(".building").forEach((building) => {
|
||||
building.addEventListener("click", async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const name = b.querySelector("title").textContent;
|
||||
const url = b.getAttribute("href");
|
||||
try {
|
||||
const name = building.querySelector("title")?.textContent || "Gebäude";
|
||||
const url = building.getAttribute("href");
|
||||
|
||||
title.innerText = name;
|
||||
title.innerText = name;
|
||||
|
||||
// Position des Gebäudes
|
||||
const rect = b.getBoundingClientRect();
|
||||
popup.style.left = "50%";
|
||||
popup.style.top = "50%";
|
||||
popup.style.display = "block";
|
||||
|
||||
popup.style.left = "50%";
|
||||
popup.style.top = "50%";
|
||||
resetTabs();
|
||||
|
||||
popup.style.display = "block";
|
||||
resetTabs();
|
||||
const res = await fetch("/api" + url);
|
||||
|
||||
// AJAX Gebäudedaten laden
|
||||
const res = await fetch("/api" + url);
|
||||
const data = await res.json();
|
||||
if (!res.ok) throw new Error("API Fehler");
|
||||
|
||||
document.getElementById("tab-info").innerHTML = `
|
||||
<h3>${data.name}</h3>
|
||||
<p>Level: ${data.level}</p>
|
||||
<p>Punkte: ${data.points} / ${data.nextLevelPoints}</p>
|
||||
<p>${data.description}</p>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill"
|
||||
style="width:${(data.points / data.nextLevelPoints) * 100}%">
|
||||
const data = await res.json();
|
||||
|
||||
document.getElementById("tab-info").innerHTML = `
|
||||
<h3>${data.name}</h3>
|
||||
<p>Level: ${data.level}</p>
|
||||
<p>Punkte: ${data.points} / ${data.nextLevelPoints}</p>
|
||||
<p>${data.description}</p>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill"
|
||||
style="width:${(data.points / data.nextLevelPoints) * 100}%">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
`;
|
||||
|
||||
document.getElementById("tab-actions").innerHTML = `
|
||||
<button>Betreten</button>
|
||||
<button>Handeln</button>
|
||||
`;
|
||||
document.getElementById("tab-actions").innerHTML = `
|
||||
<button>Betreten</button>
|
||||
<button>Handeln</button>
|
||||
`;
|
||||
|
||||
document.getElementById("tab-upgrade").innerHTML = `
|
||||
<p>Kosten: ${data.upgradeCost}</p>
|
||||
<button>Upgrade</button>
|
||||
`;
|
||||
document.getElementById("tab-upgrade").innerHTML = `
|
||||
<p>Kosten: ${data.upgradeCost}</p>
|
||||
<button>Upgrade</button>
|
||||
`;
|
||||
|
||||
document.getElementById("tab-history").innerHTML = `
|
||||
<p>${data.history}</p>
|
||||
`;
|
||||
document.getElementById("tab-history").innerHTML = `
|
||||
<p>${data.history}</p>
|
||||
`;
|
||||
} catch (error) {
|
||||
console.error("Gebäude konnte nicht geladen werden:", error);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Tabs
|
||||
/* ================================
|
||||
Tabs wechseln
|
||||
================================ */
|
||||
|
||||
document.querySelectorAll(".tab").forEach((tab) => {
|
||||
tab.addEventListener("click", () => {
|
||||
document
|
||||
@ -84,53 +97,42 @@ document.querySelectorAll(".tab").forEach((tab) => {
|
||||
});
|
||||
});
|
||||
|
||||
/* ================================
|
||||
Popup schließen
|
||||
================================ */
|
||||
|
||||
document.querySelector(".popup-close").onclick = () => {
|
||||
popup.style.display = "none";
|
||||
};
|
||||
|
||||
async function loadBuilding(buildingId) {
|
||||
try {
|
||||
const res = await fetch("/api/building/" + buildingId);
|
||||
const data = await res.json();
|
||||
|
||||
document.getElementById("tab-info").innerHTML = `
|
||||
<h3>${data.name}</h3>
|
||||
<p>Level: ${data.level}</p>
|
||||
<p>Punkte: ${data.points} / ${data.nextLevelPoints}</p>
|
||||
<p>${data.description}</p>
|
||||
`;
|
||||
|
||||
document.getElementById("tab-upgrade").innerHTML = `
|
||||
<p>Nächstes Level benötigt:</p>
|
||||
<p>${data.nextLevelPoints} Punkte</p>
|
||||
<p>Kosten: ${data.upgradeCost}</p>
|
||||
`;
|
||||
|
||||
document.getElementById("tab-history").innerHTML = `
|
||||
<p>${data.history}</p>
|
||||
`;
|
||||
} catch (err) {
|
||||
console.error("Fehler beim Laden des Gebäudes:", err);
|
||||
}
|
||||
}
|
||||
/* ================================
|
||||
Tooltip
|
||||
================================ */
|
||||
|
||||
document.querySelectorAll(".building").forEach((building) => {
|
||||
building.addEventListener("mouseenter", async (e) => {
|
||||
const id = building.dataset.id;
|
||||
try {
|
||||
const id = building.dataset.id;
|
||||
|
||||
const res = await fetch("/api/building/" + id);
|
||||
const data = await res.json();
|
||||
const res = await fetch("/api/building/" + id);
|
||||
|
||||
tooltip.innerHTML = `
|
||||
<strong>${data.name}</strong><br>
|
||||
Level ${data.level}<br>
|
||||
Punkte ${data.points}/${data.nextLevelPoints}<br>
|
||||
<hr>
|
||||
Upgrade Kosten:<br>
|
||||
${data.upgradeCost}
|
||||
`;
|
||||
if (!res.ok) throw new Error("API Fehler");
|
||||
|
||||
tooltip.style.display = "block";
|
||||
const data = await res.json();
|
||||
|
||||
tooltip.innerHTML = `
|
||||
<strong>${data.name}</strong><br>
|
||||
Level ${data.level}<br>
|
||||
Punkte ${data.points}/${data.nextLevelPoints}<br>
|
||||
<hr>
|
||||
Upgrade Kosten:<br>
|
||||
${data.upgradeCost}
|
||||
`;
|
||||
|
||||
tooltip.style.display = "block";
|
||||
} catch (err) {
|
||||
console.error("Tooltip Fehler:", err);
|
||||
}
|
||||
});
|
||||
|
||||
building.addEventListener("mousemove", (e) => {
|
||||
|
||||
@ -1,23 +1,28 @@
|
||||
const express = require("express");
|
||||
const router = express.Router();
|
||||
const auth = require("../middleware/auth");
|
||||
|
||||
router.get("/castle", (req, res) => {
|
||||
/* ================================
|
||||
Gebäude Seiten
|
||||
================================ */
|
||||
|
||||
router.get("/castle", auth, (req, res) => {
|
||||
res.render("buildings/castle");
|
||||
});
|
||||
|
||||
router.get("/market", (req, res) => {
|
||||
router.get("/market", auth, (req, res) => {
|
||||
res.render("buildings/market");
|
||||
});
|
||||
|
||||
router.get("/church", (req, res) => {
|
||||
router.get("/church", auth, (req, res) => {
|
||||
res.render("buildings/church");
|
||||
});
|
||||
|
||||
router.get("/portal", (req, res) => {
|
||||
router.get("/portal", auth, (req, res) => {
|
||||
res.render("buildings/portal");
|
||||
});
|
||||
|
||||
router.get("/tower", (req, res) => {
|
||||
router.get("/tower", auth, (req, res) => {
|
||||
res.render("buildings/tower");
|
||||
});
|
||||
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
const express = require("express");
|
||||
const router = express.Router();
|
||||
const auth = require("../middleware/auth");
|
||||
|
||||
router.get("/", (req, res) => {
|
||||
if (!req.session.user) {
|
||||
return res.redirect("/");
|
||||
}
|
||||
/* ================================
|
||||
Launcher Seite
|
||||
================================ */
|
||||
|
||||
router.get("/", auth, (req, res) => {
|
||||
res.render("launcher", {
|
||||
character: {
|
||||
name: req.session.user.username,
|
||||
@ -13,8 +14,4 @@ router.get("/", (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
router.get("/launcher-dev", (req, res) => {
|
||||
res.render("launcher-dev");
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@ -2,6 +2,7 @@ const express = require("express");
|
||||
const router = express.Router();
|
||||
const db = require("../database/database");
|
||||
const bcrypt = require("bcrypt");
|
||||
const crypto = require("crypto");
|
||||
|
||||
/* ================================
|
||||
Login verarbeiten
|
||||
@ -14,6 +15,7 @@ router.post("/", async (req, res) => {
|
||||
/* Server laden (für index.ejs) */
|
||||
const [servers] = await db.query("SELECT * FROM servers");
|
||||
|
||||
/* User laden */
|
||||
const [rows] = await db.query(
|
||||
"SELECT * FROM accounts WHERE username = ? AND verified = 1",
|
||||
[username],
|
||||
@ -28,6 +30,7 @@ router.post("/", async (req, res) => {
|
||||
|
||||
const user = rows[0];
|
||||
|
||||
/* Passwort prüfen */
|
||||
const passwordMatch = await bcrypt.compare(password, user.password);
|
||||
|
||||
if (!passwordMatch) {
|
||||
@ -37,25 +40,41 @@ router.post("/", async (req, res) => {
|
||||
});
|
||||
}
|
||||
|
||||
/* Session speichern */
|
||||
/* ================================
|
||||
Session Token erstellen
|
||||
================================= */
|
||||
|
||||
const sessionToken = crypto.randomBytes(64).toString("hex");
|
||||
|
||||
/* Token in DB speichern (überschreibt alten Login) */
|
||||
|
||||
await db.query("UPDATE accounts SET session_token = ? WHERE id = ?", [
|
||||
sessionToken,
|
||||
user.id,
|
||||
]);
|
||||
|
||||
/* ================================
|
||||
Session speichern
|
||||
================================= */
|
||||
|
||||
req.session.user = {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
token: sessionToken,
|
||||
};
|
||||
|
||||
/* Wenn kein Charaktername existiert */
|
||||
/* ================================
|
||||
Weiterleitung
|
||||
================================= */
|
||||
|
||||
if (!user.ingame_name) {
|
||||
return res.redirect("/create-character");
|
||||
}
|
||||
|
||||
/* Wenn Charakter existiert */
|
||||
|
||||
res.redirect("/launcher");
|
||||
return res.redirect("/launcher");
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.send("Login Fehler");
|
||||
console.error("Login Fehler:", error);
|
||||
res.status(500).send("Serverfehler beim Login");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Schloss</title>
|
||||
|
||||
<link rel="stylesheet" href="/css/building.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="building">
|
||||
<h1>Schloss</h1>
|
||||
|
||||
<p>Hier kannst du deine Charaktere verwalten.</p>
|
||||
|
||||
<a class="back" href="/launcher"> Zurück zur Karte </a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,7 +0,0 @@
|
||||
<div class="building">
|
||||
<h1>Kirche</h1>
|
||||
|
||||
<p>Segnungen und Heilungen.</p>
|
||||
|
||||
<a href="/launcher">Zurück zur Karte</a>
|
||||
</div>
|
||||
@ -1,7 +0,0 @@
|
||||
<div class="building">
|
||||
<h1>Marktplatz</h1>
|
||||
|
||||
<p>Hier kannst du Items kaufen.</p>
|
||||
|
||||
<a href="/launcher">Zurück zur Karte</a>
|
||||
</div>
|
||||
@ -1,7 +0,0 @@
|
||||
<div class="building">
|
||||
<h1>Portal</h1>
|
||||
|
||||
<p>Dungeon Zugang.</p>
|
||||
|
||||
<a href="/launcher">Zurück zur Karte</a>
|
||||
</div>
|
||||
@ -1,7 +0,0 @@
|
||||
<div class="building">
|
||||
<h1>Turm</h1>
|
||||
|
||||
<p>PvP Arena.</p>
|
||||
|
||||
<a href="/launcher">Zurück zur Karte</a>
|
||||
</div>
|
||||
Loading…
Reference in New Issue
Block a user