connect_error) { die("Connection failed: " . $conn->connect_error); } return $conn; } function logJournal($conn, $id, $message) { if (isset($_SERVER['PHP_AUTH_USER'])) { $user = $_SERVER['PHP_AUTH_USER']; } else { $user = "None"; } $stmt = $conn->prepare("INSERT INTO journal (ppr_id, entry, user, ip) VALUES (?, ?, ?, ?)"); $ip = getUserIP(); $stmt->bind_param("isss", $id, $message, $user, $ip); $stmt->execute(); $stmt->close(); } function require_db_auth() { if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) { send_auth_headers(); } $user = $_SERVER['PHP_AUTH_USER']; $pass = $_SERVER['PHP_AUTH_PW']; $conn = connectDb(); $stmt = $conn->prepare("SELECT password FROM users WHERE username = ?"); $stmt->bind_param("s", $user); $stmt->execute(); $stmt->store_result(); $stmt->bind_result($stored_hash); $stmt->fetch(); // Verify the password if ($stmt->num_rows == 0 || !password_verify($pass, $stored_hash)) { send_auth_headers(); } // Close the connection $stmt->close(); $conn->close(); } function send_auth_headers() { header('WWW-Authenticate: Basic realm="Restricted Area"'); header('HTTP/1.0 401 Unauthorized'); die("Authentication required."); } function require_auth() { $AUTH_USER = 'admin'; $AUTH_PASS = 'admin'; header('Cache-Control: no-cache, must-revalidate, max-age=0'); $has_supplied_credentials = !(empty($_SERVER['PHP_AUTH_USER']) && empty($_SERVER['PHP_AUTH_PW'])); $is_not_authenticated = ( !$has_supplied_credentials || $_SERVER['PHP_AUTH_USER'] != $AUTH_USER || $_SERVER['PHP_AUTH_PW'] != $AUTH_PASS ); if ($is_not_authenticated) { header('HTTP/1.1 401 Authorization Required'); header('WWW-Authenticate: Basic realm="PPR"'); echo 'Text to send if user hits Cancel button'; exit; } } function generateSecureToken($email, $entryId) { $secretKey = "your-very-secret-key"; // Use an environment variable for this $timestamp = time(); $data = "$email|$entryId|$timestamp"; $hash = hash_hmac('sha256', $data, $secretKey); return base64_encode("$data|$hash"); } function validateSecureToken($token) { $secretKey = "your-very-secret-key"; $decoded = base64_decode($token); if (!$decoded) return false; list($email, $entryId, $timestamp, $hash) = explode('|', $decoded); // Check expiration (e.g., valid for 1 hour) //if (time() - $timestamp > 3600) { // return false; //} // Verify hash $data = "$email|$entryId|$timestamp"; $validHash = hash_hmac('sha256', $data, $secretKey); if (!hash_equals($validHash, $hash)) { return false; } return ['email' => $email, 'entryId' => $entryId]; } function generatePprEmail($entryId, $email, $ac_reg) { global $conn, $mailHost, $mailSMTPAuth, $mailUsername, $mailPassword, $mailPort, $baseUrl, $mailFromAddress, $mailFromName; if (!class_exists('PHPMailer\PHPMailer\PHPMailer')) { require '../vendor/autoload.php'; } $token = generateSecureToken($email, $entryId); $secureLink = $baseUrl . "/pilotppr.php?op=view&token=" . urlencode($token); $mail = new PHPMailer(true); try { $mail->isSMTP(); $mail->Host = $mailHost; $mail->SMTPAuth = $mailSMTPAuth; $mail->Username = $mailUsername; $mail->Password = $mailPassword; $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; $mail->Port = $mailPort; $mail->setFrom($mailFromAddress, $mailFromName); $mail->addAddress($email); $mail->isHTML(true); $mail->Subject = "PPR Confirmation for " . $ac_reg; $mail->Body = "
This is to confirm we have received your PPR. To view or cancel your PPR please click the button:
View PPR "; $mail->send(); echo "Email sent successfully!"; logJournal($conn, $entryId, "Confirm email sent"); } catch (Exception $e) { echo "Email sending failed: {$mail->ErrorInfo}"; logJournal($conn, $entryId, "Confirm email FAILED"); } } ?>