public
nobgit
read
NobMail
Based on mailcow: dockerized
Languages
Repository composition by tracked source files.
PHP
49%
JavaScript
35%
HTML
9%
CSS
4%
Shell
2%
Python
1%
Lua
0%
Perl
0%
Ruby
0%
SCSS
0%
Create file
Wiki Documentation
Clone
https://nobgit.com/orgs/nobgit/nobmail.git
ssh://[email protected]:2222/orgs/nobgit/nobmail.git
Commit
[Web] Add delimiter_action to mailbox and mailbox_template add/edit admin forms (#6620)
1e42b8dd
data/web/edit.php | 1 +
data/web/inc/functions.mailbox.inc.php | 17 +++
data/web/inc/vars.inc.php | 148 +++++++++++++------------
data/web/js/site/mailbox.js | 18 +++
data/web/templates/edit/mailbox-templates.twig | 17 +++
data/web/templates/edit/mailbox.twig | 31 +++++-
data/web/templates/modals/mailbox.twig | 34 ++++++
7 files changed, 193 insertions(+), 73 deletions(-)
Diff
diff --git a/data/web/edit.php b/data/web/edit.php
index 9a1e5a5c..7ce4d0c6 100644
--- a/data/web/edit.php
+++ b/data/web/edit.php
@@ -125,6 +125,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
'mailbox' => $mailbox,
'rl' => $rl,
'pushover_data' => $pushover_data,
+ 'get_tagging_options' => mailbox('get', 'delimiter_action', $mailbox),
'quarantine_notification' => $quarantine_notification,
'quarantine_category' => $quarantine_category,
'get_tls_policy' => $get_tls_policy,
diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php
index d5daeddc..6ea4f571 100644
--- a/data/web/inc/functions.mailbox.inc.php
+++ b/data/web/inc/functions.mailbox.inc.php
@@ -1223,6 +1223,14 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$stmt->execute(array(
':username' => $username
));
+ // save delimiter_action
+ if (isset($_data['tagged_mail_handler'])) {
+ mailbox('edit', 'delimiter_action', array(
+ 'username' => $username,
+ 'tagged_mail_handler' => $_data['tagged_mail_handler']
+ ));
+ }
+
// save tags
foreach($tags as $index => $tag){
if (empty($tag)) continue;
@@ -1613,6 +1621,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$attr = array();
$attr["quota"] = isset($_data['quota']) ? intval($_data['quota']) * 1048576 : 0;
$attr['tags'] = (isset($_data['tags'])) ? $_data['tags'] : array();
+ $attr["tagged_mail_handler"] = (!empty($_data['tagged_mail_handler'])) ? $_data['tagged_mail_handler'] : strval($MAILBOX_DEFAULT_ATTRIBUTES['tagged_mail_handler']);
$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";
@@ -3259,6 +3268,13 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
);
return false;
}
+ // save delimiter_action
+ if (isset($_data['tagged_mail_handler'])) {
+ mailbox('edit', 'delimiter_action', array(
+ 'username' => $username,
+ 'tagged_mail_handler' => $_data['tagged_mail_handler']
+ ));
+ }
// save tags
foreach($tags as $index => $tag){
if (empty($tag)) continue;
@@ -3604,6 +3620,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$attr = array();
$attr["quota"] = isset($_data['quota']) ? intval($_data['quota']) * 1048576 : 0;
$attr['tags'] = (isset($_data['tags'])) ? $_data['tags'] : $is_now['tags'];
+ $attr["tagged_mail_handler"] = (!empty($_data['tagged_mail_handler'])) ? $_data['tagged_mail_handler'] : $is_now['tagged_mail_handler'];
$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'];
diff --git a/data/web/inc/vars.inc.php b/data/web/inc/vars.inc.php
index 671e2033..56810530 100644
--- a/data/web/inc/vars.inc.php
+++ b/data/web/inc/vars.inc.php
@@ -186,6 +186,12 @@ $MAILBOX_DEFAULT_ATTRIBUTES['force_pw_update'] = false;
// Enable SOGo access - Users will be redirected to SOGo after login (set to false to disable redirect by default)
$MAILBOX_DEFAULT_ATTRIBUTES['sogo_access'] = true;
+// How to handle tagged emails
+// none - No special handling
+// subfolder - Create subfolder under INBOX (e.g. "INBOX/Facebook")
+// subject - Add tag to subject (e.g. "[Facebook] Subject")
+$MAILBOX_DEFAULT_ATTRIBUTES['tagged_mail_handler'] = "none";
+
// Send notification when quarantine is not empty (never, hourly, daily, weekly)
$MAILBOX_DEFAULT_ATTRIBUTES['quarantine_notification'] = 'hourly';
@@ -257,57 +263,57 @@ $RSPAMD_MAPS = array(
$IMAPSYNC_OPTIONS = array(
'whitelist' => array(
- 'abort',
- 'authmd51',
- 'authmd52',
+ 'abort',
+ 'authmd51',
+ 'authmd52',
'authmech1',
'authmech2',
- 'authuser1',
- 'authuser2',
- 'debug',
- 'debugcontent',
- 'debugcrossduplicates',
- 'debugflags',
- 'debugfolders',
- 'debugimap',
- 'debugimap1',
- 'debugimap2',
- 'debugmemory',
- 'debugssl',
+ 'authuser1',
+ 'authuser2',
+ 'debug',
+ 'debugcontent',
+ 'debugcrossduplicates',
+ 'debugflags',
+ 'debugfolders',
+ 'debugimap',
+ 'debugimap1',
+ 'debugimap2',
+ 'debugmemory',
+ 'debugssl',
'delete1emptyfolders',
- 'delete2folders',
- 'disarmreadreceipts',
+ 'delete2folders',
+ 'disarmreadreceipts',
'domain1',
'domain2',
- 'domino1',
- 'domino2',
+ 'domino1',
+ 'domino2',
'dry',
'errorsmax',
- 'exchange1',
- 'exchange2',
+ 'exchange1',
+ 'exchange2',
'exitwhenover',
'expunge1',
- 'f1f2',
- 'filterbuggyflags',
+ 'f1f2',
+ 'filterbuggyflags',
'folder',
'folderfirst',
'folderlast',
'folderrec',
- 'gmail1',
- 'gmail2',
- 'idatefromheader',
+ 'gmail1',
+ 'gmail2',
+ 'idatefromheader',
'include',
'inet4',
'inet6',
- 'justconnect',
- 'justfolders',
- 'justfoldersizes',
- 'justlogin',
- 'keepalive1',
- 'keepalive2',
+ 'justconnect',
+ 'justfolders',
+ 'justfoldersizes',
+ 'justlogin',
+ 'keepalive1',
+ 'keepalive2',
'log',
'logdir',
- 'logfile',
+ 'logfile',
'maxbytesafter',
'maxlinelength',
'maxmessagespersecond',
@@ -315,62 +321,62 @@ $IMAPSYNC_OPTIONS = array(
'maxsleep',
'minage',
'minsize',
- 'noabletosearch',
- 'noabletosearch1',
- 'noabletosearch2',
- 'noexpunge1',
- 'noexpunge2',
+ 'noabletosearch',
+ 'noabletosearch1',
+ 'noabletosearch2',
+ 'noexpunge1',
+ 'noexpunge2',
'nofoldersizesatend',
- 'noid',
- 'nolog',
- 'nomixfolders',
- 'noresyncflags',
- 'nossl1',
- 'nossl2',
- 'nosyncacls',
- 'notls1',
- 'notls2',
- 'nouidexpunge2',
- 'nousecache',
+ 'noid',
+ 'nolog',
+ 'nomixfolders',
+ 'noresyncflags',
+ 'nossl1',
+ 'nossl2',
+ 'nosyncacls',
+ 'notls1',
+ 'notls2',
+ 'nouidexpunge2',
+ 'nousecache',
'oauthaccesstoken1',
'oauthaccesstoken2',
'oauthdirect1',
'oauthdirect2',
- 'office1',
- 'office2',
- 'pidfile',
- 'pidfilelocking',
+ 'office1',
+ 'office2',
+ 'pidfile',
+ 'pidfilelocking',
'prefix1',
'prefix2',
- 'proxyauth1',
- 'proxyauth2',
- 'resyncflags',
- 'resynclabels',
- 'search',
+ 'proxyauth1',
+ 'proxyauth2',
+ 'resyncflags',
+ 'resynclabels',
+ 'search',
'search1',
- 'search2',
+ 'search2',
'sep1',
'sep2',
'showpasswords',
'skipemptyfolders',
- 'ssl2',
+ 'ssl2',
'sslargs1',
- 'sslargs2',
+ 'sslargs2',
'subfolder1',
- 'subscribe',
+ 'subscribe',
'subscribed',
'syncacls',
'syncduplicates',
'syncinternaldates',
- 'synclabels',
- 'tests',
- 'testslive',
- 'testslive6',
- 'tls2',
- 'truncmess',
- 'usecache',
- 'useheader',
- 'useuid'
+ 'synclabels',
+ 'tests',
+ 'testslive',
+ 'testslive6',
+ 'tls2',
+ 'truncmess',
+ 'usecache',
+ 'useheader',
+ 'useuid'
),
'blacklist' => array(
'skipmess',
diff --git a/data/web/js/site/mailbox.js b/data/web/js/site/mailbox.js
index 28e6fd28..135ec764 100644
--- a/data/web/js/site/mailbox.js
+++ b/data/web/js/site/mailbox.js
@@ -269,6 +269,24 @@ $(document).ready(function() {
function setMailboxTemplateData(template){
$("#addInputQuota").val(template.quota / 1048576);
+ if (template.tagged_mail_handler === "subfolder"){
+ $('#tagged_mail_handler_subfolder').prop('checked', true);
+ $('#tagged_mail_handler_subject').prop('checked', false);
+ $('#tagged_mail_handler_none').prop('checked', false);
+ } else if(template.tagged_mail_handler === "subject"){
+ $('#tagged_mail_handler_subfolder').prop('checked', false);
+ $('#tagged_mail_handler_subject').prop('checked', true);
+ $('#tagged_mail_handler_none').prop('checked', false);
+ } else if(template.tagged_mail_handler === "none"){
+ $('#tagged_mail_handler_subfolder').prop('checked', false);
+ $('#tagged_mail_handler_subject').prop('checked', false);
+ $('#tagged_mail_handler_none').prop('checked', true);
+ } else {
+ $('#tagged_mail_handler_subfolder').prop('checked', false);
+ $('#tagged_mail_handler_subject').prop('checked', false);
+ $('#tagged_mail_handler_none').prop('checked', true);
+ }
+
if (template.quarantine_notification === "never"){
$('#quarantine_notification_never').prop('checked', true);
$('#quarantine_notification_hourly').prop('checked', false);
diff --git a/data/web/templates/edit/mailbox-templates.twig b/data/web/templates/edit/mailbox-templates.twig
index 6d150b26..65a83cd2 100644
--- a/data/web/templates/edit/mailbox-templates.twig
+++ b/data/web/templates/edit/mailbox-templates.twig
@@ -36,6 +36,23 @@
<small class="text-muted">0 = ∞</small>
</div>
</div>
+ <div class="row mb-2">
+ <label class="control-label col-sm-2">{{ lang.user.tag_handling }}</label>
+ <div class="col-sm-10">
+ <div class="btn-group">
+ <input type="radio" class="btn-check" name="tagged_mail_handler" id="tagged_mail_handler_subfolder" autocomplete="off" value="subfolder" {% if template.attributes.tagged_mail_handler == 'subfolder' %}checked{% endif %}>
+ <label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="tagged_mail_handler_subfolder">{{ lang.user.tag_in_subfolder }}</label>
+
+ <input type="radio" class="btn-check" name="tagged_mail_handler" id="tagged_mail_handler_subject" autocomplete="off" value="subject" {% if template.attributes.tagged_mail_handler == 'subject' %}checked{% endif %}>
+ <label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="tagged_mail_handler_subject">{{ lang.user.tag_in_subject }}</label>
+
+ <input type="radio" class="btn-check" name="tagged_mail_handler" id="tagged_mail_handler_none" autocomplete="off" value="none" {% if template.attributes.tagged_mail_handler == 'none' %}checked{% endif %}>
+ <label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="tagged_mail_handler_none">{{ lang.user.tag_in_none }}</label>
+ </div>
+ <p class="text-muted"><small>{{ lang.user.tag_help_explain|raw }}</small></p>
+ <p class="text-muted"><small>{{ lang.user.tag_help_example|raw }}</small></p>
+ </div>
+ </div>
<div class="row mb-2">
<label class="control-label col-sm-2">{{ lang.user.quarantine_notification }}</label>
<div class="col-sm-10">
diff --git a/data/web/templates/edit/mailbox.twig b/data/web/templates/edit/mailbox.twig
index 32a3706c..12c1f3b9 100644
--- a/data/web/templates/edit/mailbox.twig
+++ b/data/web/templates/edit/mailbox.twig
@@ -117,7 +117,7 @@
<div class="row mb-2">
<label class="control-label col-sm-2" for="relayhost">{{ lang.edit.relayhost }}</label>
<div class="col-sm-10">
- <select data-acl="{{ acl.mailbox_relayhost }}" data-live-search="true" id="relayhost" name="relayhost" class="form-control mb-4">
+ <select data-acl="{{ acl.mailbox_relayhost }}" data-live-search="true" id="relayhost" name="relayhost" class="form-control">
{% for rlyhost in rlyhosts %}
<option
style="{% if rlyhost.active != '1' %}background: #ff4136; color: #fff{% endif %}"
@@ -131,7 +131,34 @@
</option>
</select>
<p class="d-block d-sm-none" style="margin: 0;padding: 0"> </p>
- <small class="text-muted d-block">{{ lang.edit.mailbox_relayhost_info }}</small>
+ <small class="text-muted d-block mb-4">{{ lang.edit.mailbox_relayhost_info }}</small>
+ </div>
+ </div>
+ <div class="row mb-2">
+ <label class="control-label col-sm-2">{{ lang.user.tag_handling }}</label>
+ <div class="col-sm-10">
+ <div class="btn-group" data-acl="{{ acl.delimiter_action }}">
+ <button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline{% if get_tagging_options == 'subfolder' %} btn-dark{% else %} btn-light{% endif %}"
+ data-action="edit_selected"
+ data-item="{{ mailbox }}"
+ data-id="delimiter_action"
+ data-api-url='edit/delimiter_action'
+ data-api-attr='{"tagged_mail_handler":"subfolder"}'>{{ lang.user.tag_in_subfolder }}</button>
+ <button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline{% if get_tagging_options == 'subject' %} btn-dark{% else %} btn-light{% endif %}"
+ data-action="edit_selected"
+ data-item="{{ mailbox }}"
+ data-id="delimiter_action"
+ data-api-url='edit/delimiter_action'
+ data-api-attr='{"tagged_mail_handler":"subject"}'>{{ lang.user.tag_in_subject }}</button>
+ <button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline{% if get_tagging_options == 'none' %} btn-dark{% else %} btn-light{% endif %}"
+ data-action="edit_selected"
+ data-item="{{ mailbox }}"
+ data-id="delimiter_action"
+ data-api-url='edit/delimiter_action'
+ data-api-attr='{"tagged_mail_handler":"none"}'>{{ lang.user.tag_in_none }}</button>
+ </div>
+ <p class="text-muted"><small>{{ lang.user.tag_help_explain|raw }}</small></p>
+ <p class="text-muted"><small>{{ lang.user.tag_help_example|raw }}</small></p>
</div>
</div>
<div class="row mb-2">
diff --git a/data/web/templates/modals/mailbox.twig b/data/web/templates/modals/mailbox.twig
index 85091da4..0c164332 100644
--- a/data/web/templates/modals/mailbox.twig
+++ b/data/web/templates/modals/mailbox.twig
@@ -76,6 +76,23 @@
<div class="badge fs-5 bg-warning addInputQuotaExhausted" style="display:none;">{{ lang.warning.quota_exceeded_scope }}</div>
</div>
</div>
+ <div class="row mb-2">
+ <label class="control-label col-sm-2 text-sm-end text-sm-end">{{ lang.user.tag_handling }}</label>
+ <div class="col-sm-10">
+ <div class="btn-group">
+ <input type="radio" class="btn-check" name="tagged_mail_handler" id="tagged_mail_handler_subfolder" autocomplete="off" value="subfolder">
+ <label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="tagged_mail_handler_subfolder">{{ lang.user.tag_in_subfolder }}</label>
+
+ <input type="radio" class="btn-check" name="tagged_mail_handler" id="tagged_mail_handler_subject" autocomplete="off" value="subject">
+ <label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="tagged_mail_handler_subject">{{ lang.user.tag_in_subject }}</label>
+
+ <input type="radio" class="btn-check" name="tagged_mail_handler" id="tagged_mail_handler_none" autocomplete="off" value="none">
+ <label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="tagged_mail_handler_none">{{ lang.user.tag_in_none }}</label>
+ </div>
+ <p class="text-muted"><small>{{ lang.user.tag_help_explain|raw }}</small></p>
+ <p class="text-muted"><small>{{ lang.user.tag_help_example|raw }}</small></p>
+ </div>
+ </div>
<div class="row mb-2">
<label class="control-label col-sm-2 text-sm-end text-sm-end">{{ lang.user.quarantine_notification }}</label>
<div class="col-sm-10">
@@ -246,6 +263,23 @@
<small class="text-muted">0 = ∞</small>
</div>
</div>
+ <div class="row mb-2">
+ <label class="control-label col-sm-2 text-sm-end text-sm-end">{{ lang.user.tag_handling }}</label>
+ <div class="col-sm-10">
+ <div class="btn-group">
+ <input type="radio" class="btn-check" name="tagged_mail_handler" id="template_tagged_mail_handler_subfolder" autocomplete="off" value="subfolder">
+ <label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="template_tagged_mail_handler_subfolder">{{ lang.user.tag_in_subfolder }}</label>
+
+ <input type="radio" class="btn-check" name="tagged_mail_handler" id="template_tagged_mail_handler_subject" autocomplete="off" value="subject">
+ <label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="template_tagged_mail_handler_subject">{{ lang.user.tag_in_subject }}</label>
+
+ <input type="radio" class="btn-check" name="tagged_mail_handler" id="template_tagged_mail_handler_none" autocomplete="off" value="none">
+ <label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="template_tagged_mail_handler_none">{{ lang.user.tag_in_none }}</label>
+ </div>
+ <p class="text-muted"><small>{{ lang.user.tag_help_explain|raw }}</small></p>
+ <p class="text-muted"><small>{{ lang.user.tag_help_example|raw }}</small></p>
+ </div>
+ </div>
<div class="row mb-2">
<label class="control-label col-sm-2 text-sm-end text-sm-end">{{ lang.user.quarantine_notification }}</label>
<div class="col-sm-10">