diff --git a/data/conf/rspamd/meta_exporter/pushover.php b/data/conf/rspamd/meta_exporter/pushover.php index 6461610c..005bacfe 100644 --- a/data/conf/rspamd/meta_exporter/pushover.php +++ b/data/conf/rspamd/meta_exporter/pushover.php @@ -51,8 +51,20 @@ $headers = getallheaders(); $qid = $headers['X-Rspamd-Qid']; $rcpts = $headers['X-Rspamd-Rcpt']; +$sender = $headers['X-Rspamd-From']; $ip = $headers['X-Rspamd-Ip']; $subject = $headers['X-Rspamd-Subject']; +$priority = 0; + +$symbols_array = json_decode($headers['X-Rspamd-Symbols'], true); +if (is_array($symbols_array)) { + foreach ($symbols_array as $symbol) { + if ($symbol['name'] == 'HAS_X_PRIO_ONE') { + $priority = 2; + break; + } + } +} $rcpt_final_mailboxes = array(); @@ -177,7 +189,7 @@ foreach (json_decode($rcpts, true) as $rcpt) { foreach ($rcpt_final_mailboxes as $rcpt_final) { - error_log("NOTIFY: pushover pipe: processing pushover message for rcpt " . $rcpt_final . PHP_EOL); + error_log("NOTIFY: pushover pipe: processing pushover message for rcpt " . $rcpt_final . " with priority " . $priority . PHP_EOL); $stmt = $pdo->prepare("SELECT * FROM `pushover` WHERE `username` = :username AND `active` = '1'"); $stmt->execute(array( @@ -187,14 +199,30 @@ foreach ($rcpt_final_mailboxes as $rcpt_final) { if (isset($api_data['key']) && isset($api_data['token'])) { $title = (!empty($api_data['title'])) ? $api_data['title'] : 'Mail'; $text = (!empty($api_data['text'])) ? $api_data['text'] : 'You\'ve got mail 📧'; + $attributes = json_decode($api_data['attributes'], true); + $senders = explode(',', $api_data['senders']); + if (!empty($senders) && !in_array($sender, $senders)) { + error_log("NOTIFY: pushover pipe: skipping unwanted sender " . $sender); + continue; + } + if ($attributes['only_x_prio'] == "1" && $priority == 0) { + error_log("NOTIFY: pushover pipe: mail has no X-Priority: 1 header, skipping"); + continue; + } + $post_fields = array( + "token" => $api_data['token'], + "user" => $api_data['key'], + "title" => sprintf("%s", str_replace(array('{SUBJECT}', '{SENDER}'), array($subject, $sender), $title)), + "priority" => $priority, + "message" => sprintf("%s", str_replace(array('{SUBJECT}', '{SENDER}'), array($subject, $sender), $text)) + ); + if ($attributes['evaluate_x_prio'] == "1" && $priority == 2) { + $post_fields['expire'] = 600; + $post_fields['retry'] = 120; + } curl_setopt_array($ch = curl_init(), array( CURLOPT_URL => "https://api.pushover.net/1/messages.json", - CURLOPT_POSTFIELDS => array( - "token" => $api_data['token'], - "user" => $api_data['key'], - "title" => $title, - "message" => sprintf("%s", str_replace('{SUBJECT}', $subject, $text)) - ), + CURLOPT_POSTFIELDS => $post_fields, CURLOPT_SAFE_UPLOAD => true, CURLOPT_RETURNTRANSFER => true, )); diff --git a/data/web/edit.php b/data/web/edit.php index 3cc97916..6d92b28e 100644 --- a/data/web/edit.php +++ b/data/web/edit.php @@ -735,12 +735,16 @@ if (isset($_SESSION['mailcow_cc_role'])) {
+ + +

+

: {SUBJECT}, {SENDER}

@@ -767,6 +771,22 @@ if (isset($_SESSION['mailcow_cc_role'])) {
+
+
+ + +
+
+
+
+ +
+
+
+
+ +
+
diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index 7dda9e40..746779ee 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -3756,6 +3756,10 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $stmt->execute(array( ':domain' => '%@'.$domain, )); + $stmt = $pdo->prepare("DELETE FROM `pushover` WHERE `username` LIKE :domain"); + $stmt->execute(array( + ':domain' => '%@'.$domain, + )); $stmt = $pdo->prepare("DELETE FROM `quota2replica` WHERE `username` LIKE :domain"); $stmt->execute(array( ':domain' => '%@'.$domain, @@ -3954,6 +3958,10 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $stmt->execute(array( ':username' => $username )); + $stmt = $pdo->prepare("DELETE FROM `pushover` WHERE `username` = :username"); + $stmt->execute(array( + ':username' => $username + )); $stmt = $pdo->prepare("DELETE FROM `quarantine` WHERE `rcpt` = :username"); $stmt->execute(array( ':username' => $username diff --git a/data/web/inc/functions.pushover.inc.php b/data/web/inc/functions.pushover.inc.php index f0cca30a..08019364 100644 --- a/data/web/inc/functions.pushover.inc.php +++ b/data/web/inc/functions.pushover.inc.php @@ -43,6 +43,21 @@ function pushover($_action, $_data = null) { } $key = $_data['key']; $token = $_data['token']; + $evaluate_x_prio = $_data['evaluate_x_prio']; + $only_x_prio = $_data['only_x_prio']; + $senders = array_map('trim', preg_split( "/( |,|;|\n)/", $_data['senders'])); + foreach ($senders as $i => &$sender) { + if (empty($sender)) { + continue; + } + if (!filter_var($sender, FILTER_VALIDATE_EMAIL) === true) { + unset($senders[$i]); + continue; + } + } + $senders = array_filter($senders); + if (empty($senders)) { $senders = ''; } + $senders = implode(",", $senders); if (!ctype_alnum($key) || strlen($key) != 30) { $_SESSION['return'][] = array( 'type' => 'danger', @@ -62,11 +77,19 @@ function pushover($_action, $_data = null) { $title = $_data['title']; $text = $_data['text']; $active = intval($_data['active']); - $stmt = $pdo->prepare("REPLACE INTO `pushover` (`username`, `key`, `token`, `title`, `text`, `active`) - VALUES (:username, :key, :token, :title, :text, :active)"); + $po_attributes = json_encode( + array( + 'evaluate_x_prio' => strval(intval($evaluate_x_prio)), + 'only_x_prio' => strval(intval($only_x_prio)) + ) + ); + $stmt = $pdo->prepare("REPLACE INTO `pushover` (`username`, `key`, `attributes`, `senders`, `token`, `title`, `text`, `active`) + VALUES (:username, :key, :po_attributes, :senders, :token, :title, :text, :active)"); $stmt->execute(array( ':username' => $username, ':key' => $key, + ':po_attributes' => $po_attributes, + ':senders' => $senders, ':token' => $token, ':title' => $title, ':text' => $text, @@ -93,6 +116,7 @@ function pushover($_action, $_data = null) { ':username' => $_data )); $data = $stmt->fetch(PDO::FETCH_ASSOC); + $data['attributes'] = json_decode($data['attributes'], true); if (empty($data)) { return false; } diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index fc50971f..0f257097 100644 --- a/data/web/inc/init_db.inc.php +++ b/data/web/inc/init_db.inc.php @@ -3,7 +3,7 @@ function init_db_schema() { try { global $pdo; - $db_version = "09042020_1403"; + $db_version = "16042020_1004"; $stmt = $pdo->query("SHOW TABLES LIKE 'versions'"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); @@ -837,8 +837,10 @@ function init_db_schema() { "username" => "VARCHAR(255) NOT NULL", "key" => "VARCHAR(255) NOT NULL", "token" => "VARCHAR(255) NOT NULL", + "attributes" => "JSON", "title" => "TEXT", "text" => "TEXT", + "senders" => "TEXT", "active" => "TINYINT(1) NOT NULL DEFAULT '1'" ), "keys" => array( @@ -1142,6 +1144,11 @@ function init_db_schema() { $stmt = $pdo->query("DELETE FROM `da_acl` WHERE `username` NOT IN (SELECT `username`FROM `domain_admins`);"); // Migrate attributes + // pushover + $stmt = $pdo->query("UPDATE `pushover` SET `attributes` = '{}' WHERE `attributes` = '' OR `attributes` IS NULL;"); + $stmt = $pdo->query("UPDATE `pushover` SET `attributes` = JSON_SET(`attributes`, '$.evaluate_x_prio', \"0\") WHERE JSON_EXTRACT(`attributes`, '$.evaluate_x_prio') IS NULL;"); + $stmt = $pdo->query("UPDATE `pushover` SET `attributes` = JSON_SET(`attributes`, '$.only_x_prio', \"0\") WHERE JSON_EXTRACT(`attributes`, '$.only_x_prio') IS NULL;"); + // mailbox $stmt = $pdo->query("UPDATE `mailbox` SET `attributes` = '{}' WHERE `attributes` = '' OR `attributes` IS NULL;"); $stmt = $pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.force_pw_update', \"0\") WHERE JSON_EXTRACT(`attributes`, '$.force_pw_update') IS NULL;"); $stmt = $pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.sogo_access', \"1\") WHERE JSON_EXTRACT(`attributes`, '$.sogo_access') IS NULL;"); diff --git a/data/web/lang/lang.de.json b/data/web/lang/lang.de.json index 00e23ebb..faf9eab6 100644 --- a/data/web/lang/lang.de.json +++ b/data/web/lang/lang.de.json @@ -236,7 +236,9 @@ "title": "Title", "pushover_title": "Notification Titel", "text": "Text", - "pushover_text": "Notification Text ({SUBJECT} entspricht dem Mail-Betreff)", + "pushover_text": "Notification Text", + "pushover_vars": "Verwendbare Variablen für Titel und Text (Datenschutzrichtlinien beachten)", + "pushover_sender_array": "Nur folgende Sender E-Mail-Adressen berücksichtigen (getrennt durch Komma)", "last_mail_login": "Letzter Mail-Login", "no_last_login": "Keine letzte UI Anmeldung gespeichert", "save": "Änderungen speichern", @@ -354,7 +356,9 @@ "title": "Title", "pushover_title": "Notification Titel", "text": "Text", - "pushover_text": "Notification Text ({SUBJECT} entspricht dem Mail-Betreff)", + "pushover_text": "Notification Text", + "pushover_vars": "Verwendbare Variablen für Titel und Text (Datenschutzrichtlinien beachten)", + "pushover_sender_array": "Nur folgende Sender E-Mail-Adressen berücksichtigen (getrennt durch Komma)", "spamfilter": "Spamfilter", "domain_s": "Domain(s)", "rspamd-com_settings": "Ein Name wird automatisch generiert. Beispielinhalte zur Einsicht stehen nachstehend bereit. Siehe auch Rspamd docs", @@ -721,6 +725,8 @@ "sieve_preset_7": "Weiterleiten und behalten oder verwerfen" }, "edit": { + "evaluate_x_prio": "Hohe Priorität eskalieren [X-Priority: 1]", + "only_x_prio": "Nur Mail mit hoher Priorität berücksichtigen [X-Priority: 1]", "generate": "generieren", "app_name": "App Name", "app_passwd": "App Passwörter", diff --git a/data/web/lang/lang.en.json b/data/web/lang/lang.en.json index d99c6be4..7aded417 100644 --- a/data/web/lang/lang.en.json +++ b/data/web/lang/lang.en.json @@ -236,7 +236,9 @@ "title": "Title", "pushover_title": "Notification title", "text": "Text", - "pushover_text": "Notification text ({SUBJECT} will be replaced by mail subject)", + "pushover_text": "Notification text", + "pushover_vars": "Useable variables for text and title (please take note of data protection)", + "pushover_sender_array": "Only consider the following sender email addresses (comma-separated)", "no_last_login": "No last UI login information", "last_mail_login": "Last mail login", "save": "Save changes", @@ -354,7 +356,9 @@ "title": "Title", "pushover_title": "Notification title", "text": "Text", - "pushover_text": "Notification text ({SUBJECT} will be replaced by mail subject)", + "pushover_text": "Notification text", + "pushover_vars": "Useable variables for text and title (please take note of data protection)", + "pushover_sender_array": "Only consider the following sender email addresses (comma-separated)", "spamfilter": "Spam filter", "domain": "Domain", "domain_s": "Domain/s", @@ -720,8 +724,10 @@ "sieve_preset_7": "Redirect and keep/drop" }, "edit": { - "generate": "generate", + "evaluate_x_prio": "Escalate high priority mail [X-Priority: 1]", + "only_x_prio": "Only consider high priority mail [X-Priority: 1]", "app_name": "App name", + "generate": "generate", "app_passwd": "App password", "sogo_visible": "Alias is visible in SOGo", "sogo_visible_info": "This option only affects objects, that can be displayed in SOGo (shared or non-shared alias addresses pointing to at least one local mailbox). If hidden, an alias will not appear as selectable sender in SOGo.", diff --git a/data/web/lang/lang.ru.json b/data/web/lang/lang.ru.json index e33c1392..d1f2263f 100644 --- a/data/web/lang/lang.ru.json +++ b/data/web/lang/lang.ru.json @@ -207,7 +207,7 @@ "priority": "Приоритет", "private_key": "Закрытый ключ", "pushover_info": "Настройки Push-уведомления будут применяться ко всей не-спам почте доставляемой на %s включая псевдонимы (общие, не общие и с метками).", - "pushover_text": "Текст уведомления ({SUBJECT} будет заменён на тему письма)", + "pushover_text": "Текст уведомления", "pushover_title": "Заголовок уведомления", "pushover_verify": "Проверить доступ", "quarantine": "Карантин", @@ -902,7 +902,7 @@ "password_now": "Текущий пароль (подтверждение изменения)", "password_repeat": "Подтверждение пароля (повтор)", "pushover_info": "Настройки Push-уведомления будут применяться ко всей не-спам почте доставляемой на %s включая псевдонимы (общие, не общие и с метками).", - "pushover_text": "Текст уведомления ({SUBJECT} будет заменён на тему письма)", + "pushover_text": "Текст уведомления", "pushover_title": "Заголовок уведомления", "pushover_verify": "Проверить доступ", "quarantine_notification": "Уведомления о спаме", diff --git a/data/web/lang/lang.sv.json b/data/web/lang/lang.sv.json index 85702aad..67e0f856 100644 --- a/data/web/lang/lang.sv.json +++ b/data/web/lang/lang.sv.json @@ -236,7 +236,7 @@ "title": "Titel", "pushover_title": "Meddelande titel", "text": "Text", - "pushover_text": "Meddelandetext ({SUBJECT} byts ut mot ämnesraden)", + "pushover_text": "Meddelandetext", "last_mail_login": "Senaste inloggningen", "no_last_login": "Senaste inloggningen till UI saknas", "save": "Spara ändringarna", @@ -354,7 +354,7 @@ "title": "Titel", "pushover_title": "Meddelandets titel", "text": "Text", - "pushover_text": "Meddelandetext ({SUBJECT} byts ut mot ämnesraden)", + "pushover_text": "Meddelandetext", "spamfilter": "Spamfilter", "domain_s": "Domäner", "rspamd-com_settings": "Ett inställningsnamn kommer att genereras automatiskt, se exemplet nedan. För mer detaljer se Rspamd dokumentationen", diff --git a/data/web/user.php b/data/web/user.php index f691b8bf..4aee8338 100644 --- a/data/web/user.php +++ b/data/web/user.php @@ -476,7 +476,10 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
+ + +

@@ -508,6 +511,22 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
+
+
+ + +
+
+
+
+ +
+
+
+
+ +
+