73 lines
2.3 KiB
PHP
73 lines
2.3 KiB
PHP
<?php
|
|
|
|
namespace App\Support;
|
|
|
|
use Illuminate\Validation\Rules\Password;
|
|
|
|
/**
|
|
* Wie lang ein Passwort in dieser Installation sein muss — an einer Stelle.
|
|
*
|
|
* Vorher gab es die Regel dreimal, mit drei verschiedenen Antworten:
|
|
* `ResetPassword` verlangte fest `min:12`, `CreateAdmin` `Password::min(12)`,
|
|
* und alles über `PasswordValidationRules` bekam `Password::default()` — also
|
|
* Laravels acht. Derselbe Kunde brauchte beim Zurücksetzen zwölf Zeichen und
|
|
* bei der Registrierung acht, und einstellbar war nichts davon.
|
|
*
|
|
* Gemeldet wurde die Zwölf als „zu lang". Die eigentliche Auffälligkeit war,
|
|
* dass es die Regel dreimal gibt: drei Stellen, die dieselbe Frage
|
|
* verschieden beantworten, laufen auseinander — hier waren sie es schon.
|
|
*
|
|
* Geklemmt statt abgelehnt: der Wert kommt aus einem Formular im Adminbereich,
|
|
* und eine stillschweigend gespeicherte 1 wäre schlimmer als eine sichtbar auf
|
|
* 6 geklemmte Eingabe.
|
|
*/
|
|
final class PasswordPolicy
|
|
{
|
|
public const SETTING = 'security.password_min_length';
|
|
|
|
/**
|
|
* Die kürzeste Länge, die diese Installation zulässt.
|
|
*
|
|
* Sechs ist wenig. Es ist die ausdrückliche Vorgabe des Betreibers
|
|
* (31.7.2026, „6 ist mindestens"), und die Zahl steht direkt neben dem
|
|
* Feld, an dem sie sich erhöhen lässt.
|
|
*/
|
|
public const FLOOR = 6;
|
|
|
|
/** bcrypt schneidet jenseits von 72 Byte ohnehin ab; 128 ist reichlich Luft. */
|
|
public const CEILING = 128;
|
|
|
|
public const DEFAULT_LENGTH = 6;
|
|
|
|
public static function minLength(): int
|
|
{
|
|
$stored = Settings::get(self::SETTING);
|
|
|
|
return self::clamp(is_numeric($stored) ? (int) $stored : self::DEFAULT_LENGTH);
|
|
}
|
|
|
|
public static function set(int $length): void
|
|
{
|
|
Settings::set(self::SETTING, self::clamp($length));
|
|
}
|
|
|
|
/**
|
|
* Die Regeln OHNE `confirmed`.
|
|
*
|
|
* Die Bestätigung hängt am Formular, nicht an der Richtlinie: `CreateAdmin`
|
|
* fragt auf der Kommandozeile einmal, jedes Formular zweimal. Wer sie
|
|
* braucht, hängt sie an.
|
|
*
|
|
* @return array<int, mixed>
|
|
*/
|
|
public static function rules(): array
|
|
{
|
|
return ['required', 'string', Password::min(self::minLength())];
|
|
}
|
|
|
|
private static function clamp(int $length): int
|
|
{
|
|
return max(self::FLOOR, min(self::CEILING, $length));
|
|
}
|
|
}
|