asdsad
This commit is contained in:
222
public/admin/registrations/index.php
Normal file
222
public/admin/registrations/index.php
Normal file
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once dirname(__DIR__, 3) . '/src/App/bootstrap.php';
|
||||
|
||||
use App\ConfigLoader;
|
||||
use App\RegistrationAccess;
|
||||
use App\RegistrationService;
|
||||
|
||||
session_start();
|
||||
|
||||
$projectRoot = dirname(__DIR__, 3);
|
||||
$config = ConfigLoader::load($projectRoot, 'registration');
|
||||
$registration = new RegistrationService($projectRoot, $config);
|
||||
$access = new RegistrationAccess($config);
|
||||
|
||||
if (!$access->canManage()) {
|
||||
http_response_code(403);
|
||||
echo 'Kein Zugriff auf Registrierungsfreigaben.';
|
||||
exit;
|
||||
}
|
||||
|
||||
$csrfToken = (string) ($_SESSION['registration_admin_token'] ?? '');
|
||||
|
||||
if ($csrfToken === '') {
|
||||
$csrfToken = bin2hex(random_bytes(16));
|
||||
$_SESSION['registration_admin_token'] = $csrfToken;
|
||||
}
|
||||
|
||||
$currentUser = is_array($_SESSION['desktop_auth']['user'] ?? null) ? $_SESSION['desktop_auth']['user'] : [];
|
||||
$reviewer = (string) ($currentUser['username'] ?? 'unbekannt');
|
||||
$selectedId = trim((string) ($_GET['id'] ?? $_POST['id'] ?? ''));
|
||||
$errors = [];
|
||||
$notice = null;
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$postedToken = (string) ($_POST['csrf_token'] ?? '');
|
||||
|
||||
if ($postedToken === '' || !hash_equals($csrfToken, $postedToken)) {
|
||||
$errors[] = 'Die Formularprüfung ist fehlgeschlagen.';
|
||||
} else {
|
||||
$action = (string) ($_POST['action'] ?? '');
|
||||
|
||||
if ($action === 'approve') {
|
||||
$result = $registration->approve($selectedId, array_map('strval', $_POST), $reviewer);
|
||||
|
||||
if (($result['success'] ?? false) !== true) {
|
||||
$errors = array_values(array_map('strval', (array) ($result['errors'] ?? [])));
|
||||
} else {
|
||||
$notice = 'Registrierung freigegeben. Ein LDIF-Entwurf für den inaktiven Benutzer wurde erzeugt.';
|
||||
}
|
||||
} elseif ($action === 'reject') {
|
||||
$result = $registration->reject($selectedId, (string) ($_POST['reject_reason'] ?? ''), $reviewer);
|
||||
|
||||
if (($result['success'] ?? false) !== true) {
|
||||
$errors = array_values(array_map('strval', (array) ($result['errors'] ?? [])));
|
||||
} else {
|
||||
$notice = 'Registrierung abgelehnt.';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$requests = $registration->all();
|
||||
$selected = $selectedId !== '' ? $registration->find($selectedId) : ($requests[0] ?? null);
|
||||
$provisioning = is_array($selected['provisioning'] ?? null) ? $selected['provisioning'] : [];
|
||||
?><!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Registrierungsfreigaben</title>
|
||||
<link rel="stylesheet" href="/assets/auth/login.css">
|
||||
</head>
|
||||
<body>
|
||||
<main class="login-shell">
|
||||
<section class="login-panel login-panel-admin">
|
||||
<div class="login-panel-top">
|
||||
<p class="login-kicker">Kusche.Berlin</p>
|
||||
<h1>Registrierungsfreigaben</h1>
|
||||
<p class="login-copy">Anfragen werden erst nach Prüfung für LDAP und NAS vorbereitet. Die Freigabe erzeugt aktuell einen LDIF-Entwurf für einen inaktiven Benutzer.</p>
|
||||
</div>
|
||||
|
||||
<?php if ($notice !== null): ?>
|
||||
<div class="login-notice login-notice-success">
|
||||
<strong>Aktion abgeschlossen</strong>
|
||||
<p><?= htmlspecialchars($notice, ENT_QUOTES) ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?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; ?>
|
||||
|
||||
<div class="admin-layout">
|
||||
<aside class="admin-sidebar">
|
||||
<h2>Offene Vorgänge</h2>
|
||||
<div class="admin-request-list">
|
||||
<?php foreach ($requests as $request): ?>
|
||||
<a class="admin-request-card<?= (($selected['id'] ?? '') === ($request['id'] ?? '')) ? ' is-active' : '' ?>" href="/admin/registrations/?id=<?= urlencode((string) ($request['id'] ?? '')) ?>">
|
||||
<strong><?= htmlspecialchars((string) ($request['username'] ?? ''), ENT_QUOTES) ?></strong>
|
||||
<span><?= htmlspecialchars((string) ($request['email'] ?? ''), ENT_QUOTES) ?></span>
|
||||
<span class="admin-status admin-status-<?= htmlspecialchars((string) ($request['status'] ?? 'pending'), ENT_QUOTES) ?>">
|
||||
<?= htmlspecialchars((string) ($request['status'] ?? 'pending'), ENT_QUOTES) ?>
|
||||
</span>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<section class="admin-detail">
|
||||
<?php if (!is_array($selected)): ?>
|
||||
<div class="login-notice login-notice-info">
|
||||
<strong>Keine Anfragen vorhanden</strong>
|
||||
<p>Es liegt aktuell keine Registrierungsanfrage vor.</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="admin-summary">
|
||||
<h2><?= htmlspecialchars((string) ($selected['display_name'] ?? $selected['username'] ?? ''), ENT_QUOTES) ?></h2>
|
||||
<p>Status: <strong><?= htmlspecialchars((string) ($selected['status'] ?? 'pending'), ENT_QUOTES) ?></strong></p>
|
||||
<p>Benutzername: <?= htmlspecialchars((string) ($selected['username'] ?? ''), ENT_QUOTES) ?></p>
|
||||
<p>E-Mail: <?= htmlspecialchars((string) ($selected['email'] ?? ''), ENT_QUOTES) ?></p>
|
||||
<p>Angelegt: <?= htmlspecialchars((string) ($selected['created_at'] ?? ''), ENT_QUOTES) ?></p>
|
||||
<?php if (((string) ($selected['note'] ?? '')) !== ''): ?>
|
||||
<p>Zusatzinfo: <?= nl2br(htmlspecialchars((string) ($selected['note'] ?? ''), ENT_QUOTES)) ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<form class="login-form" method="post" action="/admin/registrations">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($csrfToken, ENT_QUOTES) ?>">
|
||||
<input type="hidden" name="id" value="<?= htmlspecialchars((string) ($selected['id'] ?? ''), ENT_QUOTES) ?>">
|
||||
|
||||
<div class="login-form-grid">
|
||||
<label class="login-field">
|
||||
<span>uidNumber</span>
|
||||
<input type="text" name="uid_number" value="<?= htmlspecialchars((string) ($provisioning['uid_number'] ?? ''), ENT_QUOTES) ?>" required>
|
||||
</label>
|
||||
|
||||
<label class="login-field">
|
||||
<span>gidNumber</span>
|
||||
<input type="text" name="gid_number" value="<?= htmlspecialchars((string) ($provisioning['gid_number'] ?? ''), ENT_QUOTES) ?>" required>
|
||||
</label>
|
||||
|
||||
<label class="login-field">
|
||||
<span>homeDirectory</span>
|
||||
<input type="text" name="home_directory" value="<?= htmlspecialchars((string) ($provisioning['home_directory'] ?? ('/home/' . ($selected['username'] ?? ''))), ENT_QUOTES) ?>" required>
|
||||
</label>
|
||||
|
||||
<label class="login-field">
|
||||
<span>loginShell</span>
|
||||
<input type="text" name="login_shell" value="<?= htmlspecialchars((string) ($provisioning['login_shell'] ?? '/bin/sh'), ENT_QUOTES) ?>">
|
||||
</label>
|
||||
|
||||
<label class="login-field">
|
||||
<span>Display Name</span>
|
||||
<input type="text" name="display_name" value="<?= htmlspecialchars((string) ($provisioning['display_name'] ?? $selected['display_name'] ?? ''), ENT_QUOTES) ?>">
|
||||
</label>
|
||||
|
||||
<label class="login-field">
|
||||
<span>CN</span>
|
||||
<input type="text" name="cn" value="<?= htmlspecialchars((string) ($provisioning['cn'] ?? $selected['display_name'] ?? $selected['username'] ?? ''), ENT_QUOTES) ?>">
|
||||
</label>
|
||||
|
||||
<label class="login-field">
|
||||
<span>GECOS</span>
|
||||
<input type="text" name="gecos" value="<?= htmlspecialchars((string) ($provisioning['gecos'] ?? $selected['display_name'] ?? ''), ENT_QUOTES) ?>">
|
||||
</label>
|
||||
|
||||
<label class="login-field">
|
||||
<span>apple-generateduid</span>
|
||||
<input type="text" name="apple_generateduid" value="<?= htmlspecialchars((string) ($provisioning['apple_generateduid'] ?? ''), ENT_QUOTES) ?>">
|
||||
</label>
|
||||
|
||||
<label class="login-field">
|
||||
<span>sambaSID</span>
|
||||
<input type="text" name="samba_sid" value="<?= htmlspecialchars((string) ($provisioning['samba_sid'] ?? ''), ENT_QUOTES) ?>">
|
||||
</label>
|
||||
|
||||
<label class="login-field login-field-span-2">
|
||||
<span>memberOf als CSV</span>
|
||||
<input type="text" name="member_of_csv" value="<?= htmlspecialchars((string) ($provisioning['member_of_csv'] ?? 'cn=generaluser,cn=groups,dc=nas,dc=kusche,dc=berlin'), ENT_QUOTES) ?>">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<label class="login-field">
|
||||
<span>Admin-Notiz</span>
|
||||
<textarea name="admin_note" rows="4"><?= htmlspecialchars((string) ($provisioning['admin_note'] ?? ''), ENT_QUOTES) ?></textarea>
|
||||
</label>
|
||||
|
||||
<div class="login-actions">
|
||||
<button class="login-button login-button-primary" type="submit" name="action" value="approve">Freigeben und LDIF erzeugen</button>
|
||||
<button class="login-button login-button-danger" type="submit" name="action" value="reject">Ablehnen</button>
|
||||
</div>
|
||||
|
||||
<label class="login-field">
|
||||
<span>Ablehnungsgrund</span>
|
||||
<textarea name="reject_reason" rows="3" placeholder="Nur erforderlich, wenn du auf Ablehnen klickst."></textarea>
|
||||
</label>
|
||||
</form>
|
||||
|
||||
<?php if (((string) ($provisioning['ldif_path'] ?? '')) !== '' && is_file((string) $provisioning['ldif_path'])): ?>
|
||||
<div class="login-notice login-notice-info">
|
||||
<strong>LDIF-Entwurf</strong>
|
||||
<p><?= htmlspecialchars((string) ($provisioning['ldif_path'] ?? ''), ENT_QUOTES) ?></p>
|
||||
<pre class="login-pre"><?= htmlspecialchars((string) file_get_contents((string) $provisioning['ldif_path']), ENT_QUOTES) ?></pre>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -33,6 +33,14 @@ body {
|
||||
backdrop-filter: blur(24px);
|
||||
}
|
||||
|
||||
.login-panel-wide {
|
||||
width: min(760px, 100%);
|
||||
}
|
||||
|
||||
.login-panel-admin {
|
||||
width: min(1180px, 100%);
|
||||
}
|
||||
|
||||
.login-panel-top {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
@@ -72,6 +80,9 @@ body {
|
||||
border-radius: 14px;
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
.login-button-primary {
|
||||
@@ -91,12 +102,189 @@ body {
|
||||
border: 1px dashed rgba(255, 255, 255, 0.18);
|
||||
}
|
||||
|
||||
.login-button-danger {
|
||||
color: #fff1f2;
|
||||
background: linear-gradient(180deg, #fb7185, #e11d48);
|
||||
}
|
||||
|
||||
.login-form {
|
||||
display: grid;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.login-form-grid {
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.login-field {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.login-field span {
|
||||
font-size: 13px;
|
||||
color: #cbd5e1;
|
||||
}
|
||||
|
||||
.login-field input,
|
||||
.login-field textarea {
|
||||
width: 100%;
|
||||
min-height: 48px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 14px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.14);
|
||||
background: rgba(15, 23, 42, 0.52);
|
||||
color: #f8fafc;
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
.login-field textarea {
|
||||
min-height: 120px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.login-field-span-2 {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
.login-notice {
|
||||
margin-bottom: 18px;
|
||||
padding: 16px 18px;
|
||||
border-radius: 18px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
.login-notice strong {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.login-notice p {
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.login-notice-success {
|
||||
background: rgba(20, 83, 45, 0.45);
|
||||
}
|
||||
|
||||
.login-notice-error {
|
||||
background: rgba(127, 29, 29, 0.4);
|
||||
}
|
||||
|
||||
.login-notice-info {
|
||||
background: rgba(30, 41, 59, 0.5);
|
||||
}
|
||||
|
||||
.login-list {
|
||||
margin: 0;
|
||||
padding-left: 18px;
|
||||
}
|
||||
|
||||
.login-list li + li {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.login-meta-inline {
|
||||
margin-top: 8px !important;
|
||||
font-size: 0.92rem;
|
||||
color: #cbd5e1;
|
||||
}
|
||||
|
||||
.login-meta {
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.admin-layout {
|
||||
display: grid;
|
||||
gap: 24px;
|
||||
grid-template-columns: 320px minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.admin-sidebar h2,
|
||||
.admin-summary h2 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.admin-request-list {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
max-height: 70vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.admin-request-card {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
padding: 14px;
|
||||
border-radius: 16px;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.admin-request-card.is-active {
|
||||
border-color: rgba(167, 243, 208, 0.56);
|
||||
background: rgba(16, 185, 129, 0.12);
|
||||
}
|
||||
|
||||
.admin-request-card span {
|
||||
color: #cbd5e1;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
.admin-status {
|
||||
display: inline-flex;
|
||||
width: fit-content;
|
||||
padding: 4px 10px;
|
||||
border-radius: 999px;
|
||||
color: #e2e8f0 !important;
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
.admin-detail {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.admin-summary {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.admin-summary p {
|
||||
margin: 0 0 10px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.login-pre {
|
||||
margin: 12px 0 0;
|
||||
padding: 14px;
|
||||
border-radius: 14px;
|
||||
overflow: auto;
|
||||
background: rgba(2, 6, 23, 0.65);
|
||||
color: #dbeafe;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.admin-layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.login-form-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.login-field-span-2 {
|
||||
grid-column: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.login-meta div {
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
|
||||
@@ -18,6 +18,7 @@ $previewUrl = $auth->allowDesktopPreview()
|
||||
$loginScreen = [
|
||||
'branding' => $auth->branding(),
|
||||
'login_url' => $auth->isConfigured() ? '/auth/keycloak' : null,
|
||||
'register_url' => '/auth/register',
|
||||
'preview_url' => $previewUrl,
|
||||
'keycloak_ready' => $auth->isConfigured(),
|
||||
'callback_url' => $auth->redirectUri(),
|
||||
|
||||
153
public/auth/register/index.php
Normal file
153
public/auth/register/index.php
Normal file
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once dirname(__DIR__, 3) . '/src/App/bootstrap.php';
|
||||
|
||||
use App\ConfigLoader;
|
||||
use App\RegistrationService;
|
||||
|
||||
session_start();
|
||||
|
||||
$projectRoot = dirname(__DIR__, 3);
|
||||
$registration = new RegistrationService($projectRoot, ConfigLoader::load($projectRoot, 'registration'));
|
||||
|
||||
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 = [];
|
||||
$submitted = false;
|
||||
$createdRequest = null;
|
||||
$form = [
|
||||
'username' => '',
|
||||
'given_name' => '',
|
||||
'family_name' => '',
|
||||
'email' => '',
|
||||
'note' => '',
|
||||
];
|
||||
|
||||
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'] ?? '')),
|
||||
];
|
||||
|
||||
$postedToken = (string) ($_POST['csrf_token'] ?? '');
|
||||
|
||||
if ($postedToken === '' || !hash_equals($csrfToken, $postedToken)) {
|
||||
$errors[] = 'Die Formularprüfung ist fehlgeschlagen. Bitte versuche es erneut.';
|
||||
} else {
|
||||
$result = $registration->submit($form);
|
||||
|
||||
if (($result['success'] ?? false) !== true) {
|
||||
$errors = array_values(array_map('strval', (array) ($result['errors'] ?? [])));
|
||||
} else {
|
||||
$submitted = true;
|
||||
$createdRequest = $result['request'] ?? null;
|
||||
$csrfToken = bin2hex(random_bytes(16));
|
||||
$_SESSION['registration_form_token'] = $csrfToken;
|
||||
$form = [
|
||||
'username' => '',
|
||||
'given_name' => '',
|
||||
'family_name' => '',
|
||||
'email' => '',
|
||||
'note' => '',
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
?><!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">Neue Konten werden nicht sofort freigeschaltet. Deine Anfrage wird geprüft und erst danach für LDAP, NAS und Desktop vorbereitet.</p>
|
||||
</div>
|
||||
|
||||
<?php if ($submitted): ?>
|
||||
<div class="login-notice login-notice-success">
|
||||
<strong>Anfrage gespeichert.</strong>
|
||||
<p>Dein Zugang wurde noch nicht freigeschaltet. Eine berechtigte Person prüft nun die Registrierung.</p>
|
||||
<?php if (is_array($createdRequest)): ?>
|
||||
<p class="login-meta-inline">Vorgangs-ID: <?= htmlspecialchars((string) ($createdRequest['id'] ?? ''), ENT_QUOTES) ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?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-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>
|
||||
|
||||
<label class="login-field">
|
||||
<span>Zusätzliche Info</span>
|
||||
<textarea name="note" rows="5" placeholder="Optional: Bezug zur Familie, Einladung, gewünschte Nutzung, Rückfragekontakt"><?= htmlspecialchars($form['note'], ENT_QUOTES) ?></textarea>
|
||||
</label>
|
||||
|
||||
<div class="login-notice login-notice-info">
|
||||
<strong>Wichtig</strong>
|
||||
<p>Das Passwort wird erst nach Freigabe gesetzt. Neue Registrierungen erhalten zunächst keinen aktiven Desktop-Zugang.</p>
|
||||
</div>
|
||||
|
||||
<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/login">Zurück zum Login</a>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user