From 9745d5bdc81bcf680696db6c7ef3f34d0acce30c Mon Sep 17 00:00:00 2001
From: Jesse Norell <jesse@kci.net>
Date: Fri, 27 Aug 2021 15:32:23 -0600
Subject: [PATCH] mail: transport domain must be unique per server

---
 install/patches/upd_0094.php                  |  5 +-
 .../sql/incremental/upd_dev_collection.sql    |  4 ++
 install/sql/ispconfig3.sql                    |  2 +-
 .../classes/validate_mail_transport.inc.php   | 63 +++++++++++++++++++
 .../web/mail/form/mail_transport.tform.php    |  8 +++
 interface/web/mail/lib/lang/ar_mail_alias.lng |  4 +-
 .../web/mail/lib/lang/ar_mail_forward.lng     |  2 +-
 .../web/mail/lib/lang/ar_mail_transport.lng   |  2 +-
 interface/web/mail/lib/lang/bg_mail_alias.lng |  4 +-
 .../web/mail/lib/lang/bg_mail_forward.lng     |  2 +-
 .../web/mail/lib/lang/bg_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/br_mail_transport.lng   |  1 +
 .../web/mail/lib/lang/ca_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/cz_mail_transport.lng   |  1 +
 .../web/mail/lib/lang/de_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/dk_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/el_mail_transport.lng   |  2 +-
 interface/web/mail/lib/lang/en_mail_alias.lng |  4 +-
 .../web/mail/lib/lang/en_mail_forward.lng     |  2 +-
 .../web/mail/lib/lang/en_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/es_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/fi_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/fr_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/hr_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/hu_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/id_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/it_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/ja_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/nl_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/pl_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/pt_mail_transport.lng   |  2 +-
 interface/web/mail/lib/lang/ro_mail_alias.lng |  4 +-
 .../web/mail/lib/lang/ro_mail_forward.lng     |  2 +-
 .../web/mail/lib/lang/ro_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/ru_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/se_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/sk_mail_transport.lng   |  2 +-
 .../web/mail/lib/lang/tr_mail_transport.lng   |  2 +-
 38 files changed, 117 insertions(+), 37 deletions(-)
 create mode 100644 interface/lib/classes/validate_mail_transport.inc.php

diff --git a/install/patches/upd_0094.php b/install/patches/upd_0094.php
index b9516e232e..5531e88fa9 100644
--- a/install/patches/upd_0094.php
+++ b/install/patches/upd_0094.php
@@ -8,7 +8,10 @@ class upd_0094 extends installer_patch_update {
 		global $inst;
 
 		// Remove any duplicate mail_forwardings prior to adding unique key
-		$inst->db->query("DELETE FROM mail_forwarding WHERE forwarding_id IN (SELECT forwarding_id FROM (SELECT forwarding_id, COUNT(source) AS source_count FROM mail_forwarding GROUP BY source HAVING source_count > 1) as t1)");
+		$inst->db->query("DELETE FROM mail_forwarding WHERE forwarding_id NOT IN (SELECT MIN(forwarding_id) FROM mail_forwarding GROUP BY source)");
+
+		// Remove any duplicate mail_transports prior to adding unique key
+		$inst->db->query("DELETE FROM mail_transport WHERE transport_id NOT IN (SELECT MIN(transport_id) FROM mail_transport GROUP BY domain, server_id)");
 	}
 
 }
diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql
index 2400ca907a..72f0f03761 100644
--- a/install/sql/incremental/upd_dev_collection.sql
+++ b/install/sql/incremental/upd_dev_collection.sql
@@ -14,3 +14,7 @@ DROP TABLE IF EXISTS `software_package`;
 DROP TABLE IF EXISTS `software_repo`;
 DROP TABLE IF EXISTS `software_update`;
 DROP TABLE IF EXISTS `software_update_inst`;
+
+-- mail_transport.domain must be unique
+ALTER TABLE `mail_transport` DROP KEY `server_id_2`;
+ALTER TABLE `mail_transport` ADD UNIQUE KEY `server_id_2` (`server_id`, `domain`);
diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql
index e37bef7f28..9112599453 100644
--- a/install/sql/ispconfig3.sql
+++ b/install/sql/ispconfig3.sql
@@ -1023,7 +1023,7 @@ CREATE TABLE `mail_transport` (
   `active` enum('n','y') NOT NULL DEFAULT 'n',
   PRIMARY KEY  (`transport_id`),
   KEY `server_id` (`server_id`,`transport`),
-  KEY `server_id_2` (`server_id`,`domain`)
+  UNIQUE KEY `server_id_2` (`server_id`, `domain`)
 ) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
 
 -- --------------------------------------------------------
diff --git a/interface/lib/classes/validate_mail_transport.inc.php b/interface/lib/classes/validate_mail_transport.inc.php
new file mode 100644
index 0000000000..eaf4b92a72
--- /dev/null
+++ b/interface/lib/classes/validate_mail_transport.inc.php
@@ -0,0 +1,63 @@
+<?php
+
+/*
+Copyright (c) 2007, Till Brehm, projektfarm Gmbh
+Copyright (c) 2021, Jesse Norell <jesse@kci.net>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of ISPConfig nor the names of its contributors
+      may be used to endorse or promote products derived from this software without
+      specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+class validate_mail_transport {
+
+	function get_error($errmsg) {
+		global $app;
+
+		if(isset($app->tform->wordbook[$errmsg])) {
+			return $app->tform->wordbook[$errmsg]."<br>\r\n";
+		} else {
+			return $errmsg."<br>\r\n";
+		}
+	}
+
+	/* Validator function for checking the 'domain' of a mail transport */
+	function validate_domain($field_name, $field_value, $validator) {
+		global $app, $conf;
+
+		if(empty($field_value) || $field_name != 'domain') return;
+
+		if(isset($app->remoting_lib->primary_id)) {
+			$id = $app->remoting_lib->primary_id;
+		} else {
+			$id = $app->tform->primary_id;
+		}
+
+		// 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, $conf['server_id'], $id);
+
+		if($domain_check) return $this->get_error('domain_error_unique');
+	}
+
+}
diff --git a/interface/web/mail/form/mail_transport.tform.php b/interface/web/mail/form/mail_transport.tform.php
index b40ad86e8a..deb83d629d 100644
--- a/interface/web/mail/form/mail_transport.tform.php
+++ b/interface/web/mail/form/mail_transport.tform.php
@@ -88,6 +88,14 @@ $form["tabs"]['transport'] = array (
 				4 => array( 'event' => 'SAVE',
 					'type' => 'STRIPNL')
 			),
+			'validators' => array(
+				0 => array(
+					'type' => 'CUSTOM',
+					'class' => 'validate_mail_transport',
+					'function' => 'validate_domain',
+					'errmsg'=> 'domain_error_unique',
+				)
+			),
 			'default' => '',
 			'value'  => '',
 			'width'  => '30',
diff --git a/interface/web/mail/lib/lang/ar_mail_alias.lng b/interface/web/mail/lib/lang/ar_mail_alias.lng
index 98921ce7ce..fbfd79b501 100644
--- a/interface/web/mail/lib/lang/ar_mail_alias.lng
+++ b/interface/web/mail/lib/lang/ar_mail_alias.lng
@@ -3,9 +3,9 @@ $wb['email_txt'] = 'Email';
 $wb['destination_txt'] = 'Destination';
 $wb['active_txt'] = 'Active';
 $wb['email_error_isemail'] = 'Email address is invalid.';
-$wb['email_error_unique'] = 'Duplicate Emailaddress.';
+$wb['email_error_unique'] = 'Duplicate Email Address.';
 $wb['no_domain_perm'] = 'You have no permission for this domain.';
-$wb['destination_error_isemail'] = 'Destination Emailaddress is invalid.';
+$wb['destination_error_isemail'] = 'Destination Email Address is invalid.';
 $wb['limit_mailalias_txt'] = 'The max. number of email aliases for your account is reached.';
 $wb['duplicate_mailbox_txt'] = 'There is already a mailbox with this email address';
 $wb['domain_txt'] = 'Domain';
diff --git a/interface/web/mail/lib/lang/ar_mail_forward.lng b/interface/web/mail/lib/lang/ar_mail_forward.lng
index 4291bd415c..29d0d91a57 100644
--- a/interface/web/mail/lib/lang/ar_mail_forward.lng
+++ b/interface/web/mail/lib/lang/ar_mail_forward.lng
@@ -10,6 +10,6 @@ $wb['greylisting_txt'] = 'Enable greylisting';
 $wb['destination_error_empty'] = 'The destination must not be empty.';
 $wb['destination_error_isemail'] = 'The destination contains at least one invalid email address.';
 $wb['email_error_isemail'] = 'Please enter a valid email address.';
-$wb['email_error_unique'] = 'Duplicate Emailaddress.';
+$wb['email_error_unique'] = 'Duplicate Email Address.';
 $wb['send_as_txt'] = 'Send as';
 $wb['send_as_exp'] = 'Allow target to send mail using this address as origin (if target is internal)';
diff --git a/interface/web/mail/lib/lang/ar_mail_transport.lng b/interface/web/mail/lib/lang/ar_mail_transport.lng
index c249863469..16c33c0201 100644
--- a/interface/web/mail/lib/lang/ar_mail_transport.lng
+++ b/interface/web/mail/lib/lang/ar_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Sort by';
 $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.';
diff --git a/interface/web/mail/lib/lang/bg_mail_alias.lng b/interface/web/mail/lib/lang/bg_mail_alias.lng
index 98921ce7ce..fbfd79b501 100644
--- a/interface/web/mail/lib/lang/bg_mail_alias.lng
+++ b/interface/web/mail/lib/lang/bg_mail_alias.lng
@@ -3,9 +3,9 @@ $wb['email_txt'] = 'Email';
 $wb['destination_txt'] = 'Destination';
 $wb['active_txt'] = 'Active';
 $wb['email_error_isemail'] = 'Email address is invalid.';
-$wb['email_error_unique'] = 'Duplicate Emailaddress.';
+$wb['email_error_unique'] = 'Duplicate Email Address.';
 $wb['no_domain_perm'] = 'You have no permission for this domain.';
-$wb['destination_error_isemail'] = 'Destination Emailaddress is invalid.';
+$wb['destination_error_isemail'] = 'Destination Email Address is invalid.';
 $wb['limit_mailalias_txt'] = 'The max. number of email aliases for your account is reached.';
 $wb['duplicate_mailbox_txt'] = 'There is already a mailbox with this email address';
 $wb['domain_txt'] = 'Domain';
diff --git a/interface/web/mail/lib/lang/bg_mail_forward.lng b/interface/web/mail/lib/lang/bg_mail_forward.lng
index 1e12ca1ece..10193da740 100644
--- a/interface/web/mail/lib/lang/bg_mail_forward.lng
+++ b/interface/web/mail/lib/lang/bg_mail_forward.lng
@@ -10,6 +10,6 @@ $wb['greylisting_txt'] = 'Enable greylisting';
 $wb['destination_error_empty'] = 'The destination must not be empty.';
 $wb['destination_error_isemail'] = 'The destination contains at least one invalid email address.';
 $wb['email_error_isemail'] = 'Please enter a valid email address.';
-$wb['email_error_unique'] = 'Duplicate Emailaddress.';
+$wb['email_error_unique'] = 'Duplicate Email Address.';
 $wb['send_as_txt'] = 'Send as';
 $wb['send_as_exp'] = 'Allow target to send mail using this address as origin (if target is internal)';
diff --git a/interface/web/mail/lib/lang/bg_mail_transport.lng b/interface/web/mail/lib/lang/bg_mail_transport.lng
index 57394dc218..0f4a8db0b8 100644
--- a/interface/web/mail/lib/lang/bg_mail_transport.lng
+++ b/interface/web/mail/lib/lang/bg_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Сортирай по';
 $wb['active_txt'] = 'Активен';
 $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.';
diff --git a/interface/web/mail/lib/lang/br_mail_transport.lng b/interface/web/mail/lib/lang/br_mail_transport.lng
index 3f87343dbc..afe35c1a7e 100644
--- a/interface/web/mail/lib/lang/br_mail_transport.lng
+++ b/interface/web/mail/lib/lang/br_mail_transport.lng
@@ -8,3 +8,4 @@ $wb['sort_order_txt'] = 'Ordenar por';
 $wb['active_txt'] = 'Ativo';
 $wb['limit_mailrouting_txt'] = 'O limite de rotas de email para esta conta foi alcançado.';
 $wb['transport_txt'] = 'Transporte';
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/ca_mail_transport.lng b/interface/web/mail/lib/lang/ca_mail_transport.lng
index f8a5536560..7b12c7d0eb 100644
--- a/interface/web/mail/lib/lang/ca_mail_transport.lng
+++ b/interface/web/mail/lib/lang/ca_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Trier par';
 $wb['active_txt'] = 'Actif';
 $wb['limit_mailrouting_txt'] = 'Le nombre maximal de routes pour votre compte a été atteint.';
 $wb['transport_txt'] = 'Transport';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/cz_mail_transport.lng b/interface/web/mail/lib/lang/cz_mail_transport.lng
index 14c7dc2934..d2dfec591f 100644
--- a/interface/web/mail/lib/lang/cz_mail_transport.lng
+++ b/interface/web/mail/lib/lang/cz_mail_transport.lng
@@ -8,3 +8,4 @@ $wb['sort_order_txt'] = 'Třídit podle';
 $wb['active_txt'] = 'Aktivní';
 $wb['limit_mailrouting_txt'] = 'Byl dosažen maximální počet e-mail směrování pro Váš účet.';
 $wb['transport_txt'] = 'Transport';
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/de_mail_transport.lng b/interface/web/mail/lib/lang/de_mail_transport.lng
index 873036f947..724882866f 100644
--- a/interface/web/mail/lib/lang/de_mail_transport.lng
+++ b/interface/web/mail/lib/lang/de_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Sortiert nach';
 $wb['active_txt'] = 'Aktiv';
 $wb['limit_mailrouting_txt'] = 'Die maximale Anzahl an E-Mail Routen für Ihr Konto wurde erreicht.';
 $wb['transport_txt'] = 'Transport';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/dk_mail_transport.lng b/interface/web/mail/lib/lang/dk_mail_transport.lng
index df2131cde4..bb8a94f433 100644
--- a/interface/web/mail/lib/lang/dk_mail_transport.lng
+++ b/interface/web/mail/lib/lang/dk_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Sort by';
 $wb['active_txt'] = 'Aktiv';
 $wb['limit_mailrouting_txt'] = 'Max. antal af ruter for din konto er nået.';
 $wb['transport_txt'] = 'Transport';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/el_mail_transport.lng b/interface/web/mail/lib/lang/el_mail_transport.lng
index 1b1a5c7ab4..37eef348b6 100644
--- a/interface/web/mail/lib/lang/el_mail_transport.lng
+++ b/interface/web/mail/lib/lang/el_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Ταξινόμηση κατά';
 $wb['active_txt'] = 'Ενεργό';
 $wb['limit_mailrouting_txt'] = 'Το μέγιστο πλήθος των δρομολογήσεων email για τον λογαριασμό σας, εξαντλήθηκε.';
 $wb['transport_txt'] = 'Transport';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/en_mail_alias.lng b/interface/web/mail/lib/lang/en_mail_alias.lng
index 23c567125d..84770e4c7e 100644
--- a/interface/web/mail/lib/lang/en_mail_alias.lng
+++ b/interface/web/mail/lib/lang/en_mail_alias.lng
@@ -3,9 +3,9 @@ $wb['email_txt'] = 'Email';
 $wb['destination_txt'] = 'Destination';
 $wb['active_txt'] = 'Active';
 $wb['email_error_isemail'] = 'Email address is invalid.';
-$wb['email_error_unique'] = 'Duplicate Emailaddress.';
+$wb['email_error_unique'] = 'Duplicate Email Address.';
 $wb['no_domain_perm'] = 'You have no permission for this domain.';
-$wb['destination_error_isemail'] = 'Destination Emailaddress is invalid.';
+$wb['destination_error_isemail'] = 'Destination Email Address is invalid.';
 $wb['limit_mailalias_txt'] = 'The max. number of email aliases for your account is reached.';
 $wb['duplicate_mailbox_txt'] = 'There is already a mailbox with this email address.';
 $wb['domain_txt'] = 'Domain';
diff --git a/interface/web/mail/lib/lang/en_mail_forward.lng b/interface/web/mail/lib/lang/en_mail_forward.lng
index 6be6ab7e70..65b2b753d9 100644
--- a/interface/web/mail/lib/lang/en_mail_forward.lng
+++ b/interface/web/mail/lib/lang/en_mail_forward.lng
@@ -9,7 +9,7 @@ $wb['source_txt'] = 'Source Email';
 $wb['destination_error_empty'] = 'The destination must not be empty.';
 $wb['destination_error_isemail'] = 'The destination contains at least one invalid email address.';
 $wb['email_error_isemail'] = 'Please enter a valid email address.';
-$wb['email_error_unique'] = 'Duplicate Emailaddress.';
+$wb['email_error_unique'] = 'Duplicate Email Address.';
 $wb['send_as_txt'] = 'Send as';
 $wb['send_as_exp'] = 'Allow target to send mail using this address as origin (if target is internal)';
 $wb['greylisting_txt'] = 'Enable greylisting';
diff --git a/interface/web/mail/lib/lang/en_mail_transport.lng b/interface/web/mail/lib/lang/en_mail_transport.lng
index a0b3dd808b..16c33c0201 100644
--- a/interface/web/mail/lib/lang/en_mail_transport.lng
+++ b/interface/web/mail/lib/lang/en_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Sort by';
 $wb['active_txt'] = 'Active';
 $wb['limit_mailrouting_txt'] = 'The max. number of routes for your account is reached.';
 $wb['transport_txt'] = 'Transport';
-?>
\ No newline at end of file
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/es_mail_transport.lng b/interface/web/mail/lib/lang/es_mail_transport.lng
index b35ee39188..e0b3b4ad81 100644
--- a/interface/web/mail/lib/lang/es_mail_transport.lng
+++ b/interface/web/mail/lib/lang/es_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['server_id_txt'] = 'Servidor';
 $wb['sort_order_txt'] = 'Ordenar por';
 $wb['transport_txt'] = 'Transporte';
 $wb['type_txt'] = 'Tipo';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/fi_mail_transport.lng b/interface/web/mail/lib/lang/fi_mail_transport.lng
index 01be49e44a..24675e457f 100644
--- a/interface/web/mail/lib/lang/fi_mail_transport.lng
+++ b/interface/web/mail/lib/lang/fi_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Järjestä..';
 $wb['active_txt'] = 'Käytössä';
 $wb['limit_mailrouting_txt'] = 'Käyttäjätunnuksella on jo sallittu määrä sähköpostireitityksiä.';
 $wb['transport_txt'] = 'Transport';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/fr_mail_transport.lng b/interface/web/mail/lib/lang/fr_mail_transport.lng
index f8a5536560..7b12c7d0eb 100644
--- a/interface/web/mail/lib/lang/fr_mail_transport.lng
+++ b/interface/web/mail/lib/lang/fr_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Trier par';
 $wb['active_txt'] = 'Actif';
 $wb['limit_mailrouting_txt'] = 'Le nombre maximal de routes pour votre compte a été atteint.';
 $wb['transport_txt'] = 'Transport';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/hr_mail_transport.lng b/interface/web/mail/lib/lang/hr_mail_transport.lng
index c27687f956..923ac09d52 100644
--- a/interface/web/mail/lib/lang/hr_mail_transport.lng
+++ b/interface/web/mail/lib/lang/hr_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Sortiraj';
 $wb['active_txt'] = 'Aktivno';
 $wb['limit_mailrouting_txt'] = 'Iskorišten je maksimalan broj ruta.';
 $wb['transport_txt'] = 'Transport';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/hu_mail_transport.lng b/interface/web/mail/lib/lang/hu_mail_transport.lng
index 7ade063c2b..08e8300e2e 100644
--- a/interface/web/mail/lib/lang/hu_mail_transport.lng
+++ b/interface/web/mail/lib/lang/hu_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Rendezés';
 $wb['active_txt'] = 'Aktív';
 $wb['limit_mailrouting_txt'] = 'Nincs több Email irányítás lehetőség.';
 $wb['transport_txt'] = 'Transport';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/id_mail_transport.lng b/interface/web/mail/lib/lang/id_mail_transport.lng
index 8ad3dacf2a..818f6f7280 100644
--- a/interface/web/mail/lib/lang/id_mail_transport.lng
+++ b/interface/web/mail/lib/lang/id_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Urutkan berdasarkan';
 $wb['active_txt'] = 'Aktif';
 $wb['limit_mailrouting_txt'] = 'Jumlah maks rute untuk akun Anda telah tercapai.';
 $wb['transport_txt'] = 'Transport';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/it_mail_transport.lng b/interface/web/mail/lib/lang/it_mail_transport.lng
index 9273621ff1..fbd1a58087 100644
--- a/interface/web/mail/lib/lang/it_mail_transport.lng
+++ b/interface/web/mail/lib/lang/it_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Ordina per';
 $wb['active_txt'] = 'Attivo';
 $wb['limit_mailrouting_txt'] = 'The max. number of routes raggiunto per il tuo account.';
 $wb['transport_txt'] = 'Transport';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/ja_mail_transport.lng b/interface/web/mail/lib/lang/ja_mail_transport.lng
index a870dd118a..afccb01956 100644
--- a/interface/web/mail/lib/lang/ja_mail_transport.lng
+++ b/interface/web/mail/lib/lang/ja_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = '優先度';
 $wb['active_txt'] = '有効';
 $wb['limit_mailrouting_txt'] = '最大数に達した為、これ以上配送経路を追加できません。';
 $wb['transport_txt'] = 'Transport';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/nl_mail_transport.lng b/interface/web/mail/lib/lang/nl_mail_transport.lng
index 9e792e8762..d7ecc761e6 100644
--- a/interface/web/mail/lib/lang/nl_mail_transport.lng
+++ b/interface/web/mail/lib/lang/nl_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Gesorteerd op';
 $wb['active_txt'] = 'Actief';
 $wb['limit_mailrouting_txt'] = 'Het max. aantal routes voor uw account is bereikt.';
 $wb['transport_txt'] = 'Transport';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/pl_mail_transport.lng b/interface/web/mail/lib/lang/pl_mail_transport.lng
index 514fc263a5..672a0c6455 100644
--- a/interface/web/mail/lib/lang/pl_mail_transport.lng
+++ b/interface/web/mail/lib/lang/pl_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Sortuj według';
 $wb['active_txt'] = 'Aktywny';
 $wb['limit_mailrouting_txt'] = 'Maksymalna ilość ścieżek dla Twojego konta została przekroczona.';
 $wb['transport_txt'] = 'Transport';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/pt_mail_transport.lng b/interface/web/mail/lib/lang/pt_mail_transport.lng
index 3c676b8b4a..e41c129ac6 100644
--- a/interface/web/mail/lib/lang/pt_mail_transport.lng
+++ b/interface/web/mail/lib/lang/pt_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Ordenar por';
 $wb['active_txt'] = 'Activo';
 $wb['limit_mailrouting_txt'] = 'O número máximo de rotas para a conta foi atingido.';
 $wb['transport_txt'] = 'Transport';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/ro_mail_alias.lng b/interface/web/mail/lib/lang/ro_mail_alias.lng
index 65b9abbd52..389e96cb4c 100644
--- a/interface/web/mail/lib/lang/ro_mail_alias.lng
+++ b/interface/web/mail/lib/lang/ro_mail_alias.lng
@@ -3,9 +3,9 @@ $wb['email_txt'] = 'Email';
 $wb['destination_txt'] = 'Destinatie';
 $wb['active_txt'] = 'Active';
 $wb['email_error_isemail'] = 'Adresa Email invlida';
-$wb['email_error_unique'] = 'Duplicat Emailaddress.';
+$wb['email_error_unique'] = 'Duplicat Email Address.';
 $wb['no_domain_perm'] = 'NU aveti permisiunea pe acest Domain';
-$wb['destination_error_isemail'] = 'Destinatie Emailaddress  invalida.';
+$wb['destination_error_isemail'] = 'Destinatie Email Address  invalida.';
 $wb['limit_mailalias_txt'] = 'Ati atins numarul maxim de alias-uri pentru contul dumneavoastra ';
 $wb['duplicate_mailbox_txt'] = 'There is already a mailbox with this email address';
 $wb['domain_txt'] = 'Domain';
diff --git a/interface/web/mail/lib/lang/ro_mail_forward.lng b/interface/web/mail/lib/lang/ro_mail_forward.lng
index 3103f26dc8..8d60b16de9 100644
--- a/interface/web/mail/lib/lang/ro_mail_forward.lng
+++ b/interface/web/mail/lib/lang/ro_mail_forward.lng
@@ -10,6 +10,6 @@ $wb['greylisting_txt'] = 'Enable greylisting';
 $wb['destination_error_empty'] = 'The destination must not be empty.';
 $wb['destination_error_isemail'] = 'The destination contains at least one invalid email address.';
 $wb['email_error_isemail'] = 'Please enter a valid email address.';
-$wb['email_error_unique'] = 'Duplicat Emailaddress.';
+$wb['email_error_unique'] = 'Duplicat Email Address.';
 $wb['send_as_txt'] = 'Send as';
 $wb['send_as_exp'] = 'Allow target to send mail using this address as origin (if target is internal)';
diff --git a/interface/web/mail/lib/lang/ro_mail_transport.lng b/interface/web/mail/lib/lang/ro_mail_transport.lng
index 85fd99ad54..736452a6c9 100644
--- a/interface/web/mail/lib/lang/ro_mail_transport.lng
+++ b/interface/web/mail/lib/lang/ro_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Sortare pe ';
 $wb['active_txt'] = 'Active';
 $wb['limit_mailrouting_txt'] = 'numarul maxim de rute pentru contul dumneavoastra a fost atins';
 $wb['transport_txt'] = 'Transport';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/ru_mail_transport.lng b/interface/web/mail/lib/lang/ru_mail_transport.lng
index 05594256fd..2c6d758d9b 100644
--- a/interface/web/mail/lib/lang/ru_mail_transport.lng
+++ b/interface/web/mail/lib/lang/ru_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Сортировать по';
 $wb['active_txt'] = 'Активно';
 $wb['limit_mailrouting_txt'] = 'Достигнуто макс. количество маршрутов для вашей учетной записи.';
 $wb['transport_txt'] = 'Транспорт';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/se_mail_transport.lng b/interface/web/mail/lib/lang/se_mail_transport.lng
index 70e26b78f9..73ac507b47 100644
--- a/interface/web/mail/lib/lang/se_mail_transport.lng
+++ b/interface/web/mail/lib/lang/se_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Sortera på';
 $wb['active_txt'] = 'Aktiv';
 $wb['limit_mailrouting_txt'] = 'Det maximala antalet epostrutter för ditt konto är uppnått.';
 $wb['transport_txt'] = 'Transport';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/sk_mail_transport.lng b/interface/web/mail/lib/lang/sk_mail_transport.lng
index b27c585b04..e35f9d77b2 100644
--- a/interface/web/mail/lib/lang/sk_mail_transport.lng
+++ b/interface/web/mail/lib/lang/sk_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Triediť podľa';
 $wb['active_txt'] = 'Aktívny';
 $wb['limit_mailrouting_txt'] = 'Max. počet trás pre váš účet je dosiahnutý.';
 $wb['transport_txt'] = 'Transport';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
diff --git a/interface/web/mail/lib/lang/tr_mail_transport.lng b/interface/web/mail/lib/lang/tr_mail_transport.lng
index 0b41770392..bc318545a9 100644
--- a/interface/web/mail/lib/lang/tr_mail_transport.lng
+++ b/interface/web/mail/lib/lang/tr_mail_transport.lng
@@ -8,4 +8,4 @@ $wb['sort_order_txt'] = 'Sıralama';
 $wb['active_txt'] = 'Etkin';
 $wb['limit_mailrouting_txt'] = 'Hesabınıza ekleyebileceğiniz en fazla yöneltme sayısına ulaştınız.';
 $wb['transport_txt'] = 'Aktarım';
-?>
+$wb['domain_error_unique'] = 'A mail transport for this Domain already exists on this server.';
-- 
GitLab