From 35115404be38ec902b24660c085948df4186be9a Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Sat, 15 Aug 2026 09:55:33 +0000 Subject: [PATCH] Validate the guest e-mail before the booking is saved MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An address like "asdf" used to be accepted: the field was type="text" with only `required`, and there was no server-side check. createBooking() runs long before sendEmail(), so the failure was silent rather than loud - reproduced end to end on test: - the booking row WAS created, with a manage_token - PHPMailer's addAddress() threw, so nothing was ever sent - the Location header was already queued, so the guest was redirected to the normal "booking finished" page and saw success - Evelin is a CC on that same message, so the salon was not told either - the guest had no manage link, so they could not cancel Fixes - booking_process() rejects an empty or malformed address BEFORE any write, returning invalid_email / HTTP 400. Message added in all three languages, worded to say why it matters (the confirmation and the manage link go there). filter_var is equal-or-stricter than PHPMailer's own validator - checked against it on ten cases - so anything accepted here cannot throw later. - The three public booking forms use type="email", so most typos never reach the server. - Removed three debug echoes from User_model::sendEmail() that leaked $lang and Hungarian strings ("Üzenet elküldve", "Üzenetküldési hiba. Mailer Error: ...") into the guest-facing response. Scope - Public flow only. 508 existing bookings have an empty guest_email because admin-created block bookings legitimately have none; those go through Admin::booking_process(), which is untouched, and its form stays type="text". - Not covered: a valid address whose SMTP delivery fails still leaves the booking created and the guest seeing success, logged only via log_message(). Different failure mode, needs a separate decision. Co-Authored-By: Claude Opus 5 --- application/controllers/Pages.php | 19 ++++++++++++++++++- application/models/User_model.php | 7 ++++--- .../pages/includes/booking-error-form-en.php | 1 + .../pages/includes/booking-error-form-hu.php | 1 + .../pages/includes/booking-error-form-no.php | 1 + .../views/pages/includes/booking-form-en.php | 2 +- .../views/pages/includes/booking-form-hu.php | 2 +- .../views/pages/includes/booking-form-no.php | 2 +- 8 files changed, 28 insertions(+), 7 deletions(-) diff --git a/application/controllers/Pages.php b/application/controllers/Pages.php index cc8d946..a63be1d 100755 --- a/application/controllers/Pages.php +++ b/application/controllers/Pages.php @@ -403,7 +403,24 @@ class Pages extends CI_Controller { 'guest_confirm_code' => '1234', 'manage_token' => $manageToken, ); - + + // Reject an unusable e-mail BEFORE anything is written. The booking is + // saved well before sendEmail() runs, so without this the row is created, + // PHPMailer's addAddress() throws, and the guest is redirected to the + // success page having received nothing - no confirmation and no manage + // link. Evelin is a CC on that same message, so the salon is not told + // either. filter_var is equal-or-stricter than PHPMailer's own check, so + // anything accepted here will not throw later. + // + // Public flow only: admin-created block bookings legitimately carry an + // empty guest_email and go through Admin::booking_process(). + $guestEmailInput = isset($_POST['guest_email']) ? trim($_POST['guest_email']) : ''; + if ($guestEmailInput === '' || !filter_var($guestEmailInput, FILTER_VALIDATE_EMAIL)) { + $this->_booking_error('invalid_email', 400); + return; + } + $bookingArray['guest_email'] = $guestEmailInput; + $bookingDate = $bookingArray['booking_date']; $bookingTime = $bookingArray['booking_start_time']; diff --git a/application/models/User_model.php b/application/models/User_model.php index a6c56b6..5e9ab92 100755 --- a/application/models/User_model.php +++ b/application/models/User_model.php @@ -132,7 +132,6 @@ class User_model extends CI_Model { public function sendEmail($addressList, $lang, $subpage){ // Import PHPMailer classes into the global namespace // These must be at the top of your script, not inside a function - echo $lang; if(!empty($addressList)){ foreach($addressList as $addressListItem){ // Instantiation and passing `true` enables exceptions @@ -179,7 +178,6 @@ class User_model extends CI_Model { //$mail->AltBody = strip_tags($answer_message); $mail->send(); - echo 'Üzenet elküldve'; if($subpage != ''){ header('location:'.base_url().$lang.'/booking-finished/'.$subpage); } @@ -187,7 +185,10 @@ class User_model extends CI_Model { } catch (Exception $e) { //header('location:'.base_url().'manage-applicants/?email-sent=false&error='.$mail->ErrorInfo); log_message('error', 'sendEmail FAILED: ' . $mail->ErrorInfo); - echo "Üzenetküldési hiba. Mailer Error: {$mail->ErrorInfo}"; + // Do NOT echo the mailer error. This runs after the booking is + // saved and after the redirect header is queued, so it only leaks + // Hungarian internals into a response the guest never reads. + // The log_message() above is the record. } } diff --git a/application/views/pages/includes/booking-error-form-en.php b/application/views/pages/includes/booking-error-form-en.php index 55f2e99..48f60f0 100755 --- a/application/views/pages/includes/booking-error-form-en.php +++ b/application/views/pages/includes/booking-error-form-en.php @@ -8,6 +8,7 @@ 'too_far' => 'Bookings can only be made up to 3 months in advance.', 'category_mismatch' => 'The selected staff member does not perform the chosen services. Please start again.', 'single_service_only' => 'Only one treatment can be booked at a time. Please select just one.', + 'invalid_email' => 'That e-mail address does not look valid. Please check it - your confirmation and the link to manage your booking are sent there.', 'no_service' => 'No service was selected. Please choose at least one service.', 'default' => 'Something went wrong with your booking. Please try again.', ); diff --git a/application/views/pages/includes/booking-error-form-hu.php b/application/views/pages/includes/booking-error-form-hu.php index c79cc2e..0464482 100755 --- a/application/views/pages/includes/booking-error-form-hu.php +++ b/application/views/pages/includes/booking-error-form-hu.php @@ -8,6 +8,7 @@ 'too_far' => 'Foglalás legfeljebb 3 hónappal előre adható le.', 'category_mismatch' => 'A kiválasztott kolléga nem végzi a kiválasztott szolgáltatásokat. Kérjük, válasszon újra.', 'single_service_only' => 'Egyszerre csak egy kezelés foglalható. Kérjük, csak egyet válasszon.', + 'invalid_email' => 'Az e-mail cím nem tűnik érvényesnek. Kérjük, ellenőrizze - a visszaigazolást és a foglalás kezelésére szolgáló linket erre a címre küldjük.', 'no_service' => 'Nem választott ki szolgáltatást. Kérjük, válasszon legalább egyet.', 'default' => 'Hiba történt a foglalás során. Kérjük, próbálja újra.', ); diff --git a/application/views/pages/includes/booking-error-form-no.php b/application/views/pages/includes/booking-error-form-no.php index bd38e73..b419dc2 100755 --- a/application/views/pages/includes/booking-error-form-no.php +++ b/application/views/pages/includes/booking-error-form-no.php @@ -8,6 +8,7 @@ 'too_far' => 'Du kan kun bestille time inntil 3 måneder frem i tid.', 'category_mismatch' => 'Den valgte medarbeideren utfører ikke de valgte tjenestene. Vennligst velg på nytt.', 'single_service_only' => 'Du kan kun bestille én behandling om gangen. Vennligst velg kun én.', + 'invalid_email' => 'E-postadressen ser ikke ut til å være gyldig. Vennligst kontroller den - bekreftelsen og lenken for å endre bestillingen sendes dit.', 'no_service' => 'Du har ikke valgt noen tjeneste. Vennligst velg minst én tjeneste.', 'default' => 'Noe gikk galt med bestillingen. Vennligst prøv igjen.', ); diff --git a/application/views/pages/includes/booking-form-en.php b/application/views/pages/includes/booking-form-en.php index f8fe150..46548c3 100755 --- a/application/views/pages/includes/booking-form-en.php +++ b/application/views/pages/includes/booking-form-en.php @@ -177,7 +177,7 @@
- +
diff --git a/application/views/pages/includes/booking-form-hu.php b/application/views/pages/includes/booking-form-hu.php index 381f258..01d6ff6 100755 --- a/application/views/pages/includes/booking-form-hu.php +++ b/application/views/pages/includes/booking-form-hu.php @@ -178,7 +178,7 @@
- +
diff --git a/application/views/pages/includes/booking-form-no.php b/application/views/pages/includes/booking-form-no.php index 2b2ba1b..3917631 100755 --- a/application/views/pages/includes/booking-form-no.php +++ b/application/views/pages/includes/booking-form-no.php @@ -178,7 +178,7 @@ if (is_array($services) && count($services) > 0) {
- +