extract shared OneTimeToken model for single-use tokens + AdminAuth reset API

This commit is contained in:
Pontoporeia
2026-08-24 11:35:22 +02:00
parent 802b601b59
commit abb735253e
4 changed files with 204 additions and 0 deletions
+40
View File
@@ -165,6 +165,46 @@ class AdminAuth
$db->setSetting('admin_password_hash', '');
}
/**
* Issue a single-use password-reset token (plaintext, to be emailed).
*
* Uses the shared OneTimeToken model (purpose 'password_reset').
*
* @param int $ttlSeconds Lifetime in seconds (default 30 minutes).
* @return string The plaintext token to send to the admin.
*/
public static function issuePasswordResetToken(int $ttlSeconds = 1800): string
{
require_once APP_ROOT . '/src/OneTimeToken.php';
$db = new Database();
$ot = new OneTimeToken($db->getPDO());
return $ot->issue('password_reset', $ttlSeconds);
}
/**
* Redeem a password-reset token and return the new password hash.
*
* On success, the token is consumed (one-time) and a fresh bcrypt hash
* is generated for the given new password — but NOT yet persisted; the
* caller decides when to store it (so the reset flow can validate before
* committing).
*
* @return string|null bcrypt hash, or null when the token is invalid.
*/
public static function redeemPasswordResetToken(string $token, string $newPassword): ?string
{
require_once APP_ROOT . '/src/OneTimeToken.php';
$db = new Database();
$ot = new OneTimeToken($db->getPDO());
$context = $ot->redeem('password_reset', $token);
if ($context === null) {
return null;
}
return password_hash($newPassword, PASSWORD_BCRYPT, ['cost' => 12]);
}
/**
* Check whether the current request is authenticated (without redirecting).
*/