Setzt die Rechte aus dem vorigen Commit in den Oberflaechen um und
ergaenzt die fehlenden Verwaltungsseiten.
Neu:
- /admin/users - Konten anlegen, Rolle und Sperre setzen, Passwort
zuruecksetzen, Gruppenzuordnung je Konto
- /admin/groups - Gruppen anlegen und umbenennen, Mitglieder samt
Rolle pflegen, zugeordnete Domains einsehen
- /admin/profile - eigenes Konto: Gruppenzugehoerigkeit ansehen und
das Passwort aendern. Das fehlte bisher vollstaendig, auch fuer
den einen Administrator.
Domains sind jetzt Administratorsache, weil dort die Gruppe zugewiesen
wird. Kurzlinks, Statistik und QR-Codes richten sich nach der Gruppe:
ein fremder Kurzlink antwortet mit 404 (seine Existenz geht den
Aufrufer nichts an), ein sichtbarer ohne Schreibrecht mit 403.
Geschlossene Luecke: /admin/uploads/{file} pruefte bisher nur, ob
ueberhaupt jemand angemeldet ist. Da alle Logos in einem gemeinsamen
Verzeichnis liegen, war der Dateiname die einzige Huerde. Ausgeliefert
wird jetzt nur noch, was laut Datenbank zu einem Kurzlink aus einer
Gruppe des Aufrufers gehoert.
Die Navigation blendet aus, wofuer die Rechte fehlen - das ist
Bedienkomfort, kein Zugriffsschutz: die Routen pruefen unabhaengig
davon noch einmal.
Der Setup-Assistent legt das erste Konto als Administrator an und
traegt es gleich als Editor der Gruppe "Standard" ein. Ohne das
koennte es zwar verwalten, aber selbst keine Kurzlinks anlegen.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
111 lines
5.1 KiB
PHP
111 lines
5.1 KiB
PHP
<?php
|
||
|
||
/**
|
||
* @var array<string,mixed>|null $domain
|
||
* @var list<array<string,mixed>> $groups
|
||
* @var array{base_url:string,label:string,is_default:string,group_id:string} $values
|
||
* @var array<string,string> $errors
|
||
* @var App\Security\Csrf $csrf
|
||
*/
|
||
|
||
$isEdit = $domain !== null;
|
||
$action = $isEdit
|
||
? $url('/admin/domains/' . (int) $domain['id'] . '/edit')
|
||
: $url('/admin/domains/new');
|
||
$isDefault = $isEdit && (int) $domain['is_default'] === 1;
|
||
?>
|
||
<div class="page-head">
|
||
<div>
|
||
<h1><?= $isEdit ? 'Domain bearbeiten' : 'Neue Domain' ?></h1>
|
||
<?php if ($isEdit): ?>
|
||
<p class="muted mono"><?= $e($domain['host']) ?></p>
|
||
<?php else: ?>
|
||
<p class="muted">Eine weitere Domain, unter der Kurzlinks ausgeliefert werden.</p>
|
||
<?php endif; ?>
|
||
</div>
|
||
<a href="<?= $e($url('/admin/domains')) ?>" class="btn btn--ghost">Zurück zur Liste</a>
|
||
</div>
|
||
|
||
<div class="card card--form">
|
||
<form method="post" action="<?= $e($action) ?>" class="form">
|
||
<?= $csrf->field() ?>
|
||
|
||
<div class="field <?= isset($errors['base_url']) ? 'field--error' : '' ?>">
|
||
<label for="base_url">Domain <span class="req">*</span></label>
|
||
<input type="text" id="base_url" name="base_url" value="<?= $e($values['base_url']) ?>"
|
||
placeholder="qr.example.de" required autofocus spellcheck="false" autocapitalize="off">
|
||
<p class="field__hint">
|
||
Genau so eintragen, wie die Domain im Browser aufgerufen wird. Ohne Schema wird
|
||
<code>https://</code> ergänzt – solange noch kein Zertifikat eingerichtet ist,
|
||
bitte <code>http://</code> voranstellen. Ein Unterverzeichnis ist erlaubt
|
||
(<code>example.de/kurz</code>), ein Port ebenfalls (<code>localhost:8088</code>).
|
||
Jede Domain darf nur einmal vorkommen.
|
||
</p>
|
||
<?php if (isset($errors['base_url'])): ?>
|
||
<p class="field__error"><?= $e($errors['base_url']) ?></p>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<div class="field">
|
||
<label for="label">Bezeichnung (optional)</label>
|
||
<input type="text" id="label" name="label" value="<?= $e($values['label']) ?>" maxlength="255"
|
||
placeholder="z. B. QR-Codes für Print">
|
||
<p class="field__hint">Nur zur eigenen Orientierung in der Auswahlliste.</p>
|
||
</div>
|
||
|
||
<div class="field <?= isset($errors['group_id']) ? 'field--error' : '' ?>">
|
||
<label for="group_id">Gruppe <span class="req">*</span></label>
|
||
<select id="group_id" name="group_id">
|
||
<?php foreach ($groups as $group): ?>
|
||
<option value="<?= (int) $group['id'] ?>" <?= $values['group_id'] === (string) $group['id'] ? 'selected' : '' ?>>
|
||
<?= $e($group['name']) ?>
|
||
</option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
<p class="field__hint">
|
||
Bestimmt, wer die Kurzlinks dieser Domain sehen und anlegen darf: alle Mitglieder
|
||
der gewählten Gruppe. Administratoren sehen ohnehin alles. Die Zuordnung lässt sich
|
||
jederzeit ändern – bestehende Kurzlinks wechseln dabei mit.
|
||
</p>
|
||
<?php if (isset($errors['group_id'])): ?>
|
||
<p class="field__error"><?= $e($errors['group_id']) ?></p>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<div class="field field--check">
|
||
<label class="check">
|
||
<input type="checkbox" name="is_default" value="1"
|
||
<?= $values['is_default'] === '1' ? 'checked' : '' ?>
|
||
<?= $isDefault ? 'disabled' : '' ?>>
|
||
<span>Als Standarddomain verwenden</span>
|
||
</label>
|
||
<?php if ($isDefault): ?>
|
||
<input type="hidden" name="is_default" value="1">
|
||
<p class="field__hint">Dies ist bereits die Standarddomain.</p>
|
||
<?php else: ?>
|
||
<p class="field__hint">Die Standarddomain ist im Formular vorausgewählt und fängt Aufrufe
|
||
über unbekannte Hostnamen ab.</p>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<?php if ($isEdit): ?>
|
||
<div class="alert alert--warn">
|
||
Wird der Hostname geändert, sind bereits verteilte Links und gedruckte QR-Codes
|
||
dieser Domain nicht mehr erreichbar.
|
||
</div>
|
||
<?php else: ?>
|
||
<p class="field__hint">
|
||
Damit die Domain auch wirklich hier ankommt, sind noch Einstellungen bei Domain-Anbieter
|
||
und Hoster nötig – die
|
||
<a href="<?= $e($url('/admin/domains#anleitung')) ?>">Schritt-für-Schritt-Anleitung</a>
|
||
steht auf der Domain-Übersicht.
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<div class="form__actions">
|
||
<button type="submit" class="btn btn--primary"><?= $isEdit ? 'Änderungen speichern' : 'Domain anlegen' ?></button>
|
||
<a href="<?= $e($url('/admin/domains')) ?>" class="btn btn--ghost">Abbrechen</a>
|
||
</div>
|
||
</form>
|
||
</div>
|