'Bitte geben Sie eine gültige E-Mail-Adresse ein.', 3 => 'Ungültiger oder abgelaufener Bestätigungscode.', 5 => 'Passwort muss mindestens 8 Zeichen, einen Buchstaben und eine Zahl enthalten.', 6 => 'Passwörter stimmen nicht überein.', 7 => 'Sitzung abgelaufen. Bitte starten Sie den Vorgang erneut.', ]; if (isset($errorMessages[$errorCode])) { $error = $errorMessages[$errorCode]; } if ($step === 'verify' && !authorization_reset_request_is_active()) { authorization_clear_reset_state(); authorization_redirect('reset-password.php?error=7', 302); } if ($step === 'newpassword' && !authorization_reset_is_authorized()) { authorization_clear_reset_state(); authorization_redirect('reset-password.php?error=7', 302); } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $action = (string) ($_POST['action'] ?? ''); if (!authorization_csrf_is_valid($_POST['csrf_token'] ?? null)) { authorization_clear_reset_state(); authorization_redirect('reset-password.php?error=7'); } $pdo = require $_SERVER['DOCUMENT_ROOT'] . '/intranet_repo/general_files/ini/database.php'; $pdo->exec("SET timezone = 'Europe/Berlin'"); if ($action === 'request_otp') { $email = trim((string) ($_POST['email'] ?? '')); if (strlen($email) > 254 || !filter_var($email, FILTER_VALIDATE_EMAIL)) { authorization_redirect('reset-password.php?error=1'); } authorization_clear_reset_state(); $_SESSION['auth_reset_started_at'] = time(); $_SESSION['auth_reset_attempts'] = 0; $_SESSION['auth_reset_user_id'] = 0; $stmt = $pdo->prepare( 'SELECT ugi.user_id, ugi.phone, ugi.first_name, ugi.mail ' . 'FROM user_general_information ugi ' . 'INNER JOIN user_login ul ON ul.user_id = ugi.user_id ' . 'WHERE LOWER(ugi.mail) = LOWER(?) LIMIT 1' ); $stmt->execute([$email]); $resetUser = $stmt->fetch(PDO::FETCH_ASSOC); if (is_array($resetUser)) { $userId = (int) $resetUser['user_id']; $otp = str_pad((string) random_int(0, 999999), 6, '0', STR_PAD_LEFT); $expiresAt = date('Y-m-d H:i:s', time() + AUTH_RESET_TTL_SECONDS); $pdo->beginTransaction(); try { $stmt = $pdo->prepare('UPDATE password_reset_otp SET used = 1 WHERE user_id = ? AND used = 0'); $stmt->execute([$userId]); $stmt = $pdo->prepare('INSERT INTO password_reset_otp (user_id, otp_code, expires_at) VALUES (?, ?, ?)'); $stmt->execute([$userId, $otp, $expiresAt]); $pdo->commit(); } catch (Throwable $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } error_log('authorization reset OTP persistence failed: ' . $e->getMessage()); authorization_redirect('reset-password.php?step=verify&sent=1'); } $mailSent = false; try { require_once $_SERVER['DOCUMENT_ROOT'] . '/intranet_repo/general_files/ini/send_mail.php'; $greeting = !empty($resetUser['first_name']) ? 'Hallo ' . $resetUser['first_name'] : 'Hallo'; $mailMessage = $greeting . ",\n\n" . "Sie haben das Zurücksetzen Ihres Passworts angefordert.\n\n" . "Ihr Bestätigungscode lautet: {$otp}\n\n" . "Der Code ist 10 Minuten gültig.\n\n" . 'Falls Sie diese Anfrage nicht gestellt haben, können Sie diese Nachricht ignorieren.'; $mailSent = send_intranet_mail((string) $resetUser['mail'], 'Ihr Bestätigungscode', $mailMessage); } catch (Throwable $e) { error_log('authorization reset mail delivery failed: ' . $e->getMessage()); } $smsSent = authorization_send_reset_sms(authorization_normalize_phone((string) ($resetUser['phone'] ?? '')), $otp); if ($mailSent || $smsSent) { $_SESSION['auth_reset_user_id'] = $userId; } else { error_log('authorization reset delivery failed for user_id=' . $userId); $stmt = $pdo->prepare('UPDATE password_reset_otp SET used = 1 WHERE user_id = ? AND used = 0'); $stmt->execute([$userId]); } } // Immer dieselbe Antwort, damit aus dem Reset-Flow kein Kontostatus abgeleitet werden kann. authorization_redirect('reset-password.php?step=verify&sent=1'); } if ($action === 'verify_otp') { if (!authorization_reset_request_is_active()) { authorization_clear_reset_state(); authorization_redirect('reset-password.php?error=7'); } $otp = trim((string) ($_POST['otp_code'] ?? '')); $attempts = (int) ($_SESSION['auth_reset_attempts'] ?? 0) + 1; $_SESSION['auth_reset_attempts'] = $attempts; $userId = (int) ($_SESSION['auth_reset_user_id'] ?? 0); if (!preg_match('/^[0-9]{6}$/', $otp) || $userId <= 0 || $attempts > AUTH_RESET_MAX_ATTEMPTS) { if ($attempts >= AUTH_RESET_MAX_ATTEMPTS && $userId > 0) { $stmt = $pdo->prepare('UPDATE password_reset_otp SET used = 1 WHERE user_id = ? AND used = 0'); $stmt->execute([$userId]); authorization_clear_reset_state(); authorization_redirect('reset-password.php?error=7'); } authorization_redirect('reset-password.php?step=verify&error=3'); } $now = date('Y-m-d H:i:s'); $pdo->beginTransaction(); try { $stmt = $pdo->prepare( 'SELECT id FROM password_reset_otp ' . 'WHERE user_id = ? AND otp_code = ? AND used = 0 AND expires_at > ? ' . 'ORDER BY id DESC LIMIT 1 FOR UPDATE' ); $stmt->execute([$userId, $otp, $now]); $otpId = (int) ($stmt->fetchColumn() ?: 0); if ($otpId <= 0) { $pdo->rollBack(); authorization_redirect('reset-password.php?step=verify&error=3'); } $stmt = $pdo->prepare('UPDATE password_reset_otp SET used = 1 WHERE id = ?'); $stmt->execute([$otpId]); $pdo->commit(); session_regenerate_id(true); $_SESSION['auth_reset_user_id'] = $userId; $_SESSION['auth_reset_authorized_until'] = time() + AUTH_RESET_TTL_SECONDS; unset($_SESSION['auth_reset_attempts']); authorization_redirect('reset-password.php?step=newpassword'); } catch (Throwable $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } error_log('authorization OTP verification failed: ' . $e->getMessage()); authorization_redirect('reset-password.php?step=verify&error=3'); } } if ($action === 'set_password') { if (!authorization_reset_is_authorized()) { authorization_clear_reset_state(); authorization_redirect('reset-password.php?error=7'); } $newPassword = (string) ($_POST['new_password'] ?? ''); $confirmation = (string) ($_POST['new_password_confirm'] ?? ''); $passwordError = authorization_password_error($newPassword, $confirmation); if ($passwordError !== null) { $code = str_contains($passwordError, 'stimmen') ? 6 : 5; authorization_redirect('reset-password.php?step=newpassword&error=' . $code); } $userId = (int) $_SESSION['auth_reset_user_id']; $passwordHash = password_hash($newPassword, PASSWORD_DEFAULT); $resetUser = null; $pdo->beginTransaction(); try { $stmt = $pdo->prepare('UPDATE user_login SET password_hash = ? WHERE user_id = ?'); $stmt->execute([$passwordHash, $userId]); if ($stmt->rowCount() !== 1) { throw new RuntimeException('Reset target login no longer exists.'); } $stmt = $pdo->prepare('UPDATE password_reset_otp SET used = 1 WHERE user_id = ? AND used = 0'); $stmt->execute([$userId]); $stmt = $pdo->prepare('SELECT mail, first_name, last_name FROM user_general_information WHERE user_id = ?'); $stmt->execute([$userId]); $resetUser = $stmt->fetch(PDO::FETCH_ASSOC); if (!is_array($resetUser)) { throw new RuntimeException('Reset target user no longer exists.'); } $userName = trim(($resetUser['first_name'] ?? '') . ' ' . ($resetUser['last_name'] ?? '')); if ($userName === '') { $userName = (string) $resetUser['mail']; } $taskSubject = "Passwort selbst zurückgesetzt: {$userName}"; $taskMessage = "{$userName} ({$resetUser['mail']}) hat das eigene Passwort erfolgreich zurückgesetzt."; $stmt = $pdo->prepare( "INSERT INTO admin_messages (type, sender_name, sender_email, subject, message, status, processed_at, created_at) " . "VALUES ('system', ?, ?, ?, ?, 'done', NOW(), NOW())" ); $stmt->execute([$userName, $resetUser['mail'], $taskSubject, $taskMessage]); $pdo->commit(); } catch (Throwable $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } error_log('authorization password reset failed: ' . $e->getMessage()); authorization_clear_reset_state(); authorization_redirect('reset-password.php?error=7'); } try { require_once $_SERVER['DOCUMENT_ROOT'] . '/intranet_repo/general_files/ini/send_mail.php'; $loginUrl = authorization_public_url('/intranet_repo/projects/authorization/login.php'); $greeting = !empty($resetUser['first_name']) ? 'Hallo ' . $resetUser['first_name'] : 'Hallo'; $message = $greeting . ",\n\n" . "Ihr Passwort für das Intranet der NAK Reinickendorf wurde erfolgreich geändert.\n\n" . 'Sie können sich ab sofort mit Ihrem neuen Passwort anmelden.'; send_intranet_mail((string) $resetUser['mail'], 'Passwort erfolgreich geändert', $message, null, 'intranet@nak-reinickendorf.de', 'Jetzt anmelden', $loginUrl); } catch (Throwable $e) { error_log('authorization password reset notification failed: ' . $e->getMessage()); } authorization_clear_reset_state(); session_regenerate_id(true); authorization_redirect('login.php?message=1'); } authorization_redirect('reset-password.php'); } $csrfToken = authorization_csrf_token(); ?>
Geben Sie Ihre E-Mail-Adresse ein. Wenn ein passendes Konto vorhanden ist, senden wir einen Bestätigungscode an die hinterlegten Kontaktwege.
= authorization_html(authorization_masked_reset_message()) ?>
Ihr Code wurde bestätigt. Geben Sie nun Ihr neues Passwort ein.