75 lines
3.8 KiB
PHP
75 lines
3.8 KiB
PHP
<?php
|
||
declare(strict_types=1);
|
||
|
||
require_once __DIR__ . '/includes/bootstrap.php';
|
||
pnpaas_session_start();
|
||
$csrfToken = pnpaas_csrf_token();
|
||
$message = null;
|
||
$error = null;
|
||
|
||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||
$email = trim((string)($_POST['email'] ?? ''));
|
||
if (!pnpaas_valid_csrf((string)($_POST['csrf_token'] ?? ''))) {
|
||
$error = 'Die Sitzung ist abgelaufen. Bitte laden Sie die Seite neu.';
|
||
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||
$error = 'Bitte geben Sie eine gültige E-Mail-Adresse ein.';
|
||
} else {
|
||
try {
|
||
$db = pnpaas_db();
|
||
$db->exec('DELETE FROM password_reset_tokens WHERE expires_at < NOW() OR used_at IS NOT NULL');
|
||
$statement = $db->prepare('SELECT id, email FROM users WHERE email = :email AND status = :status LIMIT 1');
|
||
$statement->execute(['email' => $email, 'status' => 'active']);
|
||
$user = $statement->fetch();
|
||
if (is_array($user)) {
|
||
$token = bin2hex(random_bytes(32));
|
||
$insert = $db->prepare(
|
||
'INSERT INTO password_reset_tokens (user_id, token_hash, expires_at, requested_ip)
|
||
VALUES (:user_id, :token_hash, DATE_ADD(NOW(), INTERVAL 1 HOUR), :requested_ip)'
|
||
);
|
||
$insert->execute([
|
||
'user_id' => (int)$user['id'],
|
||
'token_hash' => hash('sha256', $token),
|
||
'requested_ip' => $_SERVER['REMOTE_ADDR'] ?? null,
|
||
]);
|
||
if (!pnpaas_send_password_reset((string)$user['email'], $token)) {
|
||
error_log('PnPaaS password reset mail could not be sent.');
|
||
}
|
||
}
|
||
$message = 'Wenn ein aktives Konto zu dieser E-Mail-Adresse existiert, wurde ein Link zum Zurücksetzen versendet.';
|
||
} catch (Throwable $exception) {
|
||
error_log('PnPaaS password reset request error: ' . $exception->getMessage());
|
||
$error = 'Die Anfrage ist derzeit nicht möglich. Bitte versuchen Sie es später erneut.';
|
||
}
|
||
}
|
||
}
|
||
?>
|
||
<!doctype html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>PnPaaS – Passwort zurücksetzen</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@500;600&family=Open+Sans:wght@400;600;700&display=swap" rel="stylesheet">
|
||
<link rel="stylesheet" href="assets/style.css">
|
||
</head>
|
||
<body class="auth-page">
|
||
<main class="auth-card" aria-labelledby="reset-title">
|
||
<div class="brand-mark" aria-hidden="true">✦</div>
|
||
<p class="eyebrow">PnPaaS Administration</p>
|
||
<h1 id="reset-title">Passwort vergessen?</h1>
|
||
<p class="intro">Geben Sie Ihre E-Mail-Adresse ein. Falls ein aktives Konto dazugehört, senden wir Ihnen einen zeitlich begrenzten Link.</p>
|
||
<?php if ($error !== null): ?><div class="alert alert-error" role="alert"><?= htmlspecialchars($error, ENT_QUOTES, 'UTF-8') ?></div><?php endif; ?>
|
||
<?php if ($message !== null): ?><div class="alert alert-success" role="status"><?= htmlspecialchars($message, ENT_QUOTES, 'UTF-8') ?></div><?php endif; ?>
|
||
<form method="post" action="forgot-password.php" class="login-form">
|
||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($csrfToken, ENT_QUOTES, 'UTF-8') ?>">
|
||
<label for="email">E-Mail-Adresse</label>
|
||
<input id="email" name="email" type="email" autocomplete="email" required autofocus>
|
||
<button type="submit">Link anfordern</button>
|
||
</form>
|
||
<p class="form-footer"><a href="index.php">Zurück zur Anmeldung</a></p>
|
||
</main>
|
||
</body>
|
||
</html>
|