You've already forked mailcow-dockerized
mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2025-07-13 01:30:34 +02:00
[Web][DockerApi] Add the ability to rename the local part of a mailbox
This commit is contained in:
@ -342,6 +342,30 @@ class DockerApi:
|
|||||||
cmd = ["/bin/bash", "-c", cmd_vmail]
|
cmd = ["/bin/bash", "-c", cmd_vmail]
|
||||||
maildir_cleanup = container.exec_run(cmd, user='vmail')
|
maildir_cleanup = container.exec_run(cmd, user='vmail')
|
||||||
return self.exec_run_handler('generic', maildir_cleanup)
|
return self.exec_run_handler('generic', maildir_cleanup)
|
||||||
|
# api call: container_post - post_action: exec - cmd: maildir - task: move
|
||||||
|
def container_post__exec__maildir__move(self, request_json, **kwargs):
|
||||||
|
if 'container_id' in kwargs:
|
||||||
|
filters = {"id": kwargs['container_id']}
|
||||||
|
elif 'container_name' in kwargs:
|
||||||
|
filters = {"name": kwargs['container_name']}
|
||||||
|
|
||||||
|
if 'old_maildir' in request_json and 'new_maildir' in request_json:
|
||||||
|
for container in self.sync_docker_client.containers.list(filters=filters):
|
||||||
|
vmail_name = request_json['old_maildir'].replace("'", "'\\''")
|
||||||
|
new_vmail_name = request_json['new_maildir'].replace("'", "'\\''")
|
||||||
|
cmd_vmail = "if [[ -d '/var/vmail/" + vmail_name + "' ]]; then /bin/mv '/var/vmail/" + vmail_name + "' '/var/vmail/" + new_vmail_name + "'; fi"
|
||||||
|
|
||||||
|
index_name = request_json['old_maildir'].split("/")
|
||||||
|
new_index_name = request_json['new_maildir'].split("/")
|
||||||
|
if len(index_name) > 1 and len(new_index_name) > 1:
|
||||||
|
index_name = index_name[1].replace("'", "'\\''") + "@" + index_name[0].replace("'", "'\\''")
|
||||||
|
new_index_name = new_index_name[1].replace("'", "'\\''") + "@" + new_index_name[0].replace("'", "'\\''")
|
||||||
|
cmd_vmail_index = "if [[ -d '/var/vmail_index/" + index_name + "' ]]; then /bin/mv '/var/vmail_index/" + index_name + "' '/var/vmail_index/" + new_index_name + "_index'; fi"
|
||||||
|
cmd = ["/bin/bash", "-c", cmd_vmail + " && " + cmd_vmail_index]
|
||||||
|
else:
|
||||||
|
cmd = ["/bin/bash", "-c", cmd_vmail]
|
||||||
|
maildir_move = container.exec_run(cmd, user='vmail')
|
||||||
|
return self.exec_run_handler('generic', maildir_move)
|
||||||
# api call: container_post - post_action: exec - cmd: rspamd - task: worker_password
|
# api call: container_post - post_action: exec - cmd: rspamd - task: worker_password
|
||||||
def container_post__exec__rspamd__worker_password(self, request_json, **kwargs):
|
def container_post__exec__rspamd__worker_password(self, request_json, **kwargs):
|
||||||
if 'container_id' in kwargs:
|
if 'container_id' in kwargs:
|
||||||
@ -374,6 +398,20 @@ class DockerApi:
|
|||||||
self.logger.error('failed changing Rspamd password')
|
self.logger.error('failed changing Rspamd password')
|
||||||
res = { 'type': 'danger', 'msg': 'command did not complete' }
|
res = { 'type': 'danger', 'msg': 'command did not complete' }
|
||||||
return Response(content=json.dumps(res, indent=4), media_type="application/json")
|
return Response(content=json.dumps(res, indent=4), media_type="application/json")
|
||||||
|
# api call: container_post - post_action: exec - cmd: sogo - task: rename
|
||||||
|
def container_post__exec__sogo__rename_user(self, request_json, **kwargs):
|
||||||
|
if 'container_id' in kwargs:
|
||||||
|
filters = {"id": kwargs['container_id']}
|
||||||
|
elif 'container_name' in kwargs:
|
||||||
|
filters = {"name": kwargs['container_name']}
|
||||||
|
|
||||||
|
if 'old_username' in request_json and 'new_username' in request_json:
|
||||||
|
for container in self.sync_docker_client.containers.list(filters=filters):
|
||||||
|
old_username = request_json['old_username'].replace("'", "'\\''")
|
||||||
|
new_username = request_json['new_username'].replace("'", "'\\''")
|
||||||
|
|
||||||
|
sogo_return = container.exec_run(['sogo-tool', 'rename-user', old_username, new_username], user='sogo')
|
||||||
|
return self.exec_run_handler('generic', sogo_return)
|
||||||
|
|
||||||
# Collect host stats
|
# Collect host stats
|
||||||
async def get_host_stats(self, wait=5):
|
async def get_host_stats(self, wait=5):
|
||||||
|
@ -953,11 +953,6 @@ function check_login($user, $pass, $app_passwd_data = false) {
|
|||||||
$_SESSION['pending_mailcow_cc_role'] = "user";
|
$_SESSION['pending_mailcow_cc_role'] = "user";
|
||||||
$_SESSION['pending_tfa_methods'] = $authenticators['additional'];
|
$_SESSION['pending_tfa_methods'] = $authenticators['additional'];
|
||||||
unset($_SESSION['ldelay']);
|
unset($_SESSION['ldelay']);
|
||||||
$_SESSION['return'][] = array(
|
|
||||||
'type' => 'success',
|
|
||||||
'log' => array(__FUNCTION__, $user, '*'),
|
|
||||||
'msg' => array('logged_in_as', $user)
|
|
||||||
);
|
|
||||||
return "pending";
|
return "pending";
|
||||||
} else if (!isset($authenticators['additional']) || !is_array($authenticators['additional']) || count($authenticators['additional']) == 0) {
|
} else if (!isset($authenticators['additional']) || !is_array($authenticators['additional']) || count($authenticators['additional']) == 0) {
|
||||||
// no authenticators found, login successfull
|
// no authenticators found, login successfull
|
||||||
@ -966,6 +961,11 @@ function check_login($user, $pass, $app_passwd_data = false) {
|
|||||||
$stmt->execute(array(':user' => $user));
|
$stmt->execute(array(':user' => $user));
|
||||||
|
|
||||||
unset($_SESSION['ldelay']);
|
unset($_SESSION['ldelay']);
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'success',
|
||||||
|
'log' => array(__FUNCTION__, $user, '*'),
|
||||||
|
'msg' => array('logged_in_as', $user)
|
||||||
|
);
|
||||||
return "user";
|
return "user";
|
||||||
}
|
}
|
||||||
} elseif ($app_passwd_data['eas'] === true || $app_passwd_data['dav'] === true) {
|
} elseif ($app_passwd_data['eas'] === true || $app_passwd_data['dav'] === true) {
|
||||||
|
@ -3203,6 +3203,146 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
case 'mailbox_rename':
|
||||||
|
$domain = $_data['domain'];
|
||||||
|
$old_local_part = $_data['old_local_part'];
|
||||||
|
$old_username = $old_local_part . "@" . $domain;
|
||||||
|
$new_local_part = $_data['new_local_part'];
|
||||||
|
$new_username = $new_local_part . "@" . $domain;
|
||||||
|
$create_alias = intval($_data['create_alias']);
|
||||||
|
|
||||||
|
if (!filter_var($old_username, FILTER_VALIDATE_EMAIL)) {
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => array('username_invalid', $old_username)
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!filter_var($new_username, FILTER_VALIDATE_EMAIL)) {
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => array('username_invalid', $new_username)
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$is_now = mailbox('get', 'mailbox_details', $old_username);
|
||||||
|
if (empty($is_now)) {
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => 'access_denied'
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $is_now['domain'])) {
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => 'access_denied'
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rename username in sql
|
||||||
|
try {
|
||||||
|
$pdo->beginTransaction();
|
||||||
|
$pdo->exec('SET FOREIGN_KEY_CHECKS = 0');
|
||||||
|
|
||||||
|
$pdo->prepare('UPDATE mailbox SET username = :new_username, local_part = :new_local_part WHERE username = :old_username')
|
||||||
|
->execute([
|
||||||
|
':new_username' => $new_username,
|
||||||
|
':new_local_part' => $new_local_part,
|
||||||
|
':old_username' => $old_username
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Update the username in all related tables
|
||||||
|
$tables = [
|
||||||
|
'tags_mailbox' => 'username',
|
||||||
|
'sieve_filters' => 'username',
|
||||||
|
'app_passwd' => 'mailbox',
|
||||||
|
'user_acl' => 'username',
|
||||||
|
'da_acl' => 'username',
|
||||||
|
'quota2' => 'username',
|
||||||
|
'quota2replica' => 'username',
|
||||||
|
'pushover' => 'username'
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($tables as $table => $column) {
|
||||||
|
$pdo->prepare("UPDATE $table SET $column = :new_username WHERE $column = :old_username")
|
||||||
|
->execute([
|
||||||
|
':new_username' => $new_username,
|
||||||
|
':old_username' => $old_username
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdo->prepare("UPDATE _sogo_static_view SET c_uid = :new_username, c_name = :new_username2, mail = :new_username3 WHERE c_uid = :old_username")
|
||||||
|
->execute([
|
||||||
|
':new_username' => $new_username,
|
||||||
|
':new_username2' => $new_username,
|
||||||
|
':new_username3' => $new_username,
|
||||||
|
':old_username' => $old_username
|
||||||
|
]);
|
||||||
|
|
||||||
|
$pdo->prepare("UPDATE alias SET address = :new_username, goto = :new_username2 WHERE address = :old_username")
|
||||||
|
->execute([
|
||||||
|
':new_username' => $new_username,
|
||||||
|
':new_username2' => $new_username,
|
||||||
|
':old_username' => $old_username
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
// Re-enable foreign key checks
|
||||||
|
$pdo->exec('SET FOREIGN_KEY_CHECKS = 1');
|
||||||
|
$pdo->commit();
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
// Rollback the transaction if something goes wrong
|
||||||
|
$pdo->rollBack();
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => $e->getMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// move maildir
|
||||||
|
$exec_fields = array(
|
||||||
|
'cmd' => 'maildir',
|
||||||
|
'task' => 'move',
|
||||||
|
'old_maildir' => $domain . '/' . $old_local_part,
|
||||||
|
'new_maildir' => $domain . '/' . $new_local_part
|
||||||
|
);
|
||||||
|
docker('post', 'dovecot-mailcow', 'exec', $exec_fields);
|
||||||
|
|
||||||
|
// rename username in sogo
|
||||||
|
$exec_fields = array(
|
||||||
|
'cmd' => 'sogo',
|
||||||
|
'task' => 'rename_user',
|
||||||
|
'old_username' => $old_username,
|
||||||
|
'new_username' => $new_username
|
||||||
|
);
|
||||||
|
docker('post', 'sogo-mailcow', 'exec', $exec_fields);
|
||||||
|
|
||||||
|
// create alias
|
||||||
|
if ($create_alias == 1) {
|
||||||
|
mailbox("add", "alias", array(
|
||||||
|
"address" => $old_username,
|
||||||
|
"goto" => $new_username,
|
||||||
|
"active" => 1,
|
||||||
|
"sogo_visible" => 1,
|
||||||
|
"private_comment" => sprintf($lang['success']['mailbox_renamed'], $old_username, $new_username)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'success',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => array('mailbox_renamed', $old_username, $new_username)
|
||||||
|
);
|
||||||
|
break;
|
||||||
case 'mailbox_templates':
|
case 'mailbox_templates':
|
||||||
if ($_SESSION['mailcow_cc_role'] != "admin") {
|
if ($_SESSION['mailcow_cc_role'] != "admin") {
|
||||||
$_SESSION['return'][] = array(
|
$_SESSION['return'][] = array(
|
||||||
|
@ -89,27 +89,30 @@ if (isset($_POST["login_user"]) && isset($_POST["pass_user"])) {
|
|||||||
if ($as == "admin") {
|
if ($as == "admin") {
|
||||||
$_SESSION['mailcow_cc_username'] = $login_user;
|
$_SESSION['mailcow_cc_username'] = $login_user;
|
||||||
$_SESSION['mailcow_cc_role'] = "admin";
|
$_SESSION['mailcow_cc_role'] = "admin";
|
||||||
header("Location: /admin");
|
header("Location: /debug");
|
||||||
|
die();
|
||||||
}
|
}
|
||||||
elseif ($as == "domainadmin") {
|
elseif ($as == "domainadmin") {
|
||||||
$_SESSION['mailcow_cc_username'] = $login_user;
|
$_SESSION['mailcow_cc_username'] = $login_user;
|
||||||
$_SESSION['mailcow_cc_role'] = "domainadmin";
|
$_SESSION['mailcow_cc_role'] = "domainadmin";
|
||||||
header("Location: /mailbox");
|
header("Location: /mailbox");
|
||||||
|
die();
|
||||||
}
|
}
|
||||||
elseif ($as == "user") {
|
elseif ($as == "user") {
|
||||||
$_SESSION['mailcow_cc_username'] = $login_user;
|
$_SESSION['mailcow_cc_username'] = $login_user;
|
||||||
$_SESSION['mailcow_cc_role'] = "user";
|
$_SESSION['mailcow_cc_role'] = "user";
|
||||||
$http_parameters = explode('&', $_SESSION['index_query_string']);
|
$http_parameters = explode('&', $_SESSION['index_query_string']);
|
||||||
unset($_SESSION['index_query_string']);
|
unset($_SESSION['index_query_string']);
|
||||||
if (in_array('mobileconfig', $http_parameters)) {
|
if (in_array('mobileconfig', $http_parameters)) {
|
||||||
if (in_array('only_email', $http_parameters)) {
|
if (in_array('only_email', $http_parameters)) {
|
||||||
header("Location: /mobileconfig.php?only_email");
|
header("Location: /mobileconfig.php?only_email");
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
header("Location: /mobileconfig.php");
|
header("Location: /mobileconfig.php");
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
header("Location: /user");
|
header("Location: /user");
|
||||||
|
die();
|
||||||
}
|
}
|
||||||
elseif ($as != "pending") {
|
elseif ($as != "pending") {
|
||||||
unset($_SESSION['pending_mailcow_cc_username']);
|
unset($_SESSION['pending_mailcow_cc_username']);
|
||||||
|
@ -58,6 +58,11 @@ $(document).ready(function() {
|
|||||||
$('input[name=multiple_bookings]').val($("#multiple_bookings_custom").val());
|
$('input[name=multiple_bookings]').val($("#multiple_bookings_custom").val());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$("#show_mailbox_rename_form").click(function() {
|
||||||
|
$("#rename_warning").hide();
|
||||||
|
$("#rename_form").removeClass("d-none");
|
||||||
|
});
|
||||||
|
|
||||||
// load tags
|
// load tags
|
||||||
if ($('#tags').length){
|
if ($('#tags').length){
|
||||||
var tagsEl = $('#tags').parent().find('.tag-values')[0];
|
var tagsEl = $('#tags').parent().find('.tag-values')[0];
|
||||||
|
@ -2020,6 +2020,9 @@ if (isset($_GET['query'])) {
|
|||||||
case "rl-mbox":
|
case "rl-mbox":
|
||||||
process_edit_return(ratelimit('edit', 'mailbox', array_merge(array('object' => $items), $attr)));
|
process_edit_return(ratelimit('edit', 'mailbox', array_merge(array('object' => $items), $attr)));
|
||||||
break;
|
break;
|
||||||
|
case "rename-mbox":
|
||||||
|
process_edit_return(mailbox('edit', 'mailbox_rename', array_merge(array('mailbox' => $items), $attr)));
|
||||||
|
break;
|
||||||
case "user-acl":
|
case "user-acl":
|
||||||
process_edit_return(acl('edit', 'user', array_merge(array('username' => $items), $attr)));
|
process_edit_return(acl('edit', 'user', array_merge(array('username' => $items), $attr)));
|
||||||
break;
|
break;
|
||||||
|
@ -641,6 +641,10 @@
|
|||||||
"mailbox": "Mailbox bearbeiten",
|
"mailbox": "Mailbox bearbeiten",
|
||||||
"mailbox_quota_def": "Standard-Quota einer Mailbox",
|
"mailbox_quota_def": "Standard-Quota einer Mailbox",
|
||||||
"mailbox_relayhost_info": "Wird auf eine Mailbox und direkte Alias-Adressen angewendet. Überschreibt die Einstellung einer Domain.",
|
"mailbox_relayhost_info": "Wird auf eine Mailbox und direkte Alias-Adressen angewendet. Überschreibt die Einstellung einer Domain.",
|
||||||
|
"mailbox_rename": "Mailbox umbennnen",
|
||||||
|
"mailbox_rename_agree": "Ich habe ein Backup erstellt.",
|
||||||
|
"mailbox_rename_warning": "WICHTIG! Vor dem Umbenennen der Mailbox ein Backup erstellen.",
|
||||||
|
"mailbox_rename_alias": "Alias automatisch erstellen",
|
||||||
"max_aliases": "Max. Aliasse",
|
"max_aliases": "Max. Aliasse",
|
||||||
"max_mailboxes": "Max. Mailboxanzahl",
|
"max_mailboxes": "Max. Mailboxanzahl",
|
||||||
"max_quota": "Max. Größe per Mailbox (MiB)",
|
"max_quota": "Max. Größe per Mailbox (MiB)",
|
||||||
@ -1084,6 +1088,7 @@
|
|||||||
"mailbox_added": "Mailbox %s wurde angelegt",
|
"mailbox_added": "Mailbox %s wurde angelegt",
|
||||||
"mailbox_modified": "Änderungen an Mailbox %s wurden gespeichert",
|
"mailbox_modified": "Änderungen an Mailbox %s wurden gespeichert",
|
||||||
"mailbox_removed": "Mailbox %s wurde entfernt",
|
"mailbox_removed": "Mailbox %s wurde entfernt",
|
||||||
|
"mailbox_renamed": "Mailbox wurde von %s in %s umbenannt",
|
||||||
"nginx_reloaded": "Nginx wurde neu geladen",
|
"nginx_reloaded": "Nginx wurde neu geladen",
|
||||||
"object_modified": "Änderungen an Objekt %s wurden gespeichert",
|
"object_modified": "Änderungen an Objekt %s wurden gespeichert",
|
||||||
"password_policy_saved": "Passwortrichtlinie wurde erfolgreich gespeichert",
|
"password_policy_saved": "Passwortrichtlinie wurde erfolgreich gespeichert",
|
||||||
|
@ -641,6 +641,10 @@
|
|||||||
"mailbox": "Edit mailbox",
|
"mailbox": "Edit mailbox",
|
||||||
"mailbox_quota_def": "Default mailbox quota",
|
"mailbox_quota_def": "Default mailbox quota",
|
||||||
"mailbox_relayhost_info": "Applied to the mailbox and direct aliases only, does override a domain relayhost.",
|
"mailbox_relayhost_info": "Applied to the mailbox and direct aliases only, does override a domain relayhost.",
|
||||||
|
"mailbox_rename": "Rename mailbox",
|
||||||
|
"mailbox_rename_agree": "I have created a backup.",
|
||||||
|
"mailbox_rename_warning": "IMPORTANT! Create a backup before renaming the mailbox.",
|
||||||
|
"mailbox_rename_alias": "Create alias automatically",
|
||||||
"max_aliases": "Max. aliases",
|
"max_aliases": "Max. aliases",
|
||||||
"max_mailboxes": "Max. possible mailboxes",
|
"max_mailboxes": "Max. possible mailboxes",
|
||||||
"max_quota": "Max. quota per mailbox (MiB)",
|
"max_quota": "Max. quota per mailbox (MiB)",
|
||||||
@ -1091,6 +1095,7 @@
|
|||||||
"mailbox_added": "Mailbox %s has been added",
|
"mailbox_added": "Mailbox %s has been added",
|
||||||
"mailbox_modified": "Changes to mailbox %s have been saved",
|
"mailbox_modified": "Changes to mailbox %s have been saved",
|
||||||
"mailbox_removed": "Mailbox %s has been removed",
|
"mailbox_removed": "Mailbox %s has been removed",
|
||||||
|
"mailbox_renamed": "Mailbox was renamed from %s to %s",
|
||||||
"nginx_reloaded": "Nginx was reloaded",
|
"nginx_reloaded": "Nginx was reloaded",
|
||||||
"object_modified": "Changes to object %s have been saved",
|
"object_modified": "Changes to object %s have been saved",
|
||||||
"password_policy_saved": "Password policy was saved successfully",
|
"password_policy_saved": "Password policy was saved successfully",
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
<li role="presentation" class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#mpushover">{{ lang.edit.pushover }}</button></li>
|
<li role="presentation" class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#mpushover">{{ lang.edit.pushover }}</button></li>
|
||||||
<li role="presentation" class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#macl">{{ lang.edit.acl }}</button></li>
|
<li role="presentation" class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#macl">{{ lang.edit.acl }}</button></li>
|
||||||
<li role="presentation" class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#mrl">{{ lang.edit.ratelimit }}</button></li>
|
<li role="presentation" class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#mrl">{{ lang.edit.ratelimit }}</button></li>
|
||||||
|
<li role="presentation" class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#mrename">⚠️ {{ lang.edit.mailbox_rename }}</button></li>
|
||||||
</ul>
|
</ul>
|
||||||
<hr class="d-none d-md-block">
|
<hr class="d-none d-md-block">
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
@ -287,10 +288,10 @@
|
|||||||
<div class="card mb-4">
|
<div class="card mb-4">
|
||||||
<div class="card-header d-flex d-md-none fs-5">
|
<div class="card-header d-flex d-md-none fs-5">
|
||||||
<button class="btn flex-grow-1 text-start" data-bs-target="#collapse-tab-mattr" data-bs-toggle="collapse" aria-controls="collapse-tab-mattr">
|
<button class="btn flex-grow-1 text-start" data-bs-target="#collapse-tab-mattr" data-bs-toggle="collapse" aria-controls="collapse-tab-mattr">
|
||||||
{{ lang.edit.mailbox }} <span class="badge bg-info table-lines"></span>
|
{{ lang.edit.custom_attributes }} <span class="badge bg-info table-lines"></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="collapse-tab-mattr" class="card-body collapse show" data-bs-parent="#mailbox-content">
|
<div id="collapse-tab-mattr" class="card-body collapse" data-bs-parent="#mailbox-content">
|
||||||
<form class="form-inline" data-id="mbox_attr" role="form" method="post">
|
<form class="form-inline" data-id="mbox_attr" role="form" method="post">
|
||||||
<table class="table table-condensed" style="white-space: nowrap;" id="mbox_attr_table">
|
<table class="table table-condensed" style="white-space: nowrap;" id="mbox_attr_table">
|
||||||
<tr>
|
<tr>
|
||||||
@ -477,6 +478,55 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="mrename" class="tab-pane fade" role="tabpanel" aria-labelledby="mailbox-rename">
|
||||||
|
<div class="card mb-4">
|
||||||
|
<div class="card-header d-flex d-md-none fs-5">
|
||||||
|
<button class="btn flex-grow-1 text-start" data-bs-target="#collapse-tab-mrename" data-bs-toggle="collapse" aria-controls="collapse-tab-mrename">
|
||||||
|
⚠️ {{ lang.edit.mailbox_rename }}<span class="badge bg-info table-lines"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div id="collapse-tab-mrename" class="card-body collapse" data-bs-parent="#mailbox-content">
|
||||||
|
<div class="well">
|
||||||
|
<div id="rename_warning">
|
||||||
|
<p>{{ lang.edit.mailbox_rename_warning }}</p>
|
||||||
|
<div id="confirm_show_rspamd_global_filters">
|
||||||
|
<div class="row">
|
||||||
|
<div class="offset-sm-2 col-sm-10">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" class="form-check-input" id="show_mailbox_rename_form"> {{ lang.edit.mailbox_rename_agree }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="rename_form" class="d-none">
|
||||||
|
<form data-id="mboxrename" method="post">
|
||||||
|
<input name="domain" type="hidden" value="{{ result.domain }}">
|
||||||
|
<input name="old_local_part" type="hidden" value="{{ result.local_part }}">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="offset-sm-2 col-sm-10 col-md-8 col-xl-6">
|
||||||
|
<div class="input-group mb-2">
|
||||||
|
<input type="text" class="form-control" name="new_local_part" autocomplete="off" value="{{ result.local_part }}">
|
||||||
|
<span class="input-group-text">@{{ result.domain }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="offset-sm-2 col-sm-10">
|
||||||
|
<label><input type="checkbox" class="form-check-input" value="1" name="create_alias" checked> {{ lang.edit.mailbox_rename_alias }}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="offset-sm-2 col-sm-10">
|
||||||
|
<button class="btn btn-xs-lg d-block d-sm-inline btn-secondary" data-action="edit_selected" data-id="mboxrename" data-item="{{ mailbox }}" data-api-url='edit/rename-mbox' data-api-attr='{}' data-api-reload-location="/mailbox" href="#">{{ lang.edit.save }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -534,7 +534,7 @@ services:
|
|||||||
- watchdog
|
- watchdog
|
||||||
|
|
||||||
dockerapi-mailcow:
|
dockerapi-mailcow:
|
||||||
image: mailcow/dockerapi:2.08
|
image: mailcow/dockerapi:2.09
|
||||||
security_opt:
|
security_opt:
|
||||||
- label=disable
|
- label=disable
|
||||||
restart: always
|
restart: always
|
||||||
|
Reference in New Issue
Block a user