Files
pnpaas-adm/forgot-password.php
T

75 lines
3.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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>