Auf Shared Hosting gibt es keine Kommandozeile - ohne Anzeige laesst sich dort nicht feststellen, ob etwa gd fehlt, die PHP-Version zu alt ist oder data/ nicht beschreibbar ist. Der Setup-Assistent prueft das jetzt und listet es auf; im Dashboard meldet sich die Pruefung spaeter nur noch, wenn etwas nicht stimmt. Fehlende Pflichtbausteine sind Fehler, fehlende Kuer (intl, imagick, cURL) nur Hinweise mit Angabe, was dadurch entfaellt. build-release.sh erzeugt das Upload-Paket: Abhaengigkeiten ohne Entwicklungspakete, ohne Tests und Docker-Dateien. Dabei faellt eine 16 MB grosse Schriftart aus endroid/qr-code weg, die ausschliesslich fuer Beschriftungen unter dem QR-Code gebraucht wird - die erzeugt diese Anwendung nicht. Das Paket schrumpft damit von 18 MB auf 1 MB. Sollte spaeter doch eine Beschriftung dazukommen, erkennt das Skript das und behaelt die Datei. Die Variante ohne eigenen Webroot (alles liegt im Domainverzeichnis, die .htaccess im Stammverzeichnis leitet nach public/ um) war bisher gebaut, aber nie erprobt. Sie ist jetzt gegen eine Hoster-Simulation getestet: Ersteinrichtung, Kurzlinks, Weiterleitung, QR-Codes, Statistik und die Sperren fuer src/, vendor/, data/ und .env.
126 lines
5.5 KiB
PHP
126 lines
5.5 KiB
PHP
<?php
|
||
|
||
/**
|
||
* @var App\Security\Csrf $csrf
|
||
* @var string $username
|
||
* @var array<string,string> $errors
|
||
* @var int $minLength
|
||
* @var string $tokenPath
|
||
* @var list<array{label:string,status:string,text:string,required:bool}> $systemChecks
|
||
* @var string $systemStatus
|
||
*/
|
||
|
||
use App\Service\SystemCheck;
|
||
|
||
$symbol = static fn (string $status): string => match ($status) {
|
||
SystemCheck::OK => '✓',
|
||
SystemCheck::WARNING => '!',
|
||
default => '×',
|
||
};
|
||
$cssClass = static fn (string $status): string => match ($status) {
|
||
SystemCheck::OK => 'ok',
|
||
SystemCheck::WARNING => 'warn',
|
||
default => 'error',
|
||
};
|
||
?>
|
||
<div class="card card--narrow">
|
||
<div class="card__head">
|
||
<span class="brand__mark brand__mark--lg" aria-hidden="true"></span>
|
||
<h1>Ersteinrichtung</h1>
|
||
<p class="muted">
|
||
Es ist noch kein Administrator-Konto vorhanden. Lege jetzt Benutzername und Passwort fest –
|
||
danach ist diese Seite gesperrt.
|
||
</p>
|
||
</div>
|
||
|
||
<form method="post" action="<?= $e($url('/setup')) ?>" class="form">
|
||
<?= $csrf->field() ?>
|
||
|
||
<div class="field <?= isset($errors['token']) ? 'field--error' : '' ?>">
|
||
<label for="setup_token">Einrichtungs-Token <span class="req">*</span></label>
|
||
<input type="text" id="setup_token" name="setup_token" required autofocus
|
||
spellcheck="false" autocapitalize="characters" autocomplete="off"
|
||
class="mono" placeholder="z. B. 3F9A1C0E7B2D4856">
|
||
<p class="field__hint">
|
||
Damit niemand anderes diese Installation übernimmt, steht das Token auf dem Server:
|
||
</p>
|
||
<details>
|
||
<summary>Wo finde ich das Token?</summary>
|
||
<ul class="checklist small muted">
|
||
<li><strong>Per FTP/SFTP oder Dateimanager:</strong> in der Datei
|
||
<code><?= $e($tokenPath) ?></code></li>
|
||
<li><strong>Docker:</strong> <code>docker compose logs app | grep Einrichtungs-Token</code>
|
||
oder <code>docker compose exec app cat data/setup-token.txt</code></li>
|
||
<li><strong>Mit Shell-Zugang:</strong> <code>cat <?= $e($tokenPath) ?></code></li>
|
||
</ul>
|
||
<p class="muted small">
|
||
Nach abgeschlossener Einrichtung wird die Datei automatisch gelöscht.
|
||
</p>
|
||
</details>
|
||
<?php if (isset($errors['token'])): ?>
|
||
<p class="field__error"><?= $e($errors['token']) ?></p>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<div class="field <?= isset($errors['username']) ? 'field--error' : '' ?>">
|
||
<label for="username">Benutzername</label>
|
||
<input type="text" id="username" name="username" value="<?= $e($username) ?>"
|
||
autocomplete="username" required>
|
||
<?php if (isset($errors['username'])): ?>
|
||
<p class="field__error"><?= $e($errors['username']) ?></p>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<div class="field <?= isset($errors['password']) ? 'field--error' : '' ?>">
|
||
<label for="password">Passwort</label>
|
||
<input type="password" id="password" name="password" autocomplete="new-password" required
|
||
minlength="<?= (int) $minLength ?>">
|
||
<p class="field__hint">Mindestens <?= (int) $minLength ?> Zeichen.</p>
|
||
<?php if (isset($errors['password'])): ?>
|
||
<p class="field__error"><?= $e($errors['password']) ?></p>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<div class="field <?= isset($errors['password_confirm']) ? 'field--error' : '' ?>">
|
||
<label for="password_confirm">Passwort wiederholen</label>
|
||
<input type="password" id="password_confirm" name="password_confirm" autocomplete="new-password" required>
|
||
<?php if (isset($errors['password_confirm'])): ?>
|
||
<p class="field__error"><?= $e($errors['password_confirm']) ?></p>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<button type="submit" class="btn btn--primary btn--block">Konto anlegen und anmelden</button>
|
||
</form>
|
||
|
||
<p class="muted small">
|
||
Alternativ kann das Konto auch fest in der <code>.env</code> hinterlegt werden
|
||
(<code>ADMIN_USER</code> und <code>ADMIN_PASSWORD_HASH</code>). Details stehen in der README.
|
||
</p>
|
||
</div>
|
||
|
||
<section class="card check-result check-result--<?= $e($cssClass($systemStatus)) ?>">
|
||
<details <?= $systemStatus === SystemCheck::OK ? '' : 'open' ?>>
|
||
<summary>
|
||
Systemvoraussetzungen –
|
||
<?= $systemStatus === SystemCheck::OK
|
||
? 'alles vorhanden'
|
||
: ($systemStatus === SystemCheck::WARNING ? 'mit Einschränkungen nutzbar' : 'es fehlt etwas') ?>
|
||
</summary>
|
||
|
||
<ul class="check-list">
|
||
<?php foreach ($systemChecks as $check): ?>
|
||
<li class="check-list__item check-list__item--<?= $e($cssClass($check['status'])) ?>">
|
||
<span class="check-list__icon" aria-hidden="true"><?= $e($symbol($check['status'])) ?></span>
|
||
<span class="check-list__label"><?= $e($check['label']) ?></span>
|
||
<span class="check-list__text"><?= $e($check['text']) ?></span>
|
||
</li>
|
||
<?php endforeach; ?>
|
||
</ul>
|
||
|
||
<p class="muted small">
|
||
Dass diese Seite überhaupt erscheint, belegt bereits, dass <code>mod_rewrite</code> arbeitet
|
||
und die <code>.htaccess</code> ausgewertet wird.
|
||
</p>
|
||
</details>
|
||
</section>
|