git subrepo commit mailcow/src/mailcow-dockerized
subrepo: subdir: "mailcow/src/mailcow-dockerized"
merged: "308860af"
upstream: origin: "https://github.com/mailcow/mailcow-dockerized.git"
branch: "master"
commit: "3f1a5af8"
git-subrepo: version: "0.4.5"
origin: "???"
commit: "???"
Change-Id: I5d51c14b45db54fe706be40a591ddbfcea50d4b0
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/functions.mailbox.inc.php b/mailcow/src/mailcow-dockerized/data/web/inc/functions.mailbox.inc.php
index 21b6b13..d67fa3e 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/functions.mailbox.inc.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/functions.mailbox.inc.php
@@ -336,9 +336,37 @@
$mins_interval = $_data['mins_interval'];
$enc1 = $_data['enc1'];
$custom_params = (empty(trim($_data['custom_params']))) ? '' : trim($_data['custom_params']);
- // Workaround, fixme
- if (strpos($custom_params, 'pipemess')) {
- $custom_params = '';
+
+ // validate custom params
+ foreach (explode('-', $custom_params) as $param){
+ if(empty($param)) continue;
+
+ // extract option
+ if (str_contains($param, '=')) $param = explode('=', $param)[0];
+ else $param = rtrim($param, ' ');
+ // remove first char if first char is -
+ if ($param[0] == '-') $param = ltrim($param, $param[0]);
+
+ if (str_contains($param, ' ')) {
+ // bad char
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'bad character SPACE'
+ );
+ return false;
+ }
+
+ // check if param is whitelisted
+ if (!in_array(strtolower($param), $GLOBALS["IMAPSYNC_OPTIONS"]["whitelist"])){
+ // bad option
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'bad option '. $param
+ );
+ return false;
+ }
}
if (empty($subfolder2)) {
$subfolder2 = "";
@@ -443,16 +471,15 @@
if ($_SESSION['mailcow_cc_role'] != "admin") {
$_SESSION['return'][] = array(
'type' => 'danger',
- 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_extra),
'msg' => 'access_denied'
);
return false;
}
$domain = idn_to_ascii(strtolower(trim($_data['domain'])), 0, INTL_IDNA_VARIANT_UTS46);
$description = $_data['description'];
- if (empty($description)) {
- $description = $domain;
- }
+ if (empty($description)) $description = $domain;
+ $tags = (array)$_data['tags'];
$aliases = (int)$_data['aliases'];
$mailboxes = (int)$_data['mailboxes'];
$defquota = (int)$_data['defquota'];
@@ -545,10 +572,12 @@
);
return false;
}
+
$stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `external` = 1 AND `send_as` LIKE :domain");
$stmt->execute(array(
':domain' => '%@' . $domain
));
+ // save domain
$stmt = $pdo->prepare("INSERT INTO `domain` (`domain`, `description`, `aliases`, `mailboxes`, `defquota`, `maxquota`, `quota`, `backupmx`, `gal`, `active`, `relay_unknown_only`, `relay_all_recipients`)
VALUES (:domain, :description, :aliases, :mailboxes, :defquota, :maxquota, :quota, :backupmx, :gal, :active, :relay_unknown_only, :relay_all_recipients)");
$stmt->execute(array(
@@ -565,6 +594,24 @@
':relay_unknown_only' => $relay_unknown_only,
':relay_all_recipients' => $relay_all_recipients
));
+ // save tags
+ foreach($tags as $index => $tag){
+ if (empty($tag)) continue;
+ if ($index > $GLOBALS['TAGGING_LIMIT']) {
+ $_SESSION['return'][] = array(
+ 'type' => 'warning',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('tag_limit_exceeded', 'limit '.$GLOBALS['TAGGING_LIMIT'])
+ );
+ break;
+ }
+ $stmt = $pdo->prepare("INSERT INTO `tags_domain` (`domain`, `tag_name`) VALUES (:domain, :tag_name)");
+ $stmt->execute(array(
+ ':domain' => $domain,
+ ':tag_name' => $tag,
+ ));
+ }
+
try {
$redis->hSet('DOMAIN_MAP', $domain, 1);
}
@@ -580,7 +627,16 @@
ratelimit('edit', 'domain', array('rl_value' => $_data['rl_value'], 'rl_frame' => $_data['rl_frame'], 'object' => $domain));
}
if (!empty($_data['key_size']) && !empty($_data['dkim_selector'])) {
- dkim('add', array('key_size' => $_data['key_size'], 'dkim_selector' => $_data['dkim_selector'], 'domains' => $domain));
+ if (!empty($redis->hGet('DKIM_SELECTORS', $domain))) {
+ $_SESSION['return'][] = array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'domain_add_dkim_available'
+ );
+ }
+ else {
+ dkim('add', array('key_size' => $_data['key_size'], 'dkim_selector' => $_data['dkim_selector'], 'domains' => $domain));
+ }
}
if (!empty($restart_sogo)) {
$restart_response = json_decode(docker('post', 'sogo-mailcow', 'restart'), true);
@@ -910,7 +966,16 @@
ratelimit('edit', 'domain', array('rl_value' => $_data['rl_value'], 'rl_frame' => $_data['rl_frame'], 'object' => $alias_domain));
}
if (!empty($_data['key_size']) && !empty($_data['dkim_selector'])) {
- dkim('add', array('key_size' => $_data['key_size'], 'dkim_selector' => $_data['dkim_selector'], 'domains' => $alias_domain));
+ if (!empty($redis->hGet('DKIM_SELECTORS', $alias_domain))) {
+ $_SESSION['return'][] = array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'domain_add_dkim_available'
+ );
+ }
+ else {
+ dkim('add', array('key_size' => $_data['key_size'], 'dkim_selector' => $_data['dkim_selector'], 'domains' => $alias_domain));
+ }
}
$_SESSION['return'][] = array(
'type' => 'success',
@@ -942,6 +1007,7 @@
$password = $_data['password'];
$password2 = $_data['password2'];
$name = ltrim(rtrim($_data['name'], '>'), '<');
+ $tags = $_data['tags'];
$quota_m = intval($_data['quota']);
if ((!isset($_SESSION['acl']['unlimited_quota']) || $_SESSION['acl']['unlimited_quota'] != "1") && $quota_m === 0) {
$_SESSION['return'][] = array(
@@ -954,6 +1020,13 @@
if (empty($name)) {
$name = $local_part;
}
+ if (isset($_data['protocol_access'])) {
+ $_data['protocol_access'] = (array)$_data['protocol_access'];
+ $_data['imap_access'] = (in_array('imap', $_data['protocol_access'])) ? 1 : 0;
+ $_data['pop3_access'] = (in_array('pop3', $_data['protocol_access'])) ? 1 : 0;
+ $_data['smtp_access'] = (in_array('smtp', $_data['protocol_access'])) ? 1 : 0;
+ $_data['sieve_access'] = (in_array('sieve', $_data['protocol_access'])) ? 1 : 0;
+ }
$active = intval($_data['active']);
$force_pw_update = (isset($_data['force_pw_update'])) ? intval($_data['force_pw_update']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['force_pw_update']);
$tls_enforce_in = (isset($_data['tls_enforce_in'])) ? intval($_data['tls_enforce_in']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['tls_enforce_in']);
@@ -1103,6 +1176,23 @@
$stmt->execute(array(
':username' => $username
));
+ // save tags
+ foreach($tags as $index => $tag){
+ if (empty($tag)) continue;
+ if ($index > $GLOBALS['TAGGING_LIMIT']) {
+ $_SESSION['return'][] = array(
+ 'type' => 'warning',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('tag_limit_exceeded', 'limit '.$GLOBALS['TAGGING_LIMIT'])
+ );
+ break;
+ }
+ $stmt = $pdo->prepare("INSERT INTO `tags_mailbox` (`username`, `tag_name`) VALUES (:username, :tag_name)");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':tag_name' => $tag,
+ ));
+ }
$stmt = $pdo->prepare("INSERT INTO `quota2` (`username`, `bytes`, `messages`)
VALUES (:username, '0', '0') ON DUPLICATE KEY UPDATE `bytes` = '0', `messages` = '0';");
$stmt->execute(array(':username' => $username));
@@ -1117,10 +1207,63 @@
':domain' => $domain,
':active' => $active
));
- $stmt = $pdo->prepare("INSERT INTO `user_acl` (`username`) VALUES (:username)");
- $stmt->execute(array(
- ':username' => $username
- ));
+
+
+ if (isset($_data['acl'])) {
+ $_data['acl'] = (array)$_data['acl'];
+ $_data['spam_alias'] = (in_array('spam_alias', $_data['acl'])) ? 1 : 0;
+ $_data['tls_policy'] = (in_array('tls_policy', $_data['acl'])) ? 1 : 0;
+ $_data['spam_score'] = (in_array('spam_score', $_data['acl'])) ? 1 : 0;
+ $_data['spam_policy'] = (in_array('spam_policy', $_data['acl'])) ? 1 : 0;
+ $_data['delimiter_action'] = (in_array('delimiter_action', $_data['acl'])) ? 1 : 0;
+ $_data['syncjobs'] = (in_array('syncjobs', $_data['acl'])) ? 1 : 0;
+ $_data['eas_reset'] = (in_array('eas_reset', $_data['acl'])) ? 1 : 0;
+ $_data['sogo_profile_reset'] = (in_array('sogo_profile_reset', $_data['acl'])) ? 1 : 0;
+ $_data['pushover'] = (in_array('pushover', $_data['acl'])) ? 1 : 0;
+ $_data['quarantine'] = (in_array('quarantine', $_data['acl'])) ? 1 : 0;
+ $_data['quarantine_attachments'] = (in_array('quarantine_attachments', $_data['acl'])) ? 1 : 0;
+ $_data['quarantine_notification'] = (in_array('quarantine_notification', $_data['acl'])) ? 1 : 0;
+ $_data['quarantine_category'] = (in_array('quarantine_category', $_data['acl'])) ? 1 : 0;
+ $_data['app_passwds'] = (in_array('app_passwds', $_data['acl'])) ? 1 : 0;
+
+ $stmt = $pdo->prepare("INSERT INTO `user_acl`
+ (`username`, `spam_alias`, `tls_policy`, `spam_score`, `spam_policy`, `delimiter_action`, `syncjobs`, `eas_reset`, `sogo_profile_reset`,
+ `pushover`, `quarantine`, `quarantine_attachments`, `quarantine_notification`, `quarantine_category`, `app_passwds`)
+ VALUES (:username, :spam_alias, :tls_policy, :spam_score, :spam_policy, :delimiter_action, :syncjobs, :eas_reset, :sogo_profile_reset,
+ :pushover, :quarantine, :quarantine_attachments, :quarantine_notification, :quarantine_category, :app_passwds) ");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':spam_alias' => $_data['spam_alias'],
+ ':tls_policy' => $_data['tls_policy'],
+ ':spam_score' => $_data['spam_score'],
+ ':spam_policy' => $_data['spam_policy'],
+ ':delimiter_action' => $_data['delimiter_action'],
+ ':syncjobs' => $_data['syncjobs'],
+ ':eas_reset' => $_data['eas_reset'],
+ ':sogo_profile_reset' => $_data['sogo_profile_reset'],
+ ':pushover' => $_data['pushover'],
+ ':quarantine' => $_data['quarantine'],
+ ':quarantine_attachments' => $_data['quarantine_attachments'],
+ ':quarantine_notification' => $_data['quarantine_notification'],
+ ':quarantine_category' => $_data['quarantine_category'],
+ ':app_passwds' => $_data['app_passwds']
+ ));
+ }
+ else {
+ $stmt = $pdo->prepare("INSERT INTO `user_acl` (`username`) VALUES (:username)");
+ $stmt->execute(array(
+ ':username' => $username
+ ));
+ }
+
+ if (isset($_data['rl_frame']) && isset($_data['rl_value'])){
+ ratelimit('edit', 'mailbox', array(
+ 'object' => $username,
+ 'rl_frame' => $_data['rl_frame'],
+ 'rl_value' => $_data['rl_value']
+ ));
+ }
+
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
@@ -1239,6 +1382,190 @@
'msg' => array('resource_added', htmlspecialchars($name))
);
break;
+ case 'domain_templates':
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_extra),
+ 'msg' => 'access_denied'
+ );
+ return false;
+ }
+ if (empty($_data["template"])){
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_extra),
+ 'msg' => 'template_name_invalid'
+ );
+ return false;
+ }
+
+ // check if template name exists, return false
+ $stmt = $pdo->prepare("SELECT id FROM `templates` WHERE `type` = :type AND `template` = :template");
+ $stmt->execute(array(
+ ":type" => "domain",
+ ":template" => $_data["template"]
+ ));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ if (!empty($row)){
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_extra),
+ 'msg' => array('template_exists', $_data["template"])
+ );
+ return false;
+ }
+
+ // check attributes
+ $attr = array();
+ $attr['tags'] = (isset($_data['tags'])) ? $_data['tags'] : array();
+ $attr['max_num_aliases_for_domain'] = (!empty($_data['max_num_aliases_for_domain'])) ? intval($_data['max_num_aliases_for_domain']) : 400;
+ $attr['max_num_mboxes_for_domain'] = (!empty($_data['max_num_mboxes_for_domain'])) ? intval($_data['max_num_mboxes_for_domain']) : 10;
+ $attr['def_quota_for_mbox'] = (!empty($_data['def_quota_for_mbox'])) ? intval($_data['def_quota_for_mbox']) * 1048576 : 3072 * 1048576;
+ $attr['max_quota_for_mbox'] = (!empty($_data['max_quota_for_mbox'])) ? intval($_data['max_quota_for_mbox']) * 1048576 : 10240 * 1048576;
+ $attr['max_quota_for_domain'] = (!empty($_data['max_quota_for_domain'])) ? intval($_data['max_quota_for_domain']) * 1048576 : 10240 * 1048576;
+ $attr['rl_frame'] = (!empty($_data['rl_frame'])) ? $_data['rl_frame'] : "s";
+ $attr['rl_value'] = (!empty($_data['rl_value'])) ? $_data['rl_value'] : "";
+ $attr['active'] = isset($_data['active']) ? intval($_data['active']) : 1;
+ $attr['gal'] = (isset($_data['gal'])) ? intval($_data['gal']) : 1;
+ $attr['backupmx'] = (isset($_data['backupmx'])) ? intval($_data['backupmx']) : 0;
+ $attr['relay_all_recipients'] = (isset($_data['relay_all_recipients'])) ? intval($_data['relay_all_recipients']) : 0;
+ $attr['relay_unknown_only'] = (isset($_data['relay_unknown_only'])) ? intval($_data['relay_unknown_only']) : 0;
+ $attr['dkim_selector'] = (isset($_data['dkim_selector'])) ? $_data['dkim_selector'] : "dkim";
+ $attr['key_size'] = isset($_data['key_size']) ? intval($_data['key_size']) : 2048;
+
+ // save template
+ $stmt = $pdo->prepare("INSERT INTO `templates` (`type`, `template`, `attributes`)
+ VALUES (:type, :template, :attributes)");
+ $stmt->execute(array(
+ ":type" => "domain",
+ ":template" => $_data["template"],
+ ":attributes" => json_encode($attr)
+ ));
+
+ // success
+ $_SESSION['return'][] = array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('template_added', $_data["template"])
+ );
+ return true;
+ break;
+ case 'mailbox_templates':
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_extra),
+ 'msg' => 'access_denied'
+ );
+ return false;
+ }
+ if (empty($_data["template"])){
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_extra),
+ 'msg' => 'template_name_invalid'
+ );
+ return false;
+ }
+
+ // check if template name exists, return false
+ $stmt = $pdo->prepare("SELECT id FROM `templates` WHERE `type` = :type AND `template` = :template");
+ $stmt->execute(array(
+ ":type" => "mailbox",
+ ":template" => $_data["template"]
+ ));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ if (!empty($row)){
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_extra),
+ 'msg' => array('template_exists', $_data["template"])
+ );
+ return false;
+ }
+
+
+ // check attributes
+ $attr = array();
+ $attr["quota"] = isset($_data['quota']) ? intval($_data['quota']) * 1048576 : 0;
+ $attr['tags'] = (isset($_data['tags'])) ? $_data['tags'] : array();
+ $attr["quarantine_notification"] = (!empty($_data['quarantine_notification'])) ? $_data['quarantine_notification'] : strval($MAILBOX_DEFAULT_ATTRIBUTES['quarantine_notification']);
+ $attr["quarantine_category"] = (!empty($_data['quarantine_category'])) ? $_data['quarantine_category'] : strval($MAILBOX_DEFAULT_ATTRIBUTES['quarantine_category']);
+ $attr["rl_frame"] = (!empty($_data['rl_frame'])) ? $_data['rl_frame'] : "s";
+ $attr["rl_value"] = (!empty($_data['rl_value'])) ? $_data['rl_value'] : "";
+ $attr["force_pw_update"] = isset($_data['force_pw_update']) ? intval($_data['force_pw_update']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['force_pw_update']);
+ $attr["sogo_access"] = isset($_data['sogo_access']) ? intval($_data['sogo_access']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['sogo_access']);
+ $attr["active"] = isset($_data['active']) ? intval($_data['active']) : 1;
+ $attr["tls_enforce_in"] = isset($_data['tls_enforce_in']) ? intval($_data['tls_enforce_in']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['tls_enforce_in']);
+ $attr["tls_enforce_out"] = isset($_data['tls_enforce_out']) ? intval($_data['tls_enforce_out']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['tls_enforce_out']);
+ if (isset($_data['protocol_access'])) {
+ $_data['protocol_access'] = (array)$_data['protocol_access'];
+ $attr['imap_access'] = (in_array('imap', $_data['protocol_access'])) ? 1 : intval($MAILBOX_DEFAULT_ATTRIBUTES['imap_access']);
+ $attr['pop3_access'] = (in_array('pop3', $_data['protocol_access'])) ? 1 : intval($MAILBOX_DEFAULT_ATTRIBUTES['pop3_access']);
+ $attr['smtp_access'] = (in_array('smtp', $_data['protocol_access'])) ? 1 : intval($MAILBOX_DEFAULT_ATTRIBUTES['smtp_access']);
+ $attr['sieve_access'] = (in_array('sieve', $_data['protocol_access'])) ? 1 : intval($MAILBOX_DEFAULT_ATTRIBUTES['sieve_access']);
+ }
+ else {
+ $attr['imap_access'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['imap_access']);
+ $attr['pop3_access'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['pop3_access']);
+ $attr['smtp_access'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['smtp_access']);
+ $attr['sieve_access'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['sieve_access']);
+ }
+ if (isset($_data['acl'])) {
+ $_data['acl'] = (array)$_data['acl'];
+ $attr['acl_spam_alias'] = (in_array('spam_alias', $_data['acl'])) ? 1 : 0;
+ $attr['acl_tls_policy'] = (in_array('tls_policy', $_data['acl'])) ? 1 : 0;
+ $attr['acl_spam_score'] = (in_array('spam_score', $_data['acl'])) ? 1 : 0;
+ $attr['acl_spam_policy'] = (in_array('spam_policy', $_data['acl'])) ? 1 : 0;
+ $attr['acl_delimiter_action'] = (in_array('delimiter_action', $_data['acl'])) ? 1 : 0;
+ $attr['acl_syncjobs'] = (in_array('syncjobs', $_data['acl'])) ? 1 : 0;
+ $attr['acl_eas_reset'] = (in_array('eas_reset', $_data['acl'])) ? 1 : 0;
+ $attr['acl_sogo_profile_reset'] = (in_array('sogo_profile_reset', $_data['acl'])) ? 1 : 0;
+ $attr['acl_pushover'] = (in_array('pushover', $_data['acl'])) ? 1 : 0;
+ $attr['acl_quarantine'] = (in_array('quarantine', $_data['acl'])) ? 1 : 0;
+ $attr['acl_quarantine_attachments'] = (in_array('quarantine_attachments', $_data['acl'])) ? 1 : 0;
+ $attr['acl_quarantine_notification'] = (in_array('quarantine_notification', $_data['acl'])) ? 1 : 0;
+ $attr['acl_quarantine_category'] = (in_array('quarantine_category', $_data['acl'])) ? 1 : 0;
+ $attr['acl_app_passwds'] = (in_array('app_passwds', $_data['acl'])) ? 1 : 0;
+ } else {
+ $_data['acl'] = (array)$_data['acl'];
+ $attr['acl_spam_alias'] = 1;
+ $attr['acl_tls_policy'] = 1;
+ $attr['acl_spam_score'] = 1;
+ $attr['acl_spam_policy'] = 1;
+ $attr['acl_delimiter_action'] = 1;
+ $attr['acl_syncjobs'] = 0;
+ $attr['acl_eas_reset'] = 1;
+ $attr['acl_sogo_profile_reset'] = 0;
+ $attr['acl_pushover'] = 1;
+ $attr['acl_quarantine'] = 1;
+ $attr['acl_quarantine_attachments'] = 1;
+ $attr['acl_quarantine_notification'] = 1;
+ $attr['acl_quarantine_category'] = 1;
+ $attr['acl_app_passwds'] = 1;
+ }
+
+
+
+ // save template
+ $stmt = $pdo->prepare("INSERT INTO `templates` (`type`, `template`, `attributes`)
+ VALUES (:type, :template, :attributes)");
+ $stmt->execute(array(
+ ":type" => "mailbox",
+ ":template" => $_data["template"],
+ ":attributes" => json_encode($attr)
+ ));
+
+ // success
+ $_SESSION['return'][] = array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('template_added', $_data["template"])
+ );
+ return true;
+ break;
}
break;
case 'edit':
@@ -1709,8 +2036,37 @@
);
continue;
}
- if (strpos($custom_params, 'pipemess')) {
- $custom_params = '';
+
+ // validate custom params
+ foreach (explode('-', $custom_params) as $param){
+ if(empty($param)) continue;
+
+ // extract option
+ if (str_contains($param, '=')) $param = explode('=', $param)[0];
+ else $param = rtrim($param, ' ');
+ // remove first char if first char is -
+ if ($param[0] == '-') $param = ltrim($param, $param[0]);
+
+ if (str_contains($param, ' ')) {
+ // bad char
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'bad character SPACE'
+ );
+ return false;
+ }
+
+ // check if param is whitelisted
+ if (!in_array(strtolower($param), $GLOBALS["IMAPSYNC_OPTIONS"]["whitelist"])){
+ // bad option
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'bad option '. $param
+ );
+ return false;
+ }
}
if (empty($subfolder2)) {
$subfolder2 = "";
@@ -2146,6 +2502,7 @@
$gal = (isset($_data['gal'])) ? intval($_data['gal']) : $is_now['gal'];
$description = (!empty($_data['description']) && isset($_SESSION['acl']['domain_desc']) && $_SESSION['acl']['domain_desc'] == "1") ? $_data['description'] : $is_now['description'];
(int)$relayhost = (isset($_data['relayhost']) && isset($_SESSION['acl']['domain_relayhost']) && $_SESSION['acl']['domain_relayhost'] == "1") ? intval($_data['relayhost']) : intval($is_now['relayhost']);
+ $tags = (is_array($_data['tags']) ? $_data['tags'] : array());
}
else {
$_SESSION['return'][] = array(
@@ -2155,6 +2512,7 @@
);
continue;
}
+
$stmt = $pdo->prepare("UPDATE `domain` SET
`description` = :description,
`gal` = :gal
@@ -2164,6 +2522,24 @@
':gal' => $gal,
':domain' => $domain
));
+ // save tags
+ foreach($tags as $index => $tag){
+ if (empty($tag)) continue;
+ if ($index > $GLOBALS['TAGGING_LIMIT']) {
+ $_SESSION['return'][] = array(
+ 'type' => 'warning',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('tag_limit_exceeded', 'limit '.$GLOBALS['TAGGING_LIMIT'])
+ );
+ break;
+ }
+ $stmt = $pdo->prepare("INSERT INTO `tags_domain` (`domain`, `tag_name`) VALUES (:domain, :tag_name)");
+ $stmt->execute(array(
+ ':domain' => $domain,
+ ':tag_name' => $tag,
+ ));
+ }
+
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
@@ -2185,6 +2561,7 @@
$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'];
+ $tags = (is_array($_data['tags']) ? $_data['tags'] : array());
if ($relay_all_recipients == '1') {
$backupmx = '1';
}
@@ -2283,6 +2660,7 @@
);
continue;
}
+
$stmt = $pdo->prepare("UPDATE `domain` SET
`relay_all_recipients` = :relay_all_recipients,
`relay_unknown_only` = :relay_unknown_only,
@@ -2312,6 +2690,24 @@
':description' => $description,
':domain' => $domain
));
+ // save tags
+ foreach($tags as $index => $tag){
+ if (empty($tag)) continue;
+ if ($index > $GLOBALS['TAGGING_LIMIT']) {
+ $_SESSION['return'][] = array(
+ 'type' => 'warning',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('tag_limit_exceeded', 'limit '.$GLOBALS['TAGGING_LIMIT'])
+ );
+ break;
+ }
+ $stmt = $pdo->prepare("INSERT INTO `tags_domain` (`domain`, `tag_name`) VALUES (:domain, :tag_name)");
+ $stmt->execute(array(
+ ':domain' => $domain,
+ ':tag_name' => $tag,
+ ));
+ }
+
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
@@ -2320,6 +2716,79 @@
}
}
break;
+ case 'domain_templates':
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_extra),
+ 'msg' => 'access_denied'
+ );
+ return false;
+ }
+ if (!is_array($_data['ids'])) {
+ $ids = array();
+ $ids[] = $_data['ids'];
+ }
+ else {
+ $ids = $_data['ids'];
+ }
+ foreach ($ids as $id) {
+ $is_now = mailbox("get", "domain_templates", $id);
+ if (empty($is_now) ||
+ $is_now["type"] != "domain"){
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_extra),
+ 'msg' => 'template_id_invalid'
+ );
+ continue;
+ }
+
+ // check name
+ if ($is_now["template"] == "Default" && $is_now["template"] != $_data["template"]){
+ // keep template name of Default template
+ $_data["template"] = $is_now["template"];
+ }
+ else {
+ $_data["template"] = (isset($_data["template"])) ? $_data["template"] : $is_now["template"];
+ }
+ // check attributes
+ $attr = array();
+ $attr['tags'] = (isset($_data['tags'])) ? $_data['tags'] : array();
+ $attr['max_num_aliases_for_domain'] = (isset($_data['max_num_aliases_for_domain'])) ? intval($_data['max_num_aliases_for_domain']) : 0;
+ $attr['max_num_mboxes_for_domain'] = (isset($_data['max_num_mboxes_for_domain'])) ? intval($_data['max_num_mboxes_for_domain']) : 0;
+ $attr['def_quota_for_mbox'] = (isset($_data['def_quota_for_mbox'])) ? intval($_data['def_quota_for_mbox']) * 1048576 : 0;
+ $attr['max_quota_for_mbox'] = (isset($_data['max_quota_for_mbox'])) ? intval($_data['max_quota_for_mbox']) * 1048576 : 0;
+ $attr['max_quota_for_domain'] = (isset($_data['max_quota_for_domain'])) ? intval($_data['max_quota_for_domain']) * 1048576 : 0;
+ $attr['rl_frame'] = (!empty($_data['rl_frame'])) ? $_data['rl_frame'] : "s";
+ $attr['rl_value'] = (!empty($_data['rl_value'])) ? $_data['rl_value'] : "";
+ $attr['active'] = isset($_data['active']) ? intval($_data['active']) : 1;
+ $attr['gal'] = (isset($_data['gal'])) ? intval($_data['gal']) : 1;
+ $attr['backupmx'] = (isset($_data['backupmx'])) ? intval($_data['backupmx']) : 0;
+ $attr['relay_all_recipients'] = (isset($_data['relay_all_recipients'])) ? intval($_data['relay_all_recipients']) : 0;
+ $attr['relay_unknown_only'] = (isset($_data['relay_unknown_only'])) ? intval($_data['relay_unknown_only']) : 0;
+ $attr['dkim_selector'] = (isset($_data['dkim_selector'])) ? $_data['dkim_selector'] : "dkim";
+ $attr['key_size'] = isset($_data['key_size']) ? intval($_data['key_size']) : 2048;
+
+ // update template
+ $stmt = $pdo->prepare("UPDATE `templates`
+ SET `template` = :template, `attributes` = :attributes
+ WHERE id = :id");
+ $stmt->execute(array(
+ ":id" => $id ,
+ ":template" => $_data["template"] ,
+ ":attributes" => json_encode($attr)
+ ));
+ }
+
+
+ $_SESSION['return'][] = array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('template_modified', $_data["template"])
+ );
+ return true;
+ break;
case 'mailbox':
if (!is_array($_data['username'])) {
$usernames = array();
@@ -2360,6 +2829,7 @@
$quota_b = $quota_m * 1048576;
$password = (!empty($_data['password'])) ? $_data['password'] : null;
$password2 = (!empty($_data['password2'])) ? $_data['password2'] : null;
+ $tags = (is_array($_data['tags']) ? $_data['tags'] : array());
}
else {
$_SESSION['return'][] = array(
@@ -2636,6 +3106,24 @@
':relayhost' => $relayhost,
':username' => $username
));
+ // save tags
+ foreach($tags as $index => $tag){
+ if (empty($tag)) continue;
+ if ($index > $GLOBALS['TAGGING_LIMIT']) {
+ $_SESSION['return'][] = array(
+ 'type' => 'warning',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('tag_limit_exceeded', 'limit '.$GLOBALS['TAGGING_LIMIT'])
+ );
+ break;
+ }
+ $stmt = $pdo->prepare("INSERT INTO `tags_mailbox` (`username`, `tag_name`) VALUES (:username, :tag_name)");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':tag_name' => $tag,
+ ));
+ }
+
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
@@ -2643,6 +3131,110 @@
);
}
break;
+ case 'mailbox_templates':
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_extra),
+ 'msg' => 'access_denied'
+ );
+ return false;
+ }
+ if (!is_array($_data['ids'])) {
+ $ids = array();
+ $ids[] = $_data['ids'];
+ }
+ else {
+ $ids = $_data['ids'];
+ }
+ foreach ($ids as $id) {
+ $is_now = mailbox("get", "mailbox_templates", $id);
+ if (empty($is_now) ||
+ $is_now["type"] != "mailbox"){
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_extra),
+ 'msg' => 'template_id_invalid'
+ );
+ continue;
+ }
+
+
+ // check name
+ if ($is_now["template"] == "Default" && $is_now["template"] != $_data["template"]){
+ // keep template name of Default template
+ $_data["template"] = $is_now["template"];
+ }
+ else {
+ $_data["template"] = (isset($_data["template"])) ? $_data["template"] : $is_now["template"];
+ }
+ // check attributes
+ $attr = array();
+ $attr["quota"] = isset($_data['quota']) ? intval($_data['quota']) * 1048576 : 0;
+ $attr['tags'] = (isset($_data['tags'])) ? $_data['tags'] : $is_now['tags'];
+ $attr["quarantine_notification"] = (!empty($_data['quarantine_notification'])) ? $_data['quarantine_notification'] : $is_now['quarantine_notification'];
+ $attr["quarantine_category"] = (!empty($_data['quarantine_category'])) ? $_data['quarantine_category'] : $is_now['quarantine_category'];
+ $attr["rl_frame"] = (!empty($_data['rl_frame'])) ? $_data['rl_frame'] : $is_now['rl_frame'];
+ $attr["rl_value"] = (!empty($_data['rl_value'])) ? $_data['rl_value'] : $is_now['rl_value'];
+ $attr["force_pw_update"] = isset($_data['force_pw_update']) ? intval($_data['force_pw_update']) : $is_now['force_pw_update'];
+ $attr["sogo_access"] = isset($_data['sogo_access']) ? intval($_data['sogo_access']) : $is_now['sogo_access'];
+ $attr["active"] = isset($_data['active']) ? intval($_data['active']) : $is_now['active'];
+ $attr["tls_enforce_in"] = isset($_data['tls_enforce_in']) ? intval($_data['tls_enforce_in']) : $is_now['tls_enforce_in'];
+ $attr["tls_enforce_out"] = isset($_data['tls_enforce_out']) ? intval($_data['tls_enforce_out']) : $is_now['tls_enforce_out'];
+ if (isset($_data['protocol_access'])) {
+ $_data['protocol_access'] = (array)$_data['protocol_access'];
+ $attr['imap_access'] = (in_array('imap', $_data['protocol_access'])) ? 1 : 0;
+ $attr['pop3_access'] = (in_array('pop3', $_data['protocol_access'])) ? 1 : 0;
+ $attr['smtp_access'] = (in_array('smtp', $_data['protocol_access'])) ? 1 : 0;
+ $attr['sieve_access'] = (in_array('sieve', $_data['protocol_access'])) ? 1 : 0;
+ }
+ else {
+ foreach ($is_now as $key => $value){
+ $attr[$key] = $is_now[$key];
+ }
+ }
+ if (isset($_data['acl'])) {
+ $_data['acl'] = (array)$_data['acl'];
+ $attr['acl_spam_alias'] = (in_array('spam_alias', $_data['acl'])) ? 1 : 0;
+ $attr['acl_tls_policy'] = (in_array('tls_policy', $_data['acl'])) ? 1 : 0;
+ $attr['acl_spam_score'] = (in_array('spam_score', $_data['acl'])) ? 1 : 0;
+ $attr['acl_spam_policy'] = (in_array('spam_policy', $_data['acl'])) ? 1 : 0;
+ $attr['acl_delimiter_action'] = (in_array('delimiter_action', $_data['acl'])) ? 1 : 0;
+ $attr['acl_syncjobs'] = (in_array('syncjobs', $_data['acl'])) ? 1 : 0;
+ $attr['acl_eas_reset'] = (in_array('eas_reset', $_data['acl'])) ? 1 : 0;
+ $attr['acl_sogo_profile_reset'] = (in_array('sogo_profile_reset', $_data['acl'])) ? 1 : 0;
+ $attr['acl_pushover'] = (in_array('pushover', $_data['acl'])) ? 1 : 0;
+ $attr['acl_quarantine'] = (in_array('quarantine', $_data['acl'])) ? 1 : 0;
+ $attr['acl_quarantine_attachments'] = (in_array('quarantine_attachments', $_data['acl'])) ? 1 : 0;
+ $attr['acl_quarantine_notification'] = (in_array('quarantine_notification', $_data['acl'])) ? 1 : 0;
+ $attr['acl_quarantine_category'] = (in_array('quarantine_category', $_data['acl'])) ? 1 : 0;
+ $attr['acl_app_passwds'] = (in_array('app_passwds', $_data['acl'])) ? 1 : 0;
+ } else {
+ foreach ($is_now as $key => $value){
+ $attr[$key] = $is_now[$key];
+ }
+ }
+
+
+ // update template
+ $stmt = $pdo->prepare("UPDATE `templates`
+ SET `template` = :template, `attributes` = :attributes
+ WHERE id = :id");
+ $stmt->execute(array(
+ ":id" => $id ,
+ ":template" => $_data["template"] ,
+ ":attributes" => json_encode($attr)
+ ));
+ }
+
+
+ $_SESSION['return'][] = array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('template_modified', $_data["template"])
+ );
+ return true;
+ break;
case 'resource':
if (!is_array($_data['name'])) {
$names = array();
@@ -2851,10 +3443,34 @@
break;
case 'mailboxes':
$mailboxes = array();
- if (isset($_data) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
- return false;
+ if (isset($_extra) && is_array($_extra) && isset($_data)) {
+ // get by domain and tags
+ $tags = is_array($_extra) ? $_extra : array();
+
+ $sql = "";
+ foreach ($tags as $key => $tag) {
+ $sql = $sql."SELECT DISTINCT `username` FROM `tags_mailbox` WHERE `username` LIKE ? AND `tag_name` LIKE ?"; // distinct, avoid duplicates
+ if ($key === array_key_last($tags)) break;
+ $sql = $sql.' UNION DISTINCT '; // combine querys with union - distinct, avoid duplicates
+ }
+
+ // prepend domain to array
+ $params = array();
+ foreach ($tags as $key => $val){
+ array_push($params, '%'.$_data.'%');
+ array_push($params, '%'.$val.'%');
+ }
+ $stmt = $pdo->prepare($sql);
+ $stmt->execute($params);
+
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ if (hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], explode('@', $row['username'])[1]))
+ $mailboxes[] = $row['username'];
+ }
}
elseif (isset($_data) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ // get by domain
$stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE (`kind` = '' OR `kind` = NULL) AND `domain` = :domain");
$stmt->execute(array(
':domain' => $_data,
@@ -3348,20 +3964,46 @@
if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
return false;
}
- $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
- WHERE (`domain` IN (
- SELECT `domain` from `domain_admins`
- WHERE (`active`='1' AND `username` = :username))
- )
- OR 'admin'= :role");
- $stmt->execute(array(
- ':username' => $_SESSION['mailcow_cc_username'],
- ':role' => $_SESSION['mailcow_cc_role'],
- ));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while($row = array_shift($rows)) {
- $domains[] = $row['domain'];
+
+ if (isset($_extra) && is_array($_extra)){
+ // get by tags
+ $tags = is_array($_extra) ? $_extra : array();
+ // add % as prefix and suffix to every element for relative searching
+ $tags = array_map(function($x){ return '%'.$x.'%'; }, $tags);
+ $sql = "";
+ foreach ($tags as $key => $tag) {
+ $sql = $sql."SELECT DISTINCT `domain` FROM `tags_domain` WHERE `tag_name` LIKE ?"; // distinct, avoid duplicates
+ if ($key === array_key_last($tags)) break;
+ $sql = $sql.' UNION DISTINCT '; // combine querys with union - distinct, avoid duplicates
+ }
+ $stmt = $pdo->prepare($sql);
+ $stmt->execute($tags);
+
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ if ($_SESSION['mailcow_cc_role'] == "admin")
+ $domains[] = $row['domain'];
+ elseif (hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $row['domain']))
+ $domains[] = $row['domain'];
+ }
+ } else {
+ // get all
+ $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
+ WHERE (`domain` IN (
+ SELECT `domain` from `domain_admins`
+ WHERE (`active`='1' AND `username` = :username))
+ )
+ OR 'admin'= :role");
+ $stmt->execute(array(
+ ':username' => $_SESSION['mailcow_cc_username'],
+ ':role' => $_SESSION['mailcow_cc_role'],
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $domains[] = $row['domain'];
+ }
}
+
return $domains;
break;
case 'domain_details':
@@ -3385,6 +4027,8 @@
`mailboxes`,
`defquota`,
`maxquota`,
+ `created`,
+ `modified`,
`quota`,
`relayhost`,
`relay_all_recipients`,
@@ -3457,6 +4101,8 @@
$domaindata['relay_all_recipients_int'] = $row['relay_all_recipients'];
$domaindata['relay_unknown_only'] = $row['relay_unknown_only'];
$domaindata['relay_unknown_only_int'] = $row['relay_unknown_only'];
+ $domaindata['created'] = $row['created'];
+ $domaindata['modified'] = $row['modified'];
$stmt = $pdo->prepare("SELECT COUNT(`address`) AS `alias_count` FROM `alias`
WHERE (`domain`= :domain OR `domain` IN (SELECT `alias_domain` FROM `alias_domain` WHERE `target_domain` = :domain2))
AND `address` NOT IN (
@@ -3478,8 +4124,55 @@
$domain_admins = $stmt->fetch(PDO::FETCH_ASSOC);
(isset($domain_admins['domain_admins'])) ? $domaindata['domain_admins'] = $domain_admins['domain_admins'] : $domaindata['domain_admins'] = "-";
}
+ $stmt = $pdo->prepare("SELECT `tag_name`
+ FROM `tags_domain` WHERE `domain`= :domain");
+ $stmt->execute(array(
+ ':domain' => $_data
+ ));
+ $tags = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($tag = array_shift($tags)) {
+ $domaindata['tags'][] = $tag['tag_name'];
+ }
+
return $domaindata;
break;
+ case 'domain_templates':
+ if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
+ return false;
+ }
+ $_data = (isset($_data)) ? intval($_data) : null;
+
+ if (isset($_data)){
+ $stmt = $pdo->prepare("SELECT * FROM `templates`
+ WHERE `id` = :id AND type = :type");
+ $stmt->execute(array(
+ ":id" => $_data,
+ ":type" => "domain"
+ ));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ if (empty($row)){
+ return false;
+ }
+
+ $row["attributes"] = json_decode($row["attributes"], true);
+ return $row;
+ }
+ else {
+ $stmt = $pdo->prepare("SELECT * FROM `templates` WHERE `type` = 'domain'");
+ $stmt->execute();
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+
+ if (empty($rows)){
+ return false;
+ }
+
+ foreach($rows as $key => $row){
+ $rows[$key]["attributes"] = json_decode($row["attributes"], true);
+ }
+ return $rows;
+ }
+ break;
case 'mailbox_details':
if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
return false;
@@ -3494,6 +4187,8 @@
`mailbox`.`domain`,
`mailbox`.`local_part`,
`mailbox`.`quota`,
+ `mailbox`.`created`,
+ `mailbox`.`modified`,
`quota2`.`bytes`,
`attributes`,
`quota2`.`messages`
@@ -3512,6 +4207,8 @@
`mailbox`.`domain`,
`mailbox`.`local_part`,
`mailbox`.`quota`,
+ `mailbox`.`created`,
+ `mailbox`.`modified`,
`quota2replica`.`bytes`,
`attributes`,
`quota2replica`.`messages`
@@ -3538,6 +4235,8 @@
$mailboxdata['attributes'] = json_decode($row['attributes'], true);
$mailboxdata['quota_used'] = intval($row['bytes']);
$mailboxdata['percent_in_use'] = ($row['quota'] == 0) ? '- ' : round((intval($row['bytes']) / intval($row['quota'])) * 100);
+ $mailboxdata['created'] = $row['created'];
+ $mailboxdata['modified'] = $row['modified'];
if ($mailboxdata['percent_in_use'] === '- ') {
$mailboxdata['percent_class'] = "info";
@@ -3613,9 +4312,55 @@
}
$mailboxdata['is_relayed'] = $row['backupmx'];
}
+ $stmt = $pdo->prepare("SELECT `tag_name`
+ FROM `tags_mailbox` WHERE `username`= :username");
+ $stmt->execute(array(
+ ':username' => $_data
+ ));
+ $tags = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($tag = array_shift($tags)) {
+ $mailboxdata['tags'][] = $tag['tag_name'];
+ }
return $mailboxdata;
break;
+ case 'mailbox_templates':
+ if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
+ return false;
+ }
+ $_data = (isset($_data)) ? intval($_data) : null;
+
+ if (isset($_data)){
+ $stmt = $pdo->prepare("SELECT * FROM `templates`
+ WHERE `id` = :id AND type = :type");
+ $stmt->execute(array(
+ ":id" => $_data,
+ ":type" => "mailbox"
+ ));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ if (empty($row)){
+ return false;
+ }
+
+ $row["attributes"] = json_decode($row["attributes"], true);
+ return $row;
+ }
+ else {
+ $stmt = $pdo->prepare("SELECT * FROM `templates` WHERE `type` = 'mailbox'");
+ $stmt->execute();
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+
+ if (empty($rows)){
+ return false;
+ }
+
+ foreach($rows as $key => $row){
+ $rows[$key]["attributes"] = json_decode($row["attributes"], true);
+ }
+ return $rows;
+ }
+ break;
case 'resource_details':
$resourcedata = array();
if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
@@ -3984,6 +4729,42 @@
);
}
break;
+ case 'domain_templates':
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'access_denied'
+ );
+ return false;
+ }
+ if (!is_array($_data['ids'])) {
+ $ids = array();
+ $ids[] = $_data['ids'];
+ }
+ else {
+ $ids = $_data['ids'];
+ }
+
+
+ foreach ($ids as $id) {
+ // delete template
+ $stmt = $pdo->prepare("DELETE FROM `templates`
+ WHERE id = :id AND type = :type AND NOT template = :template");
+ $stmt->execute(array(
+ ":id" => $id,
+ ":type" => "domain",
+ ":template" => "Default"
+ ));
+
+ $_SESSION['return'][] = array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('template_removed', htmlspecialchars($id))
+ );
+ return true;
+ }
+ break;
case 'alias':
if (!is_array($_data['id'])) {
$ids = array();
@@ -4054,6 +4835,10 @@
$stmt->execute(array(
':alias_domain' => $alias_domain,
));
+ $stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `address` LIKE :domain");
+ $stmt->execute(array(
+ ':domain' => '%@'.$alias_domain,
+ ));
$stmt = $pdo->prepare("DELETE FROM `bcc_maps` WHERE `local_dest` = :alias_domain");
$stmt->execute(array(
':alias_domain' => $alias_domain,
@@ -4274,6 +5059,42 @@
);
}
break;
+ case 'mailbox_templates':
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'access_denied'
+ );
+ return false;
+ }
+ if (!is_array($_data['ids'])) {
+ $ids = array();
+ $ids[] = $_data['ids'];
+ }
+ else {
+ $ids = $_data['ids'];
+ }
+
+
+ foreach ($ids as $id) {
+ // delete template
+ $stmt = $pdo->prepare("DELETE FROM `templates`
+ WHERE id = :id AND type = :type AND NOT template = :template");
+ $stmt->execute(array(
+ ":id" => $id,
+ ":type" => "mailbox",
+ ":template" => "Default"
+ ));
+ }
+
+ $_SESSION['return'][] = array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'template_removed'
+ );
+ return true;
+ break;
case 'resource':
if (!is_array($_data['name'])) {
$names = array();
@@ -4338,6 +5159,108 @@
);
}
break;
+ case 'tags_domain':
+ if (!is_array($_data['domain'])) {
+ $domains = array();
+ $domains[] = $_data['domain'];
+ }
+ else {
+ $domains = $_data['domain'];
+ }
+ $tags = $_data['tags'];
+ if (!is_array($tags)) $tags = array();
+
+
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'access_denied'
+ );
+ return false;
+ }
+
+ $wasModified = false;
+ foreach ($domains as $domain) {
+ if (!is_valid_domain_name($domain)) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'domain_invalid'
+ );
+ continue;
+ }
+
+ foreach($tags as $tag){
+ // delete tag
+ $wasModified = true;
+ $stmt = $pdo->prepare("DELETE FROM `tags_domain` WHERE `domain` = :domain AND `tag_name` = :tag_name");
+ $stmt->execute(array(
+ ':domain' => $domain,
+ ':tag_name' => $tag,
+ ));
+ }
+ }
+
+ if (!$wasModified) return false;
+ $_SESSION['return'][] = array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('domain_modified', $domain)
+ );
+ break;
+ case 'tags_mailbox':
+ if (!is_array($_data['username'])) {
+ $usernames = array();
+ $usernames[] = $_data['username'];
+ }
+ else {
+ $usernames = $_data['username'];
+ }
+ $tags = $_data['tags'];
+ if (!is_array($tags)) $tags = array();
+
+ $wasModified = false;
+ foreach ($usernames as $username) {
+ if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'email invalid'
+ );
+ continue;
+ }
+
+ $is_now = mailbox('get', 'mailbox_details', $username);
+ $domain = $is_now['domain'];
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'access_denied'
+ );
+ continue;
+ }
+
+ // delete tags
+ foreach($tags as $tag){
+ $wasModified = true;
+
+ $stmt = $pdo->prepare("DELETE FROM `tags_mailbox` WHERE `username` = :username AND `tag_name` = :tag_name");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':tag_name' => $tag,
+ ));
+ }
+ }
+
+ if (!$wasModified) return false;
+ $_SESSION['return'][] = array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('mailbox_modified', $username)
+ );
+ break;
}
break;
}