66 lines
2.5 KiB
PHP
66 lines
2.5 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\User;
|
|
use Illuminate\Console\Command;
|
|
|
|
/**
|
|
* Idempotent first-run bootstrap (called by install.sh, phase 7).
|
|
*
|
|
* Creates the initial admin with the standard default password (operator decision: a
|
|
* known, memorable default so login is never blocked by a missed one-time secret).
|
|
* `must_change_password` is set, so the onboarding gate FORCES a new password on the
|
|
* first login — the default is only valid until then. Re-running once an admin exists is
|
|
* a hard no-op. NOTE: a known default credential is only acceptable because of the forced
|
|
* rotation; the operator must change it immediately (banner / MOTD / README say so).
|
|
*/
|
|
class Install extends Command
|
|
{
|
|
/** Standard default admin password — forced to change on first login (must_change_password). */
|
|
private const DEFAULT_PASSWORD = 'clusev';
|
|
|
|
protected $signature = "clusev:install
|
|
{--email= : Admin-Login + Let's-Encrypt-E-Mail}
|
|
{--name=Administrator : Anzeigename des Admins}";
|
|
|
|
protected $description = 'Idempotenter Erstlauf: legt den ersten Admin mit Standard-Passwort an (Zwangswechsel beim ersten Login)';
|
|
|
|
public function handle(): int
|
|
{
|
|
if (User::query()->exists()) {
|
|
$this->info('Clusev ist bereits installiert — kein Admin angelegt.');
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
$host = parse_url((string) config('app.url'), PHP_URL_HOST) ?: 'localhost';
|
|
$email = (string) ($this->option('email') ?: "admin@{$host}");
|
|
|
|
if (! filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
$this->error("Ungueltige Admin-E-Mail: {$email}");
|
|
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$password = self::DEFAULT_PASSWORD;
|
|
|
|
$user = User::create([
|
|
'name' => (string) ($this->option('name') ?: 'Administrator'),
|
|
'email' => $email,
|
|
'password' => $password, // 'hashed' cast hashes on save
|
|
'must_change_password' => true, // forces a new password on first login
|
|
]);
|
|
|
|
// install.sh greps these two lines for the closing banner. The password is the
|
|
// standard default and must be changed on first login (must_change_password).
|
|
$this->newLine();
|
|
$this->line('CLUSEV_ADMIN_EMAIL='.$user->email);
|
|
$this->line('CLUSEV_ADMIN_PASSWORD='.$password);
|
|
$this->newLine();
|
|
$this->info('Admin angelegt. Standard-Passwort — beim ersten Login sofort aendern.');
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
}
|