Files
desktop/public/auth/register/index.php
Lars Gebhardt-Kusche 5408a2bb89
All checks were successful
Deploy / deploy-staging (push) Successful in 26s
Deploy / deploy-production (push) Has been skipped
adasd
2026-06-15 21:36:36 +02:00

195 lines
9.8 KiB
PHP

<?php
declare(strict_types=1);
require_once dirname(__DIR__, 3) . '/src/App/bootstrap.php';
use App\ConfigLoader;
use App\PublicFormProtection;
use App\RegistrationService;
session_start();
$projectRoot = dirname(__DIR__, 3);
$registrationConfig = ConfigLoader::load($projectRoot, 'registration');
$registration = new RegistrationService($projectRoot, $registrationConfig);
$formProtection = new PublicFormProtection($projectRoot, $registrationConfig);
if (!$registration->isEnabled()) {
http_response_code(404);
echo 'Registrierung ist deaktiviert.';
exit;
}
$csrfToken = (string) ($_SESSION['registration_form_token'] ?? '');
if ($csrfToken === '') {
$csrfToken = bin2hex(random_bytes(16));
$_SESSION['registration_form_token'] = $csrfToken;
}
$errors = [];
$honeypotField = $formProtection->honeypotField();
$form = [
'username' => '',
'given_name' => '',
'family_name' => '',
'email' => '',
'note' => '',
'password' => '',
'password_confirm' => '',
];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$form = [
'username' => trim((string) ($_POST['username'] ?? '')),
'given_name' => trim((string) ($_POST['given_name'] ?? '')),
'family_name' => trim((string) ($_POST['family_name'] ?? '')),
'email' => trim((string) ($_POST['email'] ?? '')),
'note' => trim((string) ($_POST['note'] ?? '')),
'password' => (string) ($_POST['password'] ?? ''),
'password_confirm' => (string) ($_POST['password_confirm'] ?? ''),
];
$postedToken = (string) ($_POST['csrf_token'] ?? '');
if ($postedToken === '' || !hash_equals($csrfToken, $postedToken)) {
$errors[] = 'Die Formularprüfung ist fehlgeschlagen. Bitte versuche es erneut.';
} else {
$protection = $formProtection->guard('registration', $_POST);
if (!($protection['success'] ?? false)) {
$errors = array_values(array_map('strval', (array) ($protection['errors'] ?? [])));
} else {
$result = $registration->submit($form);
if (($result['success'] ?? false) !== true) {
$errors = array_values(array_map('strval', (array) ($result['errors'] ?? [])));
} else {
$createdRequest = is_array($result['request'] ?? null) ? $result['request'] : [];
$_SESSION['registration_confirmation'] = [
'id' => (string) ($createdRequest['id'] ?? ''),
'username' => (string) ($createdRequest['username'] ?? ''),
'email' => (string) ($createdRequest['email'] ?? ''),
];
$csrfToken = bin2hex(random_bytes(16));
$_SESSION['registration_form_token'] = $csrfToken;
header('Location: /auth/register/confirmation/', true, 302);
exit;
}
}
}
}
?><!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Registrierung anfragen</title>
<link rel="stylesheet" href="/assets/auth/login.css">
</head>
<body>
<main class="login-shell">
<section class="login-panel login-panel-wide">
<div class="login-panel-top">
<p class="login-kicker">Kusche.Berlin</p>
<h1>Registrierung anfragen</h1>
<p class="login-copy">Erstelle deinen Zugang für den persönlichen Desktop-Bereich von Kusche.Berlin. Nach dem Absenden kannst du alle weiteren Schritte direkt von hier aus verfolgen.</p>
</div>
<?php if ($errors !== []): ?>
<div class="login-notice login-notice-error">
<strong>Bitte prüfen</strong>
<ul class="login-list">
<?php foreach ($errors as $error): ?>
<li><?= htmlspecialchars($error, ENT_QUOTES) ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<form class="login-form" method="post" action="/auth/register/">
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($csrfToken, ENT_QUOTES) ?>">
<div class="login-honeypot" aria-hidden="true">
<label>
<span>Website</span>
<input type="text" name="<?= htmlspecialchars($honeypotField, ENT_QUOTES) ?>" value="" tabindex="-1" autocomplete="off">
</label>
</div>
<div class="login-form-grid">
<label class="login-field">
<span>Benutzername</span>
<input type="text" name="username" value="<?= htmlspecialchars($form['username'], ENT_QUOTES) ?>" required>
</label>
<label class="login-field">
<span>E-Mail</span>
<input type="email" name="email" value="<?= htmlspecialchars($form['email'], ENT_QUOTES) ?>" required>
</label>
<label class="login-field">
<span>Vorname</span>
<input type="text" name="given_name" value="<?= htmlspecialchars($form['given_name'], ENT_QUOTES) ?>" required>
</label>
<label class="login-field">
<span>Nachname</span>
<input type="text" name="family_name" value="<?= htmlspecialchars($form['family_name'], ENT_QUOTES) ?>" required>
</label>
</div>
<div class="login-form-grid">
<label class="login-field">
<span>Passwort</span>
<div class="login-password-row">
<input type="password" name="password" value="<?= htmlspecialchars($form['password'], ENT_QUOTES) ?>" required data-password-field>
<button class="login-password-toggle" type="button" data-password-toggle aria-label="Passwort anzeigen">
<svg class="login-password-icon login-password-icon-show" viewBox="0 0 24 24" aria-hidden="true">
<path d="M2 12s3.6-6 10-6 10 6 10 6-3.6 6-10 6-10-6-10-6Z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="12" cy="12" r="3" fill="none" stroke="currentColor" stroke-width="1.8"/>
</svg>
<svg class="login-password-icon login-password-icon-hide" viewBox="0 0 24 24" aria-hidden="true">
<path d="M3 3l18 18" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
<path d="M10.6 5.2A11 11 0 0 1 12 5c6.4 0 10 7 10 7a18.8 18.8 0 0 1-3.1 3.8M6.7 6.7C4 8.5 2 12 2 12a18.4 18.4 0 0 0 10 6 10.8 10.8 0 0 0 4.1-.8" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9.9 9.9A3 3 0 0 0 14.1 14.1" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
</svg>
</button>
</div>
</label>
<label class="login-field">
<span>Passwort wiederholen</span>
<div class="login-password-row">
<input type="password" name="password_confirm" value="<?= htmlspecialchars($form['password_confirm'], ENT_QUOTES) ?>" required data-password-field>
<button class="login-password-toggle" type="button" data-password-toggle aria-label="Passwort anzeigen">
<svg class="login-password-icon login-password-icon-show" viewBox="0 0 24 24" aria-hidden="true">
<path d="M2 12s3.6-6 10-6 10 6 10 6-3.6 6-10 6-10-6-10-6Z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="12" cy="12" r="3" fill="none" stroke="currentColor" stroke-width="1.8"/>
</svg>
<svg class="login-password-icon login-password-icon-hide" viewBox="0 0 24 24" aria-hidden="true">
<path d="M3 3l18 18" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
<path d="M10.6 5.2A11 11 0 0 1 12 5c6.4 0 10 7 10 7a18.8 18.8 0 0 1-3.1 3.8M6.7 6.7C4 8.5 2 12 2 12a18.4 18.4 0 0 0 10 6 10.8 10.8 0 0 0 4.1-.8" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9.9 9.9A3 3 0 0 0 14.1 14.1" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
</svg>
</button>
</div>
</label>
</div>
<label class="login-field">
<span>Hinweise für Freischaltung</span>
<textarea name="note" rows="4" placeholder="Optional: Zusätzliche Hinweise zu dir oder deinem Zugangswunsch."><?= htmlspecialchars($form['note'], ENT_QUOTES) ?></textarea>
</label>
<div class="login-actions">
<button class="login-button login-button-primary" type="submit">Registrierung absenden</button>
<a class="login-button login-button-secondary" href="/auth/keycloak">Zurück zum Login</a>
</div>
</form>
</section>
</main>
<script src="/assets/auth/password-visibility.js"></script>
</body>
</html>