login und weiterleitung zum spieltfeld

This commit is contained in:
Cay 2026-03-11 16:48:47 +00:00
parent 0b0ef6e6ed
commit 4a03effdf7
7 changed files with 249 additions and 22 deletions

15
app.js
View File

@ -8,6 +8,10 @@ const rateLimit = require("express-rate-limit");
const serverRoutes = require("./routes/servers");
const registerRoutes = require("./routes/register");
const verifyRoutes = require("./routes/verify");
const characterRoutes = require("./routes/character");
const session = require("express-session");
const loginRoutes = require("./routes/login");
const launcherRoutes = require("./routes/launcher");
const app = express();
const PORT = process.env.PORT || 3000;
@ -29,6 +33,14 @@ const limiter = rateLimit({
app.use(limiter);
app.use(
session({
secret: "dynastyofknights_secret",
resave: false,
saveUninitialized: false,
}),
);
/* ========================
Express Settings
======================== */
@ -56,6 +68,9 @@ app.use(express.static(path.join(__dirname, "public")));
app.use("/", serverRoutes);
app.use("/register", registerRoutes);
app.use("/verify", verifyRoutes);
app.use("/create-character", characterRoutes);
app.use("/login", loginRoutes);
app.use("/launcher", launcherRoutes);
/* ========================
404 Handler

BIN
public/images/dok_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 MiB

48
routes/character.js Normal file
View File

@ -0,0 +1,48 @@
const express = require("express");
const router = express.Router();
const db = require("../database/database");
/* Character erstellen Seite */
router.get("/", (req, res) => {
if (!req.session.user) {
return res.redirect("/");
}
res.render("create-character");
});
/* Character speichern */
router.post("/", async (req, res) => {
const { ingame_name } = req.body;
const userId = req.session.user.id;
const nameRegex = /^[a-zA-Z0-9_]{3,16}$/;
if (!nameRegex.test(ingame_name)) {
return res.render("create-character", {
error: "Ungültiger Name",
});
}
const [existing] = await db.query(
"SELECT id FROM accounts WHERE ingame_name = ?",
[ingame_name],
);
if (existing.length > 0) {
return res.render("create-character", {
error: "Name bereits vergeben",
});
}
await db.query("UPDATE accounts SET ingame_name = ? WHERE id = ?", [
ingame_name,
userId,
]);
res.redirect("/launcher");
});
module.exports = router;

12
routes/launcher.js Normal file
View File

@ -0,0 +1,12 @@
const express = require("express");
const router = express.Router();
router.get("/", (req, res) => {
if (!req.session.user) {
return res.redirect("/");
}
res.render("launcher");
});
module.exports = router;

57
routes/login.js Normal file
View File

@ -0,0 +1,57 @@
const express = require("express");
const router = express.Router();
const db = require("../database/database");
const bcrypt = require("bcrypt");
/* ================================
Login verarbeiten
================================ */
router.post("/", async (req, res) => {
const { username, password } = req.body;
try {
const [rows] = await db.query(
"SELECT * FROM accounts WHERE username = ? AND verified = 1",
[username],
);
if (rows.length === 0) {
return res.render("index", {
error: "Login fehlgeschlagen",
});
}
const user = rows[0];
const passwordMatch = await bcrypt.compare(password, user.password);
if (!passwordMatch) {
return res.render("index", {
error: "Login fehlgeschlagen",
});
}
/* Session speichern */
req.session.user = {
id: user.id,
username: user.username,
};
/* Wenn kein Charaktername existiert */
if (!user.ingame_name) {
return res.redirect("/create-character");
}
/* Wenn Charakter existiert */
res.redirect("/launcher");
} catch (error) {
console.error(error);
res.send("Login Fehler");
}
});
module.exports = router;

View File

@ -0,0 +1,85 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Charakter erstellen</title>
<style>
body{
margin:0;
height:100vh;
background:url("/images/background_login.png") center / cover no-repeat;
display:flex;
justify-content:center;
align-items:center;
font-family:sans-serif;
color:white;
}
.box{
background:rgba(0,0,0,0.7);
padding:40px;
border-radius:10px;
text-align:center;
width:400px;
}
input{
width:100%;
padding:12px;
margin-top:10px;
}
button{
margin-top:15px;
padding:12px;
width:100%;
}
.error{
color:red;
margin-bottom:10px;
}
</style>
</head>
<body>
<div class="box">
<h2>Wähle deinen Charakternamen</h2>
<% if (typeof error !== "undefined") { %>
<div class="error"><%= error %></div>
<% } %>
<form action="/create-character" method="POST">
<input type="text" name="ingame_name" placeholder="Charaktername" required>
<button type="submit">
Charakter erstellen
</button>
</form>
</div>
</body>
</html>

View File

@ -159,34 +159,43 @@
</head>
<body>
<div class="fog"></div>
<div class="fog"></div>
<div class="launcher">
<select>
<% servers.forEach(server => { %>
<option value="<%= server.id %>">
<%= server.name %>
</option>
<% }) %>
<div class="launcher">
<form action="/login" method="POST">
<select name="server_id">
<% servers.forEach(server => { %>
<option value="<%= server.id %>">
<%= server.name %>
</option>
<% }) %>
<% extraServers.forEach(server => { %>
<option disabled>
<%= server.name %> (Offline)
</option>
<% }) %>
<% extraServers.forEach(server => { %>
<option disabled>
<%= server.name %> (Offline)
</option>
<% }) %>
</select>
<input type="text" placeholder="Username" />
<input type="text" name="username" placeholder="Username" required />
<input type="password" placeholder="Password" />
<input type="password" name="password" placeholder="Password" required />
<button class="login">Login</button>
<button type="submit" class="login">
Login
</button>
<a class="register" href="/register">
Account registrieren
</a>
</form>
<div class="server-status">
<a class="register" href="/register">
Account registrieren
</a>
<div class="server-status">
<% servers.forEach(server => { %>
<%= server.name %>:
@ -198,7 +207,8 @@
<span class="offline">Offline</span><br>
<% }) %>
</div>
</div>
</body>
</div>
</body>
</html>