mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2024-11-21 03:14:00 +08:00
Merge pull request #6045 from mailcow/feat/rename-mbox
[Web][DockerApi] Add Feature to Rename Email Addresses
This commit is contained in:
commit
2d76ffc88c
@ -90,7 +90,7 @@ async def get_container(container_id : str):
|
||||
if container._id == container_id:
|
||||
container_info = await container.show()
|
||||
return Response(content=json.dumps(container_info, indent=4), media_type="application/json")
|
||||
|
||||
|
||||
res = {
|
||||
"type": "danger",
|
||||
"msg": "no container found"
|
||||
@ -130,7 +130,7 @@ async def get_containers():
|
||||
async def post_containers(container_id : str, post_action : str, request: Request):
|
||||
global dockerapi
|
||||
|
||||
try :
|
||||
try:
|
||||
request_json = await request.json()
|
||||
except Exception as err:
|
||||
request_json = {}
|
||||
@ -191,7 +191,7 @@ async def post_container_update_stats(container_id : str):
|
||||
|
||||
stats = json.loads(await dockerapi.redis_client.get(container_id + '_stats'))
|
||||
return Response(content=json.dumps(stats, indent=4), media_type="application/json")
|
||||
|
||||
|
||||
|
||||
# PubSub Handler
|
||||
async def handle_pubsub_messages(channel: aioredis.client.PubSub):
|
||||
@ -244,7 +244,7 @@ async def handle_pubsub_messages(channel: aioredis.client.PubSub):
|
||||
dockerapi.logger.error("Unknwon PubSub recieved - %s" % json.dumps(data_json))
|
||||
else:
|
||||
dockerapi.logger.error("Unknwon PubSub recieved - %s" % json.dumps(data_json))
|
||||
|
||||
|
||||
await asyncio.sleep(0.0)
|
||||
except asyncio.TimeoutError:
|
||||
pass
|
||||
|
@ -159,7 +159,7 @@ class DockerApi:
|
||||
postqueue_r = container.exec_run(["/bin/bash", "-c", "/usr/sbin/postqueue " + i], user='postfix')
|
||||
# todo: check each exit code
|
||||
res = { 'type': 'success', 'msg': 'Scheduled immediate delivery'}
|
||||
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: mailq - task: list
|
||||
def container_post__exec__mailq__list(self, request_json, **kwargs):
|
||||
if 'container_id' in kwargs:
|
||||
@ -318,7 +318,7 @@ class DockerApi:
|
||||
|
||||
if 'username' in request_json and 'script_name' in request_json:
|
||||
for container in self.sync_docker_client.containers.list(filters=filters):
|
||||
cmd = ["/bin/bash", "-c", "/usr/bin/doveadm sieve get -u '" + request_json['username'].replace("'", "'\\''") + "' '" + request_json['script_name'].replace("'", "'\\''") + "'"]
|
||||
cmd = ["/bin/bash", "-c", "/usr/bin/doveadm sieve get -u '" + request_json['username'].replace("'", "'\\''") + "' '" + request_json['script_name'].replace("'", "'\\''") + "'"]
|
||||
sieve_return = container.exec_run(cmd)
|
||||
return self.exec_run_handler('utf8_text_only', sieve_return)
|
||||
# api call: container_post - post_action: exec - cmd: maildir - task: cleanup
|
||||
@ -342,6 +342,30 @@ class DockerApi:
|
||||
cmd = ["/bin/bash", "-c", cmd_vmail]
|
||||
maildir_cleanup = container.exec_run(cmd, user='vmail')
|
||||
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 = f"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 = f"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
|
||||
def container_post__exec__rspamd__worker_password(self, request_json, **kwargs):
|
||||
if 'container_id' in kwargs:
|
||||
@ -374,6 +398,107 @@ class DockerApi:
|
||||
self.logger.error('failed changing Rspamd password')
|
||||
res = { 'type': 'danger', 'msg': 'command did not complete' }
|
||||
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(["/bin/bash", "-c", f"sogo-tool rename-user '{old_username}' '{new_username}'"], user='sogo')
|
||||
return self.exec_run_handler('generic', sogo_return)
|
||||
# api call: container_post - post_action: exec - cmd: doveadm - task: get_acl
|
||||
def container_post__exec__doveadm__get_acl(self, request_json, **kwargs):
|
||||
if 'container_id' in kwargs:
|
||||
filters = {"id": kwargs['container_id']}
|
||||
elif 'container_name' in kwargs:
|
||||
filters = {"name": kwargs['container_name']}
|
||||
|
||||
for container in self.sync_docker_client.containers.list(filters=filters):
|
||||
id = request_json['id'].replace("'", "'\\''")
|
||||
|
||||
shared_folders = container.exec_run(["/bin/bash", "-c", f"doveadm mailbox list -u '{id}'"])
|
||||
shared_folders = shared_folders.output.decode('utf-8')
|
||||
shared_folders = shared_folders.splitlines()
|
||||
|
||||
formatted_acls = []
|
||||
mailbox_seen = []
|
||||
for shared_folder in shared_folders:
|
||||
if "Shared" not in shared_folder and "/" not in shared_folder:
|
||||
continue
|
||||
shared_folder = shared_folder.split("/")
|
||||
if len(shared_folder) < 3:
|
||||
continue
|
||||
|
||||
user = shared_folder[1].replace("'", "'\\''")
|
||||
mailbox = '/'.join(shared_folder[2:]).replace("'", "'\\''")
|
||||
if mailbox in mailbox_seen:
|
||||
continue
|
||||
|
||||
acls = container.exec_run(["/bin/bash", "-c", f"doveadm acl get -u '{user}' '{mailbox}'"])
|
||||
acls = acls.output.decode('utf-8').strip().splitlines()
|
||||
if len(acls) >= 2:
|
||||
for acl in acls[1:]:
|
||||
_, rights = acls[1].split(maxsplit=1)
|
||||
mailbox_seen.append(mailbox)
|
||||
formatted_acls.append({ 'user': user, 'id': id, 'mailbox': mailbox, 'rights': rights.split() })
|
||||
|
||||
return Response(content=json.dumps(formatted_acls, indent=4), media_type="application/json")
|
||||
# api call: container_post - post_action: exec - cmd: doveadm - task: delete_acl
|
||||
def container_post__exec__doveadm__delete_acl(self, request_json, **kwargs):
|
||||
if 'container_id' in kwargs:
|
||||
filters = {"id": kwargs['container_id']}
|
||||
elif 'container_name' in kwargs:
|
||||
filters = {"name": kwargs['container_name']}
|
||||
|
||||
for container in self.sync_docker_client.containers.list(filters=filters):
|
||||
user = request_json['user'].replace("'", "'\\''")
|
||||
mailbox = request_json['mailbox'].replace("'", "'\\''")
|
||||
id = request_json['id'].replace("'", "'\\''")
|
||||
|
||||
if user and mailbox and id:
|
||||
acl_delete_return = container.exec_run(["/bin/bash", "-c", f"doveadm acl delete -u '{user}' '{mailbox}' 'user={id}'"])
|
||||
return self.exec_run_handler('generic', acl_delete_return)
|
||||
# api call: container_post - post_action: exec - cmd: doveadm - task: set_acl
|
||||
def container_post__exec__doveadm__set_acl(self, request_json, **kwargs):
|
||||
if 'container_id' in kwargs:
|
||||
filters = {"id": kwargs['container_id']}
|
||||
elif 'container_name' in kwargs:
|
||||
filters = {"name": kwargs['container_name']}
|
||||
|
||||
for container in self.sync_docker_client.containers.list(filters=filters):
|
||||
user = request_json['user'].replace("'", "'\\''")
|
||||
mailbox = request_json['mailbox'].replace("'", "'\\''")
|
||||
id = request_json['id'].replace("'", "'\\''")
|
||||
rights = ""
|
||||
|
||||
available_rights = [
|
||||
"admin",
|
||||
"create",
|
||||
"delete",
|
||||
"expunge",
|
||||
"insert",
|
||||
"lookup",
|
||||
"post",
|
||||
"read",
|
||||
"write",
|
||||
"write-deleted",
|
||||
"write-seen"
|
||||
]
|
||||
for right in request_json['rights']:
|
||||
right = right.replace("'", "'\\''").lower()
|
||||
if right in available_rights:
|
||||
rights += right + " "
|
||||
|
||||
if user and mailbox and id and rights:
|
||||
acl_set_return = container.exec_run(["/bin/bash", "-c", f"doveadm acl set -u '{user}' '{mailbox}' 'user={id}' {rights}"])
|
||||
return self.exec_run_handler('generic', acl_set_return)
|
||||
|
||||
|
||||
# Collect host stats
|
||||
async def get_host_stats(self, wait=5):
|
||||
@ -462,7 +587,7 @@ class DockerApi:
|
||||
except:
|
||||
pass
|
||||
return ''.join(total_data)
|
||||
|
||||
|
||||
try :
|
||||
socket = container.exec_run([shell_cmd], stdin=True, socket=True, user=user).output._sock
|
||||
if not cmd.endswith("\n"):
|
||||
|
@ -939,10 +939,10 @@ function check_login($user, $pass, $app_passwd_data = false) {
|
||||
$stmt->execute(array(':user' => $user));
|
||||
$rows = array_merge($rows, $stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
}
|
||||
foreach ($rows as $row) {
|
||||
foreach ($rows as $row) {
|
||||
// verify password
|
||||
if (verify_hash($row['password'], $pass) !== false) {
|
||||
if (!array_key_exists("app_passwd_id", $row)){
|
||||
if (!array_key_exists("app_passwd_id", $row)){
|
||||
// password is not a app password
|
||||
// check for tfa authenticators
|
||||
$authenticators = get_tfa($user);
|
||||
@ -953,11 +953,6 @@ function check_login($user, $pass, $app_passwd_data = false) {
|
||||
$_SESSION['pending_mailcow_cc_role'] = "user";
|
||||
$_SESSION['pending_tfa_methods'] = $authenticators['additional'];
|
||||
unset($_SESSION['ldelay']);
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $user, '*'),
|
||||
'msg' => array('logged_in_as', $user)
|
||||
);
|
||||
return "pending";
|
||||
} else if (!isset($authenticators['additional']) || !is_array($authenticators['additional']) || count($authenticators['additional']) == 0) {
|
||||
// no authenticators found, login successfull
|
||||
@ -966,6 +961,11 @@ function check_login($user, $pass, $app_passwd_data = false) {
|
||||
$stmt->execute(array(':user' => $user));
|
||||
|
||||
unset($_SESSION['ldelay']);
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $user, '*'),
|
||||
'msg' => array('logged_in_as', $user)
|
||||
);
|
||||
return "user";
|
||||
}
|
||||
} elseif ($app_passwd_data['eas'] === true || $app_passwd_data['dav'] === true) {
|
||||
@ -1028,7 +1028,7 @@ function update_sogo_static_view($mailbox = null) {
|
||||
// Check if the mailbox exists
|
||||
$stmt = $pdo->prepare("SELECT username FROM mailbox WHERE username = :mailbox AND active = '1'");
|
||||
$stmt->execute(array(':mailbox' => $mailbox));
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row){
|
||||
$mailbox_exists = true;
|
||||
}
|
||||
@ -1056,7 +1056,7 @@ function update_sogo_static_view($mailbox = null) {
|
||||
LEFT OUTER JOIN grouped_sender_acl_external external_acl ON external_acl.username = mailbox.username
|
||||
WHERE
|
||||
mailbox.active = '1'";
|
||||
|
||||
|
||||
if ($mailbox_exists) {
|
||||
$query .= " AND mailbox.username = :mailbox";
|
||||
$stmt = $pdo->prepare($query);
|
||||
@ -1065,9 +1065,9 @@ function update_sogo_static_view($mailbox = null) {
|
||||
$query .= " GROUP BY mailbox.username";
|
||||
$stmt = $pdo->query($query);
|
||||
}
|
||||
|
||||
|
||||
$stmt = $pdo->query("DELETE FROM _sogo_static_view WHERE `c_uid` NOT IN (SELECT `username` FROM `mailbox` WHERE `active` = '1');");
|
||||
|
||||
|
||||
flush_memcached();
|
||||
}
|
||||
function edit_user_account($_data) {
|
||||
@ -1100,7 +1100,7 @@ function edit_user_account($_data) {
|
||||
AND `username` = :user");
|
||||
$stmt->execute(array(':user' => $username));
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
|
||||
if (!verify_hash($row['password'], $password_old)) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
@ -1109,7 +1109,7 @@ function edit_user_account($_data) {
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$password_new = $_data['user_new_pass'];
|
||||
$password_new2 = $_data['user_new_pass2'];
|
||||
if (password_check($password_new, $password_new2) !== true) {
|
||||
@ -1124,7 +1124,7 @@ function edit_user_account($_data) {
|
||||
':password_hashed' => $password_hashed,
|
||||
':username' => $username
|
||||
));
|
||||
|
||||
|
||||
update_sogo_static_view();
|
||||
}
|
||||
// edit password recovery email
|
||||
@ -1374,7 +1374,7 @@ function set_tfa($_data) {
|
||||
$_data['registration']->certificate,
|
||||
0
|
||||
));
|
||||
|
||||
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_data_log),
|
||||
@ -1544,7 +1544,7 @@ function unset_tfa_key($_data) {
|
||||
|
||||
try {
|
||||
if (!is_numeric($id)) $access_denied = true;
|
||||
|
||||
|
||||
// set access_denied error
|
||||
if ($access_denied){
|
||||
$_SESSION['return'][] = array(
|
||||
@ -1553,7 +1553,7 @@ function unset_tfa_key($_data) {
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// check if it's last key
|
||||
$stmt = $pdo->prepare("SELECT COUNT(*) AS `keys` FROM `tfa`
|
||||
@ -1602,7 +1602,7 @@ function get_tfa($username = null, $id = null) {
|
||||
WHERE `username` = :username AND `active` = '1'");
|
||||
$stmt->execute(array(':username' => $username));
|
||||
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
|
||||
// no tfa methods found
|
||||
if (count($results) == 0) {
|
||||
$data['name'] = 'none';
|
||||
@ -1810,8 +1810,8 @@ function verify_tfa_login($username, $_data) {
|
||||
'msg' => array('webauthn_authenticator_failed')
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (empty($process_webauthn['publicKey']) || $process_webauthn['publicKey'] === false) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
@ -2173,7 +2173,7 @@ function cors($action, $data = null) {
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$allowed_origins = isset($data['allowed_origins']) ? $data['allowed_origins'] : array($_SERVER['SERVER_NAME']);
|
||||
$allowed_origins = !is_array($allowed_origins) ? array_filter(array_map('trim', explode("\n", $allowed_origins))) : $allowed_origins;
|
||||
@ -2206,7 +2206,7 @@ function cors($action, $data = null) {
|
||||
$redis->hMSet('CORS_SETTINGS', array(
|
||||
'allowed_origins' => implode(', ', $allowed_origins),
|
||||
'allowed_methods' => implode(', ', $allowed_methods)
|
||||
));
|
||||
));
|
||||
} catch (RedisException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
@ -2258,10 +2258,10 @@ function cors($action, $data = null) {
|
||||
header('Access-Control-Allow-Headers: Accept, Content-Type, X-Api-Key, Origin');
|
||||
|
||||
// Access-Control settings requested, this is just a preflight request
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS' &&
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS' &&
|
||||
isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) &&
|
||||
isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) {
|
||||
|
||||
|
||||
$allowed_methods = explode(', ', $cors_settings["allowed_methods"]);
|
||||
if (in_array($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'], $allowed_methods, true))
|
||||
// method allowed send 200 OK
|
||||
@ -2315,7 +2315,7 @@ function reset_password($action, $data = null) {
|
||||
break;
|
||||
case 'issue':
|
||||
$username = $data;
|
||||
|
||||
|
||||
// perform cleanup
|
||||
$stmt = $pdo->prepare("DELETE FROM `reset_password` WHERE created < DATE_SUB(NOW(), INTERVAL :lifetime MINUTE);");
|
||||
$stmt->execute(array(':lifetime' => $PW_RESET_TOKEN_LIFETIME));
|
||||
@ -2397,8 +2397,8 @@ function reset_password($action, $data = null) {
|
||||
$request_date = new DateTime();
|
||||
$locale_date = locale_get_default();
|
||||
$date_formatter = new IntlDateFormatter(
|
||||
$locale_date,
|
||||
IntlDateFormatter::FULL,
|
||||
$locale_date,
|
||||
IntlDateFormatter::FULL,
|
||||
IntlDateFormatter::FULL
|
||||
);
|
||||
$formatted_request_date = $date_formatter->format($request_date);
|
||||
@ -2514,7 +2514,7 @@ function reset_password($action, $data = null) {
|
||||
$stmt->execute(array(
|
||||
':username' => $username
|
||||
));
|
||||
|
||||
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $action, $_data_log),
|
||||
@ -2557,7 +2557,7 @@ function reset_password($action, $data = null) {
|
||||
$text = $data['text'];
|
||||
$html = $data['html'];
|
||||
$subject = $data['subject'];
|
||||
|
||||
|
||||
if (!filter_var($from, FILTER_VALIDATE_EMAIL)) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
@ -2590,7 +2590,7 @@ function reset_password($action, $data = null) {
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
ini_set('max_execution_time', 0);
|
||||
ini_set('max_input_time', 0);
|
||||
$mail = new PHPMailer;
|
||||
@ -2622,7 +2622,7 @@ function reset_password($action, $data = null) {
|
||||
return false;
|
||||
}
|
||||
$mail->ClearAllRecipients();
|
||||
|
||||
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
@ -1233,7 +1233,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
':active' => $active
|
||||
));
|
||||
|
||||
|
||||
|
||||
if (isset($_data['acl'])) {
|
||||
$_data['acl'] = (array)$_data['acl'];
|
||||
$_data['spam_alias'] = (in_array('spam_alias', $_data['acl'])) ? 1 : 0;
|
||||
@ -1265,14 +1265,14 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
$_data['quarantine_attachments'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_quarantine_attachments']);
|
||||
$_data['quarantine_notification'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_quarantine_notification']);
|
||||
$_data['quarantine_category'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_quarantine_category']);
|
||||
$_data['app_passwds'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_app_passwds']);
|
||||
$_data['pw_reset'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_pw_reset']);
|
||||
$_data['app_passwds'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_app_passwds']);
|
||||
$_data['pw_reset'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_pw_reset']);
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = $pdo->prepare("INSERT INTO `user_acl`
|
||||
$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`, `pw_reset`)
|
||||
`pushover`, `quarantine`, `quarantine_attachments`, `quarantine_notification`, `quarantine_category`, `app_passwds`, `pw_reset`)
|
||||
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, :pw_reset) ");
|
||||
$stmt->execute(array(
|
||||
@ -1467,7 +1467,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// check attributes
|
||||
$attr = array();
|
||||
$attr['tags'] = (isset($_data['tags'])) ? $_data['tags'] : array();
|
||||
@ -1557,7 +1557,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
$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 {
|
||||
$attr['imap_access'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['imap_access']);
|
||||
$attr['pop3_access'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['pop3_access']);
|
||||
@ -2109,7 +2109,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// check if param is whitelisted
|
||||
if (!in_array(strtolower($param), $GLOBALS["IMAPSYNC_OPTIONS"]["whitelist"])){
|
||||
// bad option
|
||||
@ -2802,11 +2802,11 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
// check name
|
||||
if ($is_now["template"] == "Default" && $is_now["template"] != $_data["template"]){
|
||||
// keep template name of Default template
|
||||
$_data["template"] = $is_now["template"];
|
||||
$_data["template"] = $is_now["template"];
|
||||
}
|
||||
else {
|
||||
$_data["template"] = (isset($_data["template"])) ? $_data["template"] : $is_now["template"];
|
||||
}
|
||||
$_data["template"] = (isset($_data["template"])) ? $_data["template"] : $is_now["template"];
|
||||
}
|
||||
// check attributes
|
||||
$attr = array();
|
||||
$attr['tags'] = (isset($_data['tags'])) ? $_data['tags'] : array();
|
||||
@ -2833,10 +2833,10 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
":id" => $id ,
|
||||
":template" => $_data["template"] ,
|
||||
":attributes" => json_encode($attr)
|
||||
));
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
@ -3192,7 +3192,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
':tag_name' => $tag,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
@ -3203,6 +3203,195 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
}
|
||||
return true;
|
||||
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;
|
||||
}
|
||||
|
||||
// get imap acls
|
||||
try {
|
||||
$exec_fields = array(
|
||||
'cmd' => 'doveadm',
|
||||
'task' => 'get_acl',
|
||||
'id' => $old_username
|
||||
);
|
||||
$imap_acls = json_decode(docker('post', 'dovecot-mailcow', 'exec', $exec_fields), true);
|
||||
// delete imap acls
|
||||
foreach ($imap_acls as $imap_acl) {
|
||||
$exec_fields = array(
|
||||
'cmd' => 'doveadm',
|
||||
'task' => 'delete_acl',
|
||||
'user' => $imap_acl['user'],
|
||||
'mailbox' => $imap_acl['mailbox'],
|
||||
'id' => $imap_acl['id']
|
||||
);
|
||||
docker('post', 'dovecot-mailcow', 'exec', $exec_fields);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => $e->getMessage()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
// rename username in sql
|
||||
try {
|
||||
$pdo->beginTransaction();
|
||||
$pdo->exec('SET FOREIGN_KEY_CHECKS = 0');
|
||||
|
||||
// Update username in mailbox table
|
||||
$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
|
||||
]);
|
||||
|
||||
$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
|
||||
]);
|
||||
|
||||
// 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'],
|
||||
'alias' => ['goto'],
|
||||
"imapsync" => ['user2'],
|
||||
'bcc_maps' => ['local_dest', 'bcc_dest'],
|
||||
'recipient_maps' => ['old_dest', 'new_dest'],
|
||||
'sender_acl' => ['logged_in_as', 'send_as']
|
||||
];
|
||||
foreach ($tables as $table => $columns) {
|
||||
foreach ($columns as $column) {
|
||||
$stmt = $pdo->prepare("UPDATE $table SET $column = :new_username WHERE $column = :old_username")
|
||||
->execute([
|
||||
':new_username' => $new_username,
|
||||
':old_username' => $old_username
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Update c_uid, c_name and mail in _sogo_static_view table
|
||||
$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
|
||||
]);
|
||||
|
||||
// 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()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// set imap acls
|
||||
foreach ($imap_acls as $imap_acl) {
|
||||
$exec_fields = array(
|
||||
'cmd' => 'doveadm',
|
||||
'task' => 'set_acl',
|
||||
'user' => $imap_acl['user'],
|
||||
'mailbox' => $imap_acl['mailbox'],
|
||||
'id' => $new_username,
|
||||
'rights' => $imap_acl['rights']
|
||||
);
|
||||
docker('post', 'dovecot-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':
|
||||
if ($_SESSION['mailcow_cc_role'] != "admin") {
|
||||
$_SESSION['return'][] = array(
|
||||
@ -3235,11 +3424,11 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
// check name
|
||||
if ($is_now["template"] == "Default" && $is_now["template"] != $_data["template"]){
|
||||
// keep template name of Default template
|
||||
$_data["template"] = $is_now["template"];
|
||||
$_data["template"] = $is_now["template"];
|
||||
}
|
||||
else {
|
||||
$_data["template"] = (isset($_data["template"])) ? $_data["template"] : $is_now["template"];
|
||||
}
|
||||
$_data["template"] = (isset($_data["template"])) ? $_data["template"] : $is_now["template"];
|
||||
}
|
||||
// check attributes
|
||||
$attr = array();
|
||||
$attr["quota"] = isset($_data['quota']) ? intval($_data['quota']) * 1048576 : 0;
|
||||
@ -3259,11 +3448,11 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
$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 {
|
||||
}
|
||||
else {
|
||||
foreach ($is_now as $key => $value){
|
||||
$attr[$key] = $is_now[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($_data['acl'])) {
|
||||
$_data['acl'] = (array)$_data['acl'];
|
||||
@ -3282,10 +3471,10 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
$attr['acl_quarantine_category'] = (in_array('quarantine_category', $_data['acl'])) ? 1 : 0;
|
||||
$attr['acl_app_passwds'] = (in_array('app_passwds', $_data['acl'])) ? 1 : 0;
|
||||
$attr['acl_pw_reset'] = (in_array('pw_reset', $_data['acl'])) ? 1 : 0;
|
||||
} else {
|
||||
} else {
|
||||
foreach ($is_now as $key => $value){
|
||||
$attr[$key] = $is_now[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3297,7 +3486,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
":id" => $id ,
|
||||
":template" => $_data["template"] ,
|
||||
":attributes" => json_encode($attr)
|
||||
));
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@ -3326,7 +3515,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
);
|
||||
continue;
|
||||
}
|
||||
$is_now = mailbox('get', 'mailbox_details', $mailbox);
|
||||
$is_now = mailbox('get', 'mailbox_details', $mailbox);
|
||||
if(!empty($is_now)){
|
||||
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $is_now['domain'])) {
|
||||
$_SESSION['return'][] = array(
|
||||
@ -3353,15 +3542,15 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
$stmt->execute(array(
|
||||
":username" => $mailbox,
|
||||
":custom_attributes" => json_encode($attributes)
|
||||
));
|
||||
|
||||
));
|
||||
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => array('mailbox_modified', $mailbox)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
break;
|
||||
case 'resource':
|
||||
@ -3443,7 +3632,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'domain_wide_footer':
|
||||
case 'domain_wide_footer':
|
||||
if (!is_array($_data['domains'])) {
|
||||
$domains = array();
|
||||
$domains[] = $_data['domains'];
|
||||
@ -3696,7 +3885,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
|
||||
// prepend domain to array
|
||||
$params = array();
|
||||
foreach ($tags as $key => $val){
|
||||
foreach ($tags as $key => $val){
|
||||
array_push($params, '%'.$_data.'%');
|
||||
array_push($params, '%'.$val.'%');
|
||||
}
|
||||
@ -3705,7 +3894,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
|
||||
$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]))
|
||||
if (hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], explode('@', $row['username'])[1]))
|
||||
$mailboxes[] = $row['username'];
|
||||
}
|
||||
}
|
||||
@ -4260,7 +4449,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
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']))
|
||||
elseif (hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $row['domain']))
|
||||
$domains[] = $row['domain'];
|
||||
}
|
||||
} else {
|
||||
@ -4420,19 +4609,19 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
}
|
||||
$_data = (isset($_data)) ? intval($_data) : null;
|
||||
|
||||
if (isset($_data)){
|
||||
$stmt = $pdo->prepare("SELECT * FROM `templates`
|
||||
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;
|
||||
}
|
||||
@ -4440,11 +4629,11 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
$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);
|
||||
}
|
||||
@ -4617,19 +4806,19 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
}
|
||||
$_data = (isset($_data)) ? intval($_data) : null;
|
||||
|
||||
if (isset($_data)){
|
||||
$stmt = $pdo->prepare("SELECT * FROM `templates`
|
||||
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;
|
||||
}
|
||||
@ -5071,7 +5260,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
$ids = $_data['ids'];
|
||||
}
|
||||
|
||||
|
||||
|
||||
foreach ($ids as $id) {
|
||||
// delete template
|
||||
$stmt = $pdo->prepare("DELETE FROM `templates`
|
||||
@ -5384,7 +5573,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
update_sogo_static_view($username);
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
@ -5411,7 +5600,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
$ids = $_data['ids'];
|
||||
}
|
||||
|
||||
|
||||
|
||||
foreach ($ids as $id) {
|
||||
// delete template
|
||||
$stmt = $pdo->prepare("DELETE FROM `templates`
|
||||
@ -5420,7 +5609,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
":id" => $id,
|
||||
":type" => "mailbox",
|
||||
":template" => "Default"
|
||||
));
|
||||
));
|
||||
}
|
||||
|
||||
$_SESSION['return'][] = array(
|
||||
@ -5494,7 +5683,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'tags_domain':
|
||||
case 'tags_domain':
|
||||
if (!is_array($_data['domain'])) {
|
||||
$domains = array();
|
||||
$domains[] = $_data['domain'];
|
||||
@ -5507,7 +5696,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
|
||||
|
||||
$wasModified = false;
|
||||
foreach ($domains as $domain) {
|
||||
foreach ($domains as $domain) {
|
||||
if (!is_valid_domain_name($domain)) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
@ -5524,7 +5713,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
foreach($tags as $tag){
|
||||
// delete tag
|
||||
$wasModified = true;
|
||||
@ -5579,7 +5768,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
// 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,
|
||||
|
@ -18,7 +18,7 @@ if (isset($_POST["pw_reset_request"]) && !empty($_POST['username'])) {
|
||||
if (isset($_POST["pw_reset"])) {
|
||||
$username = reset_password("check", $_POST['token']);
|
||||
$reset_result = reset_password("reset", array(
|
||||
'new_password' => $_POST['new_password'],
|
||||
'new_password' => $_POST['new_password'],
|
||||
'new_password2' => $_POST['new_password2'],
|
||||
'token' => $_POST['token'],
|
||||
'username' => $username,
|
||||
@ -52,7 +52,7 @@ if (isset($_POST["verify_tfa_login"])) {
|
||||
unset($_SESSION['pending_mailcow_cc_username']);
|
||||
unset($_SESSION['pending_mailcow_cc_role']);
|
||||
unset($_SESSION['pending_tfa_methods']);
|
||||
|
||||
|
||||
header("Location: /user");
|
||||
}
|
||||
} else {
|
||||
@ -89,27 +89,30 @@ if (isset($_POST["login_user"]) && isset($_POST["pass_user"])) {
|
||||
if ($as == "admin") {
|
||||
$_SESSION['mailcow_cc_username'] = $login_user;
|
||||
$_SESSION['mailcow_cc_role'] = "admin";
|
||||
header("Location: /admin");
|
||||
header("Location: /debug");
|
||||
die();
|
||||
}
|
||||
elseif ($as == "domainadmin") {
|
||||
$_SESSION['mailcow_cc_username'] = $login_user;
|
||||
$_SESSION['mailcow_cc_role'] = "domainadmin";
|
||||
header("Location: /mailbox");
|
||||
die();
|
||||
}
|
||||
elseif ($as == "user") {
|
||||
$_SESSION['mailcow_cc_username'] = $login_user;
|
||||
$_SESSION['mailcow_cc_role'] = "user";
|
||||
$http_parameters = explode('&', $_SESSION['index_query_string']);
|
||||
unset($_SESSION['index_query_string']);
|
||||
if (in_array('mobileconfig', $http_parameters)) {
|
||||
if (in_array('only_email', $http_parameters)) {
|
||||
header("Location: /mobileconfig.php?only_email");
|
||||
die();
|
||||
}
|
||||
header("Location: /mobileconfig.php");
|
||||
die();
|
||||
}
|
||||
$http_parameters = explode('&', $_SESSION['index_query_string']);
|
||||
unset($_SESSION['index_query_string']);
|
||||
if (in_array('mobileconfig', $http_parameters)) {
|
||||
if (in_array('only_email', $http_parameters)) {
|
||||
header("Location: /mobileconfig.php?only_email");
|
||||
die();
|
||||
}
|
||||
header("Location: /mobileconfig.php");
|
||||
die();
|
||||
}
|
||||
header("Location: /user");
|
||||
die();
|
||||
}
|
||||
elseif ($as != "pending") {
|
||||
unset($_SESSION['pending_mailcow_cc_username']);
|
||||
|
@ -58,6 +58,11 @@ $(document).ready(function() {
|
||||
$('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
|
||||
if ($('#tags').length){
|
||||
var tagsEl = $('#tags').parent().find('.tag-values')[0];
|
||||
|
@ -509,7 +509,7 @@ if (isset($_GET['query'])) {
|
||||
print(json_encode($getArgs));
|
||||
$_SESSION['challenge'] = $WebAuthn->getChallenge();
|
||||
return;
|
||||
break;
|
||||
break;
|
||||
case "fail2ban":
|
||||
if (!isset($_SESSION['mailcow_cc_role'])){
|
||||
switch ($object) {
|
||||
@ -2020,6 +2020,9 @@ if (isset($_GET['query'])) {
|
||||
case "rl-mbox":
|
||||
process_edit_return(ratelimit('edit', 'mailbox', array_merge(array('object' => $items), $attr)));
|
||||
break;
|
||||
case "rename-mbox":
|
||||
process_edit_return(mailbox('edit', 'mailbox_rename', array_merge(array('mailbox' => $items), $attr)));
|
||||
break;
|
||||
case "user-acl":
|
||||
process_edit_return(acl('edit', 'user', array_merge(array('username' => $items), $attr)));
|
||||
break;
|
||||
|
@ -641,6 +641,11 @@
|
||||
"mailbox": "Mailbox bearbeiten",
|
||||
"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_rename": "Mailbox umbenennen",
|
||||
"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",
|
||||
"mailbox_rename_title": "Neuer Lokaler Mailbox Name",
|
||||
"max_aliases": "Max. Aliasse",
|
||||
"max_mailboxes": "Max. Mailboxanzahl",
|
||||
"max_quota": "Max. Größe per Mailbox (MiB)",
|
||||
@ -764,7 +769,7 @@
|
||||
"login": "Anmelden",
|
||||
"mobileconfig_info": "Bitte als Mailbox-Benutzer einloggen, um das Verbindungsprofil herunterzuladen.",
|
||||
"new_password": "Neues Passwort",
|
||||
"new_password_confirm": "Neues Passwort bestätigen",
|
||||
"new_password_confirm": "Neues Passwort bestätigen",
|
||||
"other_logins": "Key Login",
|
||||
"password": "Passwort",
|
||||
"reset_password": "Passwort zurücksetzen",
|
||||
@ -1084,6 +1089,7 @@
|
||||
"mailbox_added": "Mailbox %s wurde angelegt",
|
||||
"mailbox_modified": "Änderungen an Mailbox %s wurden gespeichert",
|
||||
"mailbox_removed": "Mailbox %s wurde entfernt",
|
||||
"mailbox_renamed": "Mailbox wurde von %s in %s umbenannt",
|
||||
"nginx_reloaded": "Nginx wurde neu geladen",
|
||||
"object_modified": "Änderungen an Objekt %s wurden gespeichert",
|
||||
"password_policy_saved": "Passwortrichtlinie wurde erfolgreich gespeichert",
|
||||
|
@ -641,6 +641,11 @@
|
||||
"mailbox": "Edit mailbox",
|
||||
"mailbox_quota_def": "Default mailbox quota",
|
||||
"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",
|
||||
"mailbox_rename_title": "New local mailbox name",
|
||||
"max_aliases": "Max. aliases",
|
||||
"max_mailboxes": "Max. possible mailboxes",
|
||||
"max_quota": "Max. quota per mailbox (MiB)",
|
||||
@ -1091,6 +1096,7 @@
|
||||
"mailbox_added": "Mailbox %s has been added",
|
||||
"mailbox_modified": "Changes to mailbox %s have been saved",
|
||||
"mailbox_removed": "Mailbox %s has been removed",
|
||||
"mailbox_renamed": "Mailbox was renamed from %s to %s",
|
||||
"nginx_reloaded": "Nginx was reloaded",
|
||||
"object_modified": "Changes to object %s have been saved",
|
||||
"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="#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="#mrename">⚠️ {{ lang.edit.mailbox_rename }}</button></li>
|
||||
</ul>
|
||||
<hr class="d-none d-md-block">
|
||||
<div class="tab-content">
|
||||
@ -287,10 +288,10 @@
|
||||
<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-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>
|
||||
</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">
|
||||
<table class="table table-condensed" style="white-space: nowrap;" id="mbox_attr_table">
|
||||
<tr>
|
||||
@ -465,10 +466,10 @@
|
||||
{% include 'mailbox/rl-frame.twig' %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="offset-sm-2 col-sm-10">
|
||||
<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="mboxratelimit" data-item="{{ mailbox }}" data-api-url='edit/rl-mbox' data-api-attr='{}' href="#">{{ lang.edit.save }}</button>
|
||||
<p class="text-muted mt-2">{{ lang.edit.mbox_rl_info }}</p>
|
||||
</div>
|
||||
@ -477,6 +478,58 @@
|
||||
</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="col-sm-12 col-md-2">
|
||||
<span>{{ lang.edit.mailbox_rename_title }}</span>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-10 col-xl-8">
|
||||
<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="col-sm-12 offset-md-2 col-md-10 col-xl-8">
|
||||
<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="col-sm-12 offset-md-2 col-md-10 col-xl-8">
|
||||
<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>
|
||||
{% else %}
|
||||
|
@ -535,7 +535,7 @@ services:
|
||||
- watchdog
|
||||
|
||||
dockerapi-mailcow:
|
||||
image: mailcow/dockerapi:2.08
|
||||
image: mailcow/dockerapi:2.09
|
||||
security_opt:
|
||||
- label=disable
|
||||
restart: always
|
||||
|
Loading…
Reference in New Issue
Block a user