浏览代码

[Web] Verify OPTIONAL license plus minor fixes

andryyy 6 年之前
父节点
当前提交
9a500a7068

+ 36 - 2
data/web/admin.php

@@ -76,8 +76,40 @@ $tfa_data = get_tfa();
             </select>
           </div>
         </div>
-        <legend data-target="#api" style="margin-top:40px;cursor:pointer" class="arrow-toggle" unselectable="on" data-toggle="collapse">
-          <span style="font-size:12px" class="arrow rotate glyphicon glyphicon-menu-down"></span> API (experimental, work in progress)
+
+        <legend data-target="#license" class="arrow-toggle" unselectable="on" data-toggle="collapse">
+          <span style="font-size:12px" class="arrow rotate glyphicon glyphicon-menu-down"></span> <?=$lang['admin']['guid_and_license'];?>
+        </legend>
+        <div id="license" class="collapse in">
+        <form class="form-horizontal" autocapitalize="none" autocorrect="off" role="form" method="post">
+          <div class="form-group">
+            <label class="control-label col-sm-3" for="guid"><?=$lang['admin']['guid'];?>:</label>
+            <div class="col-sm-9">
+              <div class="input-group">
+                <span class="input-group-addon">
+                  <span class="glyphicon <?=(isset($_SESSION['gal']['valid']) && $_SESSION['gal']['valid'] === true) ? 'glyphicon-heart text-danger' : 'glyphicon-remove';?>" aria-hidden="true"></span>
+                </span>
+                <input type="text" id="guid" class="form-control" value="<?=license('guid');?>" readonly>
+              </div>
+              <p class="help-block">
+                <?=$lang['admin']['customer_id'];?>: <?=(isset($_SESSION['gal']['c'])) ? $_SESSION['gal']['c'] : '?';?> -
+                <?=$lang['admin']['service_id'];?>: <?=(isset($_SESSION['gal']['s'])) ? $_SESSION['gal']['s'] : '?';?>
+              </p>
+            </div>
+          </div>
+          <div class="form-group">
+            <div class="col-sm-offset-3 col-sm-9">
+              <p class="help-block"><?=$lang['admin']['license_info'];?></p>
+              <div class="btn-group">
+                <button class="btn btn-sm btn-success" name="license_validate_now" type="submit" href="#"><?=$lang['admin']['validate_license_now'];?></button>
+              </div>
+            </div>
+          </div>
+        </form>
+        </div>
+
+        <legend data-target="#api" class="arrow-toggle" unselectable="on" data-toggle="collapse">
+          <span style="font-size:12px" class="arrow rotate glyphicon glyphicon-menu-down"></span> API
         </legend>
         <?php
         $api = admin_api('get');
@@ -105,6 +137,7 @@ $tfa_data = get_tfa();
           </div>
           <div class="form-group">
             <div class="col-sm-offset-3 col-sm-9">
+              <p class="help-block"><?=$lang['admin']['api_info'];?></p>
               <div class="btn-group">
                 <button class="btn btn-default" name="admin_api" type="submit" href="#"><span class="glyphicon glyphicon-check"></span> <?=$lang['admin']['save'];?></button>
                 <button class="btn btn-info" name="admin_api_regen_key" type="submit" href="#"><?=$lang['admin']['regen_api_key'];?></button>
@@ -113,6 +146,7 @@ $tfa_data = get_tfa();
           </div>
         </form>
         </div>
+
       </div>
     </div>
 

+ 8 - 8
data/web/edit.php

@@ -515,13 +515,13 @@ if (isset($_SESSION['mailcow_cc_role'])) {
           <input type="hidden" value="0" name="force_pw_update">
           <input type="hidden" value="0" name="sogo_access">
           <div class="form-group">
-            <label class="control-label col-sm-2" for="name"><?=$lang['edit']['full_name'];?>:</label>
+            <label class="control-label col-sm-2" for="name"><?=$lang['edit']['full_name'];?></label>
             <div class="col-sm-10">
             <input type="text" class="form-control" name="name" value="<?=htmlspecialchars($result['name'], ENT_QUOTES, 'UTF-8');?>">
             </div>
           </div>
           <div class="form-group">
-            <label class="control-label col-sm-2" for="quota"><?=$lang['edit']['quota_mb'];?>:
+            <label class="control-label col-sm-2" for="quota"><?=$lang['edit']['quota_mb'];?>
               <br /><span id="quotaBadge" class="badge">max. <?=intval($result['max_new_quota'] / 1048576)?> MiB</span>
             </label>
             <div class="col-sm-10">
@@ -530,7 +530,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
             </div>
           </div>
           <div class="form-group">
-            <label class="control-label col-sm-2" for="sender_acl"><?=$lang['edit']['sender_acl'];?>:</label>
+            <label class="control-label col-sm-2" for="sender_acl"><?=$lang['edit']['sender_acl'];?></label>
             <div class="col-sm-10">
               <select data-live-search="true" data-width="100%" style="width:100%" id="editSelectSenderACL" name="sender_acl" size="10" multiple>
               <?php
@@ -789,7 +789,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
               </div>
             </div>
             <div class="form-group">
-              <label class="control-label col-sm-2" for="domain"><?=$lang['edit']['kind'];?>:</label>
+              <label class="control-label col-sm-2" for="domain"><?=$lang['edit']['kind'];?></label>
               <div class="col-sm-10">
                 <select name="kind" title="<?=$lang['edit']['select'];?>" required>
                   <option value="location" <?=($result['kind'] == "location") ? "selected" : null;?>>Location</option>
@@ -799,7 +799,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
               </div>
             </div>
             <div class="form-group">
-              <label class="control-label col-sm-2" for="multiple_bookings_select"><?=$lang['add']['multiple_bookings'];?>:</label>
+              <label class="control-label col-sm-2" for="multiple_bookings_select"><?=$lang['add']['multiple_bookings'];?></label>
               <div class="col-sm-10">
                 <select name="multiple_bookings_select" id="editSelectMultipleBookings" title="<?=$lang['add']['select'];?>" required>
                   <option value="0" <?=($result['multiple_bookings'] == 0) ? "selected" : null;?>><?=$lang['mailbox']['booking_0'];?></option>
@@ -1032,7 +1032,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
               </div>
             </div>
             <div class="form-group">
-              <label class="control-label col-sm-2" for="enc1"><?=$lang['edit']['encryption'];?>:</label>
+              <label class="control-label col-sm-2" for="enc1"><?=$lang['edit']['encryption'];?></label>
               <div class="col-sm-10">
                 <select id="enc1" name="enc1">
                   <option <?=($result['enc1'] == "TLS") ? "selected" : null;?>>TLS</option>
@@ -1168,13 +1168,13 @@ if (isset($_SESSION['mailcow_cc_role'])) {
           <form class="form-horizontal" data-id="editfilter" role="form" method="post">
             <input type="hidden" value="0" name="active">
             <div class="form-group">
-              <label class="control-label col-sm-2" for="script_desc"><?=$lang['edit']['sieve_desc'];?>:</label>
+              <label class="control-label col-sm-2" for="script_desc"><?=$lang['edit']['sieve_desc'];?></label>
               <div class="col-sm-10">
               <input type="text" class="form-control" name="script_desc" id="script_desc" value="<?=htmlspecialchars($result['script_desc'], ENT_QUOTES, 'UTF-8');?>" required maxlength="255">
               </div>
             </div>
             <div class="form-group">
-              <label class="control-label col-sm-2" for="filter_type"><?=$lang['edit']['sieve_type'];?>:</label>
+              <label class="control-label col-sm-2" for="filter_type"><?=$lang['edit']['sieve_type'];?></label>
               <div class="col-sm-10">
                 <select id="addFilterType" name="filter_type" id="filter_type" required>
                   <option value="prefilter" <?=($result['filter_type'] == 'prefilter') ? 'selected' : null;?>>Prefilter</option>

+ 53 - 0
data/web/inc/functions.inc.php

@@ -1223,6 +1223,59 @@ function admin_api($action, $data = null) {
 		'msg' => 'admin_api_modified'
 	);
 }
+function license($action, $data = null) {
+	global $pdo;
+	global $redis;
+	global $lang;
+	if ($_SESSION['mailcow_cc_role'] != "admin") {
+		$_SESSION['return'][] =  array(
+			'type' => 'danger',
+      'log' => array(__FUNCTION__),
+			'msg' => 'access_denied'
+		);
+		return false;
+	}
+	switch ($action) {
+		case "verify":
+      // Keep result until revalidate button is pressed or session expired
+      $stmt = $pdo->query("SELECT `version` FROM `versions` WHERE `application` = 'GUID'");
+      $versions = $stmt->fetch(PDO::FETCH_ASSOC);
+      $post = array('guid' => $versions['version']);
+      $curl = curl_init('https://verify.mailcow.email');
+      curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+      curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
+      curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
+      $response = curl_exec($curl);
+      curl_close($curl);
+      $json_return = json_decode($response, true);
+      if ($response && $json_return) {
+        if ($json_return['response'] === "ok") {
+          $_SESSION['gal']['valid'] = true;
+          $_SESSION['gal']['c'] = $json_return['c'];
+          $_SESSION['gal']['s'] = $json_return['s'];
+          return true;
+        }
+        if ($json_return['response'] === "invalid") {
+          $_SESSION['gal']['valid'] = false;
+          $_SESSION['gal']['c'] = $lang['mailbox']['no'];
+          $_SESSION['gal']['s'] = $lang['mailbox']['no'];
+          return true;
+        }
+      }
+      else {
+        $_SESSION['gal']['valid'] = false;
+        $_SESSION['gal']['c'] = $lang['danger']['temp_error'];
+        $_SESSION['gal']['s'] = $lang['danger']['temp_error'];
+        return false;
+      }
+    break;
+    case "guid":
+      $stmt = $pdo->query("SELECT `version` FROM `versions` WHERE `application` = 'GUID'");
+      $versions = $stmt->fetch(PDO::FETCH_ASSOC);
+      return $versions['version'];
+    break;
+  }
+}
 function rspamd_ui($action, $data = null) {
 	global $lang;
 	if ($_SESSION['mailcow_cc_role'] != "admin") {

+ 1 - 1
data/web/inc/functions.mailbox.inc.php

@@ -1887,7 +1887,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
                 $relayhost            = (isset($_data['relayhost'])) ? intval($_data['relayhost']) : $is_now['relayhost'];
                 $aliases              = (!empty($_data['aliases'])) ? $_data['aliases'] : $is_now['max_num_aliases_for_domain'];
                 $mailboxes            = (isset($_data['mailboxes']) && $_data['mailboxes'] != '') ? intval($_data['mailboxes']) : $is_now['max_num_mboxes_for_domain'];
-                $defquota             = (!empty($_data['defquota'])) ? $_data['defquota'] : ($is_now['def_quota_for_mbox'] / 1048576);
+                $defquota             = (isset($_data['defquota']) && $_data['defquota'] != '') ? intval($_data['defquota']) : ($is_now['def_quota_for_mbox'] / 1048576);
                 $maxquota             = (!empty($_data['maxquota'])) ? $_data['maxquota'] : ($is_now['max_quota_for_mbox'] / 1048576);
                 $quota                = (!empty($_data['quota'])) ? $_data['quota'] : ($is_now['max_quota_for_domain'] / 1048576);
                 $description          = (!empty($_data['description'])) ? $_data['description'] : $is_now['description'];

+ 0 - 1
data/web/inc/prerequisites.inc.php

@@ -191,4 +191,3 @@ if (isset($_SESSION['mailcow_cc_role'])) {
   acl('to_session');
 }
 $UI_TEXTS = customize('get', 'ui_texts');
-

+ 5 - 2
data/web/inc/triggers.inc.php

@@ -90,8 +90,11 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "admi
 	if (isset($_POST["reset_main_logo"])) {
     customize('delete', 'main_logo');
 	}
-  // API cannot be controlled by API
-	if (isset($_POST["admin_api"])) {
+  // API and license cannot be controlled by API
+	if (isset($_POST["license_validate_now"])) {
+		license('verify');
+	}
+  if (isset($_POST["admin_api"])) {
 		admin_api('edit', $_POST);
 	}
 	if (isset($_POST["admin_api_regen_key"])) {

+ 18 - 0
data/web/lang/lang.de.php

@@ -116,6 +116,7 @@ $lang['success']['domain_admin_added'] = 'Domain-Administrator %s wurde angelegt
 $lang['success']['admin_added'] = 'Administrator %s wurde angelegt';
 $lang['success']['admin_modified'] = 'Änderungen am Administrator wurden gespeichert';
 $lang['success']['admin_api_modified'] = "Änderungen an API wurden gespeichert";
+$lang['success']['license_modified'] = "Änderungen an Lizenz wurden gespeichert";
 $lang['danger']['username_invalid'] = 'Benutzername %s kann nicht verwendet werden';
 $lang['danger']['password_mismatch'] = 'Passwort-Wiederholung stimmt nicht überein';
 $lang['danger']['password_complexity'] = 'Passwort entspricht nicht den Richtlinien';
@@ -809,6 +810,7 @@ $lang['success']['tls_policy_map_entry_saved'] = 'TLS-Richtlinieneintrag "%s" wu
 $lang['success']['tls_policy_map_entry_deleted'] = 'TLS-Richtlinie mit der ID %s wurde gelöscht';
 $lang['mailbox']['add_tls_policy_map'] = "TLS-Richtlinieneintrag hinzufügen";
 $lang['danger']['tls_policy_map_parameter_invalid'] = "Parameter ist ungültig";
+$lang['danger']['temp_error'] = "Temporärer Fehler";
 
 $lang['oauth2']['scope_ask_permission'] = 'Eine Anwendung hat um die folgenden Berechtigungen gebeten';
 $lang['oauth2']['profile'] = 'Profil';
@@ -834,3 +836,19 @@ $lang['danger']['text_empty'] = 'Text darf nicht leer sein';
 $lang['danger']['subject_empty'] = 'Betreff darf nicht leer sein';
 $lang['danger']['from_invalid'] = 'From address must be a valid email address';
 $lang['danger']['network_host_invalid'] = 'Netzwerk oder Host ungültig: %s';
+
+$lang['add']['mailbox_quota_def'] = 'Standard-Quota einer Mailbox:';
+$lang['edit']['mailbox_quota_def'] = 'Standard-Quota einer Mailbox:';
+$lang['danger']['mailbox_defquota_exceeds_mailbox_maxquota'] = 'Standard-Quota überschreitet das Limit der maximal erlaubten Größe einer Mailbox';
+$lang['danger']['defquota_empty'] = 'Standard-Quota darf nicht 0 sein';
+$lang['mailbox']['mailbox_defquota'] = 'Standard-Quota';
+
+$lang['admin']['api_info'] = 'Das API befindet sich noch in Entwicklung, eine Dokumentation ist ausstehend.';
+
+$lang['admin']['guid_and_license'] = 'GUID & Lizenz';
+$lang['admin']['guid'] = 'GUID - Eindeutige Instanz-ID';
+$lang['admin']['license_info'] = 'Eine Lizenz ist nicht erforderlich, hilft jedoch der Entwicklung mailcows.<br><a href="https://www.servercow.de/mailcow#sal" target="_blank" alt="SAL Bestellung">Hier kann die mailcow GUID registriert werden.</a> Alternativ ist <a href="https://www.servercow.de/mailcow#support" target="_blank" alt="SAL Bestellung">die Bestellung von Support-Paketen möglich</a>.';
+$lang['admin']['validate_license_now'] = 'GUID erneut verifizieren';
+$lang['admin']['customer_id'] = 'Kunde';
+$lang['admin']['service_id'] = 'Service';
+

+ 12 - 0
data/web/lang/lang.en.php

@@ -120,6 +120,7 @@ $lang['success']['domain_admin_added'] = "Domain administrator %s has been added
 $lang['success']['admin_added'] = "Administrator %s has been added";
 $lang['success']['admin_modified'] = "Changes to administrator have been saved";
 $lang['success']['admin_api_modified'] = "Changes to API have been saved";
+$lang['success']['license_modified'] = "Changes to license have been saved";
 $lang['danger']['username_invalid'] = "Username %s cannot be used";
 $lang['danger']['password_mismatch'] = "Confirmation password does not match";
 $lang['danger']['password_complexity'] = "Password does not meet the policy";
@@ -837,6 +838,7 @@ $lang['success']['tls_policy_map_entry_saved'] = 'TLS policy map entry "%s" has
 $lang['success']['tls_policy_map_entry_deleted'] = 'TLS policy map ID %s has been deleted';
 $lang['mailbox']['add_recipient_map_entry'] = 'Add recipient map';
 $lang['danger']['tls_policy_map_parameter_invalid'] = "Policy parameter is invalid";
+$lang['danger']['temp_error'] = "Temporary error";
 
 $lang['oauth2']['scope_ask_permission'] = 'An application asked for the following permissions';
 $lang['oauth2']['profile'] = 'Profile';
@@ -868,3 +870,13 @@ $lang['edit']['mailbox_quota_def'] = 'Default mailbox quota';
 $lang['danger']['mailbox_defquota_exceeds_mailbox_maxquota'] = 'Default quota exceeds max quota limit';
 $lang['danger']['defquota_empty'] = 'Default quota per mailbox must not be 0.';
 $lang['mailbox']['mailbox_defquota'] = 'Default mailbox size';
+
+$lang['admin']['api_info'] = 'The API is a work in progress.';
+
+$lang['admin']['guid_and_license'] = 'GUID & License';
+$lang['admin']['guid'] = 'GUID - unique instance ID';
+$lang['admin']['license_info'] = 'A license is not required but helps further development.<br><a href="https://www.servercow.de/mailcow?lang=en#sal" target="_blank" alt="SAL order">Register your GUID here</a> or <a href="https://www.servercow.de/mailcow?lang=en#support" target="_blank" alt="Support order">buy support for your mailcow installation.</a>';
+$lang['admin']['validate_license_now'] = 'Validate GUID against license server';
+
+$lang['admin']['customer_id'] = 'Customer ID';
+$lang['admin']['service_id'] = 'Service ID';

+ 13 - 13
data/web/modals/mailbox.php

@@ -21,7 +21,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
             </div>
           </div>
           <div class="form-group">
-            <label class="control-label col-sm-2" for="domain"><?=$lang['add']['domain'];?>:</label>
+            <label class="control-label col-sm-2" for="domain"><?=$lang['add']['domain'];?></label>
             <div class="col-sm-10">
               <select class="full-width-select" data-live-search="true" id="addSelectDomain" name="domain" required>
               <?php
@@ -87,7 +87,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
       <div class="modal-body">
         <form class="form-horizontal" data-cached-form="true" data-id="add_domain" role="form">
           <div class="form-group">
-            <label class="control-label col-sm-2" for="domain"><?=$lang['add']['domain'];?>:</label>
+            <label class="control-label col-sm-2" for="domain"><?=$lang['add']['domain'];?></label>
             <div class="col-sm-10">
             <input type="text" autocorrect="off" autocapitalize="none" class="form-control" name="domain" required>
             </div>
@@ -199,7 +199,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
             </div>
           </div>
           <div class="form-group">
-            <label class="control-label col-sm-2" for="domain"><?=$lang['add']['domain'];?>:</label>
+            <label class="control-label col-sm-2" for="domain"><?=$lang['add']['domain'];?></label>
             <div class="col-sm-10">
               <select data-live-search="true" name="domain" title="<?=$lang['add']['select'];?>" required>
               <?php
@@ -211,7 +211,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
             </div>
           </div>
           <div class="form-group">
-            <label class="control-label col-sm-2" for="domain"><?=$lang['add']['kind'];?>:</label>
+            <label class="control-label col-sm-2" for="domain"><?=$lang['add']['kind'];?></label>
             <div class="col-sm-10">
               <select name="kind" title="<?=$lang['add']['select'];?>" required>
                 <option value="location">Location</option>
@@ -221,7 +221,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
             </div>
           </div>
           <div class="form-group">
-            <label class="control-label col-sm-2" for="multiple_bookings_select"><?=$lang['add']['multiple_bookings'];?>:</label>
+            <label class="control-label col-sm-2" for="multiple_bookings_select"><?=$lang['add']['multiple_bookings'];?></label>
             <div class="col-sm-10">
               <select name="multiple_bookings_select" id="multiple_bookings_select" title="<?=$lang['add']['select'];?>" required>
                 <option value="0"><?=$lang['mailbox']['booking_0'];?></option>
@@ -376,7 +376,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
         <p class="help-block"><?=$lang['add']['syncjob_hint'];?></p>
         <form class="form-horizontal" data-cached-form="true" role="form" data-id="add_syncjob">
           <div class="form-group">
-            <label class="control-label col-sm-2" for="username"><?=$lang['add']['username'];?>:</label>
+            <label class="control-label col-sm-2" for="username"><?=$lang['add']['username'];?></label>
             <div class="col-sm-10">
               <select data-live-search="true" name="username" required>
               <?php
@@ -552,7 +552,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
       <div class="modal-body">
         <form class="form-horizontal" data-cached-form="true" role="form" data-id="add_filter">
           <div class="form-group">
-            <label class="control-label col-sm-2" for="username"><?=$lang['add']['username'];?>:</label>
+            <label class="control-label col-sm-2" for="username"><?=$lang['add']['username'];?></label>
             <div class="col-sm-10">
               <select data-live-search="true" name="username" required>
               <?php
@@ -570,7 +570,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
             </div>
           </div>
           <div class="form-group">
-            <label class="control-label col-sm-2" for="filter_type"><?=$lang['add']['sieve_type'];?>:</label>
+            <label class="control-label col-sm-2" for="filter_type"><?=$lang['add']['sieve_type'];?></label>
             <div class="col-sm-10">
               <select id="addFilterType" name="filter_type" required>
                 <option value="prefilter">Prefilter</option>
@@ -579,7 +579,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
             </div>
           </div>
           <div class="form-group">
-            <label class="control-label col-sm-2" for="script_desc"><?=$lang['add']['sieve_desc'];?>:</label>
+            <label class="control-label col-sm-2" for="script_desc"><?=$lang['add']['sieve_desc'];?></label>
             <div class="col-sm-10">
             <input type="text" class="form-control" name="script_desc" required maxlength="255">
             </div>
@@ -620,7 +620,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
       <div class="modal-body">
         <form class="form-horizontal" data-cached-form="true" role="form" data-id="add_bcc">
           <div class="form-group">
-            <label class="control-label col-sm-2" for="local_dest"><?=$lang['mailbox']['bcc_local_dest'];?>:</label>
+            <label class="control-label col-sm-2" for="local_dest"><?=$lang['mailbox']['bcc_local_dest'];?></label>
             <div class="col-sm-10">
               <select data-live-search="true" name="local_dest" required>
               <?php
@@ -649,7 +649,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
             </div>
           </div>
           <div class="form-group">
-            <label class="control-label col-sm-2" for="type"><?=$lang['mailbox']['bcc_map_type'];?>:</label>
+            <label class="control-label col-sm-2" for="type"><?=$lang['mailbox']['bcc_map_type'];?></label>
             <div class="col-sm-10">
               <select name="type" required>
                 <option value="sender"><?=$lang['mailbox']['bcc_sender_map'];?></option>
@@ -658,7 +658,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
             </div>
           </div>
           <div class="form-group">
-            <label class="control-label col-sm-2" for="bcc_dest"><?=$lang['mailbox']['bcc_destination'];?>:</label>
+            <label class="control-label col-sm-2" for="bcc_dest"><?=$lang['mailbox']['bcc_destination'];?></label>
             <div class="col-sm-10">
               <input type="text" class="form-control" name="bcc_dest">
             </div>
@@ -739,7 +739,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
             </div>
           </div>
           <div class="form-group">
-            <label class="control-label col-sm-2" for="policy"><?=$lang['mailbox']['tls_map_policy'];?>:</label>
+            <label class="control-label col-sm-2" for="policy"><?=$lang['mailbox']['tls_map_policy'];?></label>
             <div class="col-sm-10">
               <select class="full-width-select" name="policy" required>
                 <option value="none">none</option>