diff --git a/cp/app/Controllers/ContactsController.php b/cp/app/Controllers/ContactsController.php index 069207f..c4131e0 100644 --- a/cp/app/Controllers/ContactsController.php +++ b/cp/app/Controllers/ContactsController.php @@ -227,11 +227,11 @@ class ContactsController extends Controller $fax = $normalizedFax['success']; } - if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + if (!validateUniversalEmail($email)) { $this->container->get('flash')->addMessage('error', 'Unable to create contact: Email address failed check'); return $response->withHeader('Location', '/contact/create')->withStatus(302); } - + if (!$authInfo_pw) { $this->container->get('flash')->addMessage('error', 'Unable to create contact: Email contact authinfo missing'); return $response->withHeader('Location', '/contact/create')->withStatus(302); @@ -959,7 +959,7 @@ class ContactsController extends Controller return $response->withHeader('Location', '/contact/update/'.$identifier)->withStatus(302); } - if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + if (!validateUniversalEmail($email)) { $this->container->get('flash')->addMessage('error', 'Unable to update contact: Email address failed check'); return $response->withHeader('Location', '/contact/update/'.$identifier)->withStatus(302); } diff --git a/cp/bootstrap/helper.php b/cp/bootstrap/helper.php index 2db8b51..4b8f062 100644 --- a/cp/bootstrap/helper.php +++ b/cp/bootstrap/helper.php @@ -541,4 +541,39 @@ function validateLocField($input, $minLength = 5, $maxLength = 255) { return mb_strlen($input) >= $minLength && mb_strlen($input) <= $maxLength && preg_match($locRegex, $input); +} + +function validateUniversalEmail($email) { + // Normalize the email to NFC form to ensure consistency + $email = \Normalizer::normalize($email, \Normalizer::FORM_C); + + // Remove any control characters + $email = preg_replace('/[\p{C}]/u', '', $email); + + // Split email into local and domain parts + $parts = explode('@', $email, 2); + if (count($parts) !== 2) { + return false; // Invalid email format + } + + list($localPart, $domainPart) = $parts; + + // Convert the domain part to Punycode if it contains non-ASCII characters + if (preg_match('/[^\x00-\x7F]/', $domainPart)) { + $punycodeDomain = idn_to_ascii($domainPart, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46); + if ($punycodeDomain === false) { + return false; // Invalid domain part, failed conversion + } + } else { + $punycodeDomain = $domainPart; + } + + // Reconstruct the email with the Punycode domain part (if converted) + $emailToValidate = $localPart . '@' . $punycodeDomain; + + // Updated regex for both ASCII and IDN email validation + $emailPattern = '/^[\p{L}\p{N}\p{M}._%+-]+@([a-zA-Z0-9-]+|\bxn--[a-zA-Z0-9-]+)(\.([a-zA-Z0-9-]+|\bxn--[a-zA-Z0-9-]+))+$/u'; + + // Validate using regex + return preg_match($emailPattern, $emailToValidate); } \ No newline at end of file diff --git a/cp/resources/views/admin/contacts/createContact.twig b/cp/resources/views/admin/contacts/createContact.twig index 81804ce..2307df3 100644 --- a/cp/resources/views/admin/contacts/createContact.twig +++ b/cp/resources/views/admin/contacts/createContact.twig @@ -37,7 +37,7 @@
- +