clusev/app/Console/Commands/ResetAdmin.php

66 lines
2.2 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
/**
* Emergency, shell-only recovery: resets the admin password (and optionally 2FA)
* when the operator is locked out (lost password + authenticator + backup codes).
* Requires server access, so it is a safe last resort.
*/
class ResetAdmin extends Command
{
protected $signature = 'clusev:reset-admin
{--email= : E-Mail des Admin-Kontos (sonst der einzige Benutzer)}
{--password= : Neues Passwort (zufällig erzeugt, falls leer)}
{--disable-2fa : 2FA + Backup-Codes ebenfalls zurücksetzen}';
protected $description = 'Notfall-Reset: setzt das Admin-Passwort (und optional 2FA) per Shell zurück';
public function handle(): int
{
$email = (string) $this->option('email');
$user = $email !== ''
? User::where('email', $email)->first()
: (User::count() === 1 ? User::first() : null);
if (! $user) {
$this->error($email !== '' ? "Kein Benutzer mit E-Mail {$email}." : 'Kein eindeutiger Benutzer — bitte --email angeben.');
return self::FAILURE;
}
$password = (string) ($this->option('password') ?: Str::password(20));
// Rotate remember_token so any previously issued remember-me cookie is revoked.
$user->forceFill([
'password' => Hash::make($password),
'must_change_password' => false,
'remember_token' => Str::random(60),
]);
if ($this->option('disable-2fa')) {
$user->forceFill([
'two_factor_secret' => null,
'two_factor_confirmed_at' => null,
'two_factor_recovery_codes' => null,
]);
}
$user->save();
$this->info("Passwort für {$user->email} zurückgesetzt.");
if (! $this->option('password')) {
$this->warn("Einmal-Passwort (jetzt notieren): {$password}");
}
if ($this->option('disable-2fa')) {
$this->info('2FA + Backup-Codes entfernt — beim nächsten Login neu einrichten.');
}
return self::SUCCESS;
}
}