From c343a1512d3cabc40a0c02fb9089eecdf91fc0ce Mon Sep 17 00:00:00 2001
From: Demian <demian@pyte.dev>
Date: Fri, 10 Jan 2025 10:41:55 +0100
Subject: [PATCH] Refactored Mail Transport and Domain Validator (#6791)

* Added validation to prevent conflicts between mail domains and mail transports:

    * When adding a new mail domain, the system now checks for existing mail transports with the same domain.
    * When adding a new mail transport (routing), the system verifies that no mail domain with the same domain exists.

* Cleaned up non-functional code in the mail transport validator.
---
 .../classes/validate_mail_transport.inc.php   | 38 ++++++++++++++++++-
 interface/web/mail/form/mail_domain.tform.php |  6 +++
 .../web/mail/form/mail_transport.tform.php    |  6 +++
 .../web/mail/lib/lang/en_mail_domain.lng      |  1 +
 .../web/mail/lib/lang/en_mail_transport.lng   |  1 +
 5 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/interface/lib/classes/validate_mail_transport.inc.php b/interface/lib/classes/validate_mail_transport.inc.php
index 6b47d95303..3396df65cf 100644
--- a/interface/lib/classes/validate_mail_transport.inc.php
+++ b/interface/lib/classes/validate_mail_transport.inc.php
@@ -41,6 +41,40 @@ class validate_mail_transport {
 		}
 	}
 
+	/* Validator function for checking that the 'domain' is not already set as mail_domain */
+	function validate_isnot_maildomain($field_name, $field_value, $validator) {
+		global $app, $conf;
+
+		if(isset($app->remoting_lib->primary_id)) {
+			$id = $app->remoting_lib->primary_id;
+		} else {
+			$id = $app->tform->primary_id;
+		}
+
+		$sql = "SELECT domain_id, domain FROM mail_domain WHERE domain = ? AND domain_id != ?";
+		$domain_check = $app->db->queryOneRecord($sql, $field_value, $id);
+
+		if($domain_check) return $this->get_error('domain_is_maildomain');
+
+	}
+
+	/* Validator function for checking that the 'domain' is not already set as mail_transport */
+	function validate_isnot_mailtransport($field_name, $field_value, $validator) {
+		global $app, $conf;
+
+		if(isset($app->remoting_lib->primary_id)) {
+			$id = $app->remoting_lib->primary_id;
+		} else {
+			$id = $app->tform->primary_id;
+		}
+
+		$sql = "SELECT transport_id, domain FROM mail_transport WHERE domain = ? AND transport_id != ?";
+		$domain_check = $app->db->queryOneRecord($sql, $field_value, $id);
+
+		if($domain_check) return $this->get_error('domain_is_transport');
+
+	}
+
 	/* Validator function for checking the 'domain' of a mail transport */
 	function validate_domain($field_name, $field_value, $validator) {
 		global $app, $conf;
@@ -52,8 +86,8 @@ class validate_mail_transport {
 		}
 
 		// mail_transport.domain (could also be an email address) must be unique per server
-		$sql = "SELECT transport_id, domain FROM mail_transport WHERE domain = ? AND server_id = ? AND transport_id != ?";
-		$domain_check = $app->db->queryOneRecord($sql, $field_value, $app->tform_actions->dataRecord['server_id'], $id);
+		$sql = "SELECT transport_id, domain FROM mail_transport WHERE domain = ? AND transport_id != ?";
+		$domain_check = $app->db->queryOneRecord($sql, $field_value, $id);
 
 		if($domain_check) return $this->get_error('domain_error_unique');
 	}
diff --git a/interface/web/mail/form/mail_domain.tform.php b/interface/web/mail/form/mail_domain.tform.php
index 805d223feb..778611db48 100644
--- a/interface/web/mail/form/mail_domain.tform.php
+++ b/interface/web/mail/form/mail_domain.tform.php
@@ -91,6 +91,12 @@ $form["tabs"]['domain'] = array (
 					'errmsg'=> 'domain_error_unique'),
 				2 => array ( 'type' => 'ISDOMAIN',
 					'errmsg'=> 'domain_error_regex'),
+				3 => array(
+					'type' => 'CUSTOM',
+					'class' => 'validate_mail_transport',
+					'function' => 'validate_isnot_mailtransport',
+					'errmsg'=> 'domain_is_transport',
+				),
 			),
 			'default' => '',
 			'value'  => '',
diff --git a/interface/web/mail/form/mail_transport.tform.php b/interface/web/mail/form/mail_transport.tform.php
index deb83d629d..0adbfadee0 100644
--- a/interface/web/mail/form/mail_transport.tform.php
+++ b/interface/web/mail/form/mail_transport.tform.php
@@ -94,6 +94,12 @@ $form["tabs"]['transport'] = array (
 					'class' => 'validate_mail_transport',
 					'function' => 'validate_domain',
 					'errmsg'=> 'domain_error_unique',
+				),
+				1 => array(
+					'type' => 'CUSTOM',
+					'class' => 'validate_mail_transport',
+					'function' => 'validate_isnot_maildomain',
+					'errmsg' => 'domain_is_maildomain',
 				)
 			),
 			'default' => '',
diff --git a/interface/web/mail/lib/lang/en_mail_domain.lng b/interface/web/mail/lib/lang/en_mail_domain.lng
index 3ac49dd8c6..0fd484562b 100644
--- a/interface/web/mail/lib/lang/en_mail_domain.lng
+++ b/interface/web/mail/lib/lang/en_mail_domain.lng
@@ -24,3 +24,4 @@ $wb['dkim_auto_dns_txt'] = 'Managed zone, dns updated automatically';
 $wb['relayhost_txt'] = 'Relayhost';
 $wb['relayhost_user_txt'] = 'Relayhost User';
 $wb['relayhost_password_txt'] = 'Relayhost Password';
+$wb['domain_is_transport'] = 'The Domain is already set as E-Mail Transport.';
diff --git a/interface/web/mail/lib/lang/en_mail_transport.lng b/interface/web/mail/lib/lang/en_mail_transport.lng
index 16c33c0201..c841cd2132 100644
--- a/interface/web/mail/lib/lang/en_mail_transport.lng
+++ b/interface/web/mail/lib/lang/en_mail_transport.lng
@@ -9,3 +9,4 @@ $wb['active_txt'] = 'Active';
 $wb['limit_mailrouting_txt'] = 'The max. number of routes for your account is reached.';
 $wb['transport_txt'] = 'Transport';
 $wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
+$wb['domain_is_maildomain'] = 'The Domain is already set as a E-Mail Domain.';
-- 
GitLab