Initialer Commit

This commit is contained in:
2026-03-01 19:40:49 +01:00
commit 5dc408add8
255 changed files with 16104 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
# Datasource
spring.datasource.url=jdbc:mysql://localhost:3306/xxxthegame?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
spring.datasource.username=${DB_USER:xxx}
spring.datasource.password=${DB_PASSWORD:xxxthegame$123!}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# JPA / Hibernate
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.properties.hibernate.type.preferred_uuid_jdbc_type=VARCHAR
# Mail
spring.mail.host=${MAIL_HOST:localhost}
spring.mail.port=${MAIL_PORT:25}
spring.mail.username=${MAIL_USER:}
spring.mail.password=${MAIL_PASSWORD:}
spring.mail.properties.mail.smtp.auth=false
spring.mail.properties.mail.smtp.starttls.enable=false
# JWT Keystore
jwt.keystore.path=classpath:xxx.jks
jwt.keystore.password=${JWT_KEYSTORE_PASSWORD:XUR!Rv&f$j3UsqD&}
jwt.keystore.alias=xxx
# Server
server.port=8080

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,256 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>XXX The Game Login</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #1a1a2e;
font-family: 'Segoe UI', sans-serif;
color: #eee;
}
.card {
background: #16213e;
border: 1px solid #0f3460;
border-radius: 12px;
padding: 2.5rem;
width: 100%;
max-width: 380px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
}
h1 {
text-align: center;
font-size: 1.6rem;
margin-bottom: 0.25rem;
color: #e94560;
}
.subtitle {
text-align: center;
font-size: 0.85rem;
color: #888;
margin-bottom: 2rem;
}
label {
display: block;
font-size: 0.8rem;
color: #aaa;
margin-bottom: 0.3rem;
margin-top: 1rem;
}
input {
width: 100%;
padding: 0.65rem 0.9rem;
border: 1px solid #0f3460;
border-radius: 6px;
background: #0f3460;
color: #eee;
font-size: 1rem;
outline: none;
transition: border-color 0.2s;
}
input:focus {
border-color: #e94560;
}
button {
margin-top: 1.75rem;
width: 100%;
padding: 0.75rem;
background: #e94560;
color: #fff;
border: none;
border-radius: 6px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: background 0.2s;
}
button:hover:not(:disabled) {
background: #c73652;
}
button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.message {
margin-top: 1.25rem;
padding: 0.65rem 0.9rem;
border-radius: 6px;
font-size: 0.85rem;
display: none;
word-break: break-all;
}
.message.error {
background: #3d0f1a;
border: 1px solid #e94560;
color: #e94560;
}
.message.success {
background: #0f3d1a;
border: 1px solid #2ecc71;
color: #2ecc71;
}
.token-box {
margin-top: 1.25rem;
padding: 0.65rem 0.9rem;
background: #0f1e3d;
border: 1px solid #0f3460;
border-radius: 6px;
font-size: 0.75rem;
color: #aaa;
word-break: break-all;
display: none;
}
.token-box span {
display: block;
font-size: 0.7rem;
color: #666;
margin-bottom: 0.4rem;
}
.copy-btn {
margin-top: 0.5rem;
width: auto;
padding: 0.3rem 0.7rem;
font-size: 0.75rem;
background: #0f3460;
font-weight: normal;
}
.copy-btn:hover {
background: #1a4a8a;
}
</style>
</head>
<body>
<div class="card">
<h1>XXX The Game</h1>
<p class="subtitle">Bitte melde dich an</p>
<label for="email">E-Mail</label>
<input type="email" id="email" placeholder="deine@email.de" autocomplete="username" />
<label for="password">Passwort</label>
<input type="password" id="password" placeholder="••••••••" autocomplete="current-password" />
<button id="loginBtn" onclick="login()">Anmelden</button>
<div class="message" id="message"></div>
<div class="token-box" id="tokenBox">
<span>JWT Token</span>
<div id="tokenText"></div>
<button class="copy-btn" onclick="copyToken()">Kopieren</button>
</div>
</div>
<script>
let currentToken = null;
document.addEventListener('keydown', e => {
if (e.key === 'Enter') login();
});
async function sha256(text) {
const encoder = new TextEncoder();
const data = encoder.encode(text);
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
async function login() {
const email = document.getElementById('email').value.trim();
const password = document.getElementById('password').value;
const btn = document.getElementById('loginBtn');
if (!email || !password) {
showMessage('Bitte E-Mail und Passwort eingeben.', 'error');
return;
}
btn.disabled = true;
btn.textContent = 'Wird geprüft…';
hideMessage();
hideToken();
try {
const hash = await sha256(password);
const url = `/login?email=${encodeURIComponent(email)}&hash=${encodeURIComponent(hash)}`;
const response = await fetch(url, { method: 'GET' });
if (response.ok) {
currentToken = await response.text();
showMessage('Login erfolgreich!', 'success');
showToken(currentToken);
} else if (response.status === 204) {
showMessage('E-Mail oder Passwort falsch.', 'error');
} else {
showMessage(`Fehler: HTTP ${response.status}`, 'error');
}
} catch (err) {
showMessage('Server nicht erreichbar.', 'error');
console.error(err);
} finally {
btn.disabled = false;
btn.textContent = 'Anmelden';
}
}
function showMessage(text, type) {
const el = document.getElementById('message');
el.textContent = text;
el.className = `message ${type}`;
el.style.display = 'block';
}
function hideMessage() {
document.getElementById('message').style.display = 'none';
}
function showToken(token) {
document.getElementById('tokenText').textContent = token;
document.getElementById('tokenBox').style.display = 'block';
}
function hideToken() {
document.getElementById('tokenBox').style.display = 'none';
currentToken = null;
}
function copyToken() {
if (currentToken) {
navigator.clipboard.writeText(currentToken).then(() => {
const btn = document.querySelector('.copy-btn');
btn.textContent = 'Kopiert!';
setTimeout(() => btn.textContent = 'Kopieren', 1500);
});
}
}
</script>
</body>
</html>

Binary file not shown.