mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2024-11-24 08:32:50 +02:00
[Web] Force user pass update via Modal
This commit is contained in:
parent
74b4097ee0
commit
2f401c9fc4
6
data/web/inc/ajax/destroy_pw_update.php
Normal file
6
data/web/inc/ajax/destroy_pw_update.php
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
unset($_SESSION['pending_mailcow_cc_username']);
|
||||||
|
unset($_SESSION['pending_mailcow_cc_role']);
|
||||||
|
unset($_SESSION['pending_pw_update']);
|
||||||
|
?>
|
@ -32,11 +32,11 @@ foreach($_SESSION['pending_tfa_methods'] as $authdata){
|
|||||||
if (isset($pending_tfa_authmechs['webauthn'])) {
|
if (isset($pending_tfa_authmechs['webauthn'])) {
|
||||||
$pending_tfa_authmechs['webauthn'] = true;
|
$pending_tfa_authmechs['webauthn'] = true;
|
||||||
}
|
}
|
||||||
if (!isset($pending_tfa_authmechs['webauthn'])
|
if (!isset($pending_tfa_authmechs['webauthn'])
|
||||||
&& isset($pending_tfa_authmechs['yubi_otp'])) {
|
&& isset($pending_tfa_authmechs['yubi_otp'])) {
|
||||||
$pending_tfa_authmechs['yubi_otp'] = true;
|
$pending_tfa_authmechs['yubi_otp'] = true;
|
||||||
}
|
}
|
||||||
if (!isset($pending_tfa_authmechs['webauthn'])
|
if (!isset($pending_tfa_authmechs['webauthn'])
|
||||||
&& !isset($pending_tfa_authmechs['yubi_otp'])
|
&& !isset($pending_tfa_authmechs['yubi_otp'])
|
||||||
&& isset($pending_tfa_authmechs['totp'])) {
|
&& isset($pending_tfa_authmechs['totp'])) {
|
||||||
$pending_tfa_authmechs['totp'] = true;
|
$pending_tfa_authmechs['totp'] = true;
|
||||||
@ -60,6 +60,7 @@ $globalVariables = [
|
|||||||
),
|
),
|
||||||
'js_path' => '/cache/'.basename($JSPath),
|
'js_path' => '/cache/'.basename($JSPath),
|
||||||
'pending_tfa_methods' => @$_SESSION['pending_tfa_methods'],
|
'pending_tfa_methods' => @$_SESSION['pending_tfa_methods'],
|
||||||
|
'pending_pw_update' => @$_SESSION['pending_pw_update'],
|
||||||
'pending_tfa_authmechs' => $pending_tfa_authmechs,
|
'pending_tfa_authmechs' => $pending_tfa_authmechs,
|
||||||
'pending_mailcow_cc_username' => @$_SESSION['pending_mailcow_cc_username'],
|
'pending_mailcow_cc_username' => @$_SESSION['pending_mailcow_cc_username'],
|
||||||
'lang_footer' => json_encode($lang['footer']),
|
'lang_footer' => json_encode($lang['footer']),
|
||||||
|
@ -905,7 +905,7 @@ function check_login($user, $pass, $app_passwd_data = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate mailbox user
|
// Validate mailbox user
|
||||||
$stmt = $pdo->prepare("SELECT `password` FROM `mailbox`
|
$stmt = $pdo->prepare("SELECT `password`, JSON_UNQUOTE(JSON_EXTRACT(`attributes`, '$.force_pw_update')) AS `force_pw_update` FROM `mailbox`
|
||||||
INNER JOIN domain on mailbox.domain = domain.domain
|
INNER JOIN domain on mailbox.domain = domain.domain
|
||||||
WHERE `kind` NOT REGEXP 'location|thing|group'
|
WHERE `kind` NOT REGEXP 'location|thing|group'
|
||||||
AND `mailbox`.`active`='1'
|
AND `mailbox`.`active`='1'
|
||||||
@ -939,11 +939,17 @@ function check_login($user, $pass, $app_passwd_data = false) {
|
|||||||
$stmt->execute(array(':user' => $user));
|
$stmt->execute(array(':user' => $user));
|
||||||
$rows = array_merge($rows, $stmt->fetchAll(PDO::FETCH_ASSOC));
|
$rows = array_merge($rows, $stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
}
|
}
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
// verify password
|
// verify password
|
||||||
if (verify_hash($row['password'], $pass) !== false) {
|
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
|
// password is not a app password
|
||||||
|
|
||||||
|
// check if pw update is required
|
||||||
|
if (array_key_exists('force_pw_update', $row) && intval($row['force_pw_update']) == 1) {
|
||||||
|
$_SESSION['pending_pw_update'] = True;
|
||||||
|
}
|
||||||
|
|
||||||
// check for tfa authenticators
|
// check for tfa authenticators
|
||||||
$authenticators = get_tfa($user);
|
$authenticators = get_tfa($user);
|
||||||
if (isset($authenticators['additional']) && is_array($authenticators['additional']) && count($authenticators['additional']) > 0 &&
|
if (isset($authenticators['additional']) && is_array($authenticators['additional']) && count($authenticators['additional']) > 0 &&
|
||||||
@ -1028,7 +1034,7 @@ function update_sogo_static_view($mailbox = null) {
|
|||||||
// Check if the mailbox exists
|
// Check if the mailbox exists
|
||||||
$stmt = $pdo->prepare("SELECT username FROM mailbox WHERE username = :mailbox AND active = '1'");
|
$stmt = $pdo->prepare("SELECT username FROM mailbox WHERE username = :mailbox AND active = '1'");
|
||||||
$stmt->execute(array(':mailbox' => $mailbox));
|
$stmt->execute(array(':mailbox' => $mailbox));
|
||||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
if ($row){
|
if ($row){
|
||||||
$mailbox_exists = true;
|
$mailbox_exists = true;
|
||||||
}
|
}
|
||||||
@ -1056,7 +1062,7 @@ function update_sogo_static_view($mailbox = null) {
|
|||||||
LEFT OUTER JOIN grouped_sender_acl_external external_acl ON external_acl.username = mailbox.username
|
LEFT OUTER JOIN grouped_sender_acl_external external_acl ON external_acl.username = mailbox.username
|
||||||
WHERE
|
WHERE
|
||||||
mailbox.active = '1'";
|
mailbox.active = '1'";
|
||||||
|
|
||||||
if ($mailbox_exists) {
|
if ($mailbox_exists) {
|
||||||
$query .= " AND mailbox.username = :mailbox";
|
$query .= " AND mailbox.username = :mailbox";
|
||||||
$stmt = $pdo->prepare($query);
|
$stmt = $pdo->prepare($query);
|
||||||
@ -1065,9 +1071,9 @@ function update_sogo_static_view($mailbox = null) {
|
|||||||
$query .= " GROUP BY mailbox.username";
|
$query .= " GROUP BY mailbox.username";
|
||||||
$stmt = $pdo->query($query);
|
$stmt = $pdo->query($query);
|
||||||
}
|
}
|
||||||
|
|
||||||
$stmt = $pdo->query("DELETE FROM _sogo_static_view WHERE `c_uid` NOT IN (SELECT `username` FROM `mailbox` WHERE `active` = '1');");
|
$stmt = $pdo->query("DELETE FROM _sogo_static_view WHERE `c_uid` NOT IN (SELECT `username` FROM `mailbox` WHERE `active` = '1');");
|
||||||
|
|
||||||
flush_memcached();
|
flush_memcached();
|
||||||
}
|
}
|
||||||
function edit_user_account($_data) {
|
function edit_user_account($_data) {
|
||||||
@ -1079,9 +1085,10 @@ function edit_user_account($_data) {
|
|||||||
!isset($_data_log['user_new_pass2']) ?: $_data_log['user_new_pass2'] = '*';
|
!isset($_data_log['user_new_pass2']) ?: $_data_log['user_new_pass2'] = '*';
|
||||||
!isset($_data_log['user_old_pass']) ?: $_data_log['user_old_pass'] = '*';
|
!isset($_data_log['user_old_pass']) ?: $_data_log['user_old_pass'] = '*';
|
||||||
|
|
||||||
$username = $_SESSION['mailcow_cc_username'];
|
$username = (!empty($_data['username'])) ? $_data['username'] : $_SESSION['mailcow_cc_username'];
|
||||||
$role = $_SESSION['mailcow_cc_role'];
|
$role = (!empty($_data['role'])) ? $_data['role'] : $_SESSION['mailcow_cc_role'];
|
||||||
$password_old = $_data['user_old_pass'];
|
$password_old = $_data['user_old_pass'];
|
||||||
|
$skip_old_password_check = $_data['skip_old_password_check'];
|
||||||
$pw_recovery_email = $_data['pw_recovery_email'];
|
$pw_recovery_email = $_data['pw_recovery_email'];
|
||||||
|
|
||||||
if (filter_var($username, FILTER_VALIDATE_EMAIL === false) || $role != 'user') {
|
if (filter_var($username, FILTER_VALIDATE_EMAIL === false) || $role != 'user') {
|
||||||
@ -1094,22 +1101,24 @@ function edit_user_account($_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// edit password
|
// edit password
|
||||||
if (!empty($password_old) && !empty($_data['user_new_pass']) && !empty($_data['user_new_pass2'])) {
|
if ((!empty($password_old) || $skip_old_password_check) && !empty($_data['user_new_pass']) && !empty($_data['user_new_pass2'])) {
|
||||||
$stmt = $pdo->prepare("SELECT `password` FROM `mailbox`
|
if (!$skip_old_password_check) {
|
||||||
WHERE `kind` NOT REGEXP 'location|thing|group'
|
$stmt = $pdo->prepare("SELECT `password` FROM `mailbox`
|
||||||
AND `username` = :user");
|
WHERE `kind` NOT REGEXP 'location|thing|group'
|
||||||
$stmt->execute(array(':user' => $username));
|
AND `username` = :user");
|
||||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
$stmt->execute(array(':user' => $username));
|
||||||
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
if (!verify_hash($row['password'], $password_old)) {
|
|
||||||
$_SESSION['return'][] = array(
|
if (!verify_hash($row['password'], $password_old)) {
|
||||||
'type' => 'danger',
|
$_SESSION['return'][] = array(
|
||||||
'log' => array(__FUNCTION__, $_data_log),
|
'type' => 'danger',
|
||||||
'msg' => 'access_denied'
|
'log' => array(__FUNCTION__, $_data_log),
|
||||||
);
|
'msg' => 'access_denied'
|
||||||
return false;
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$password_new = $_data['user_new_pass'];
|
$password_new = $_data['user_new_pass'];
|
||||||
$password_new2 = $_data['user_new_pass2'];
|
$password_new2 = $_data['user_new_pass2'];
|
||||||
if (password_check($password_new, $password_new2) !== true) {
|
if (password_check($password_new, $password_new2) !== true) {
|
||||||
@ -1124,7 +1133,7 @@ function edit_user_account($_data) {
|
|||||||
':password_hashed' => $password_hashed,
|
':password_hashed' => $password_hashed,
|
||||||
':username' => $username
|
':username' => $username
|
||||||
));
|
));
|
||||||
|
|
||||||
update_sogo_static_view();
|
update_sogo_static_view();
|
||||||
}
|
}
|
||||||
// edit password recovery email
|
// edit password recovery email
|
||||||
@ -1152,6 +1161,7 @@ function edit_user_account($_data) {
|
|||||||
'log' => array(__FUNCTION__, $_data_log),
|
'log' => array(__FUNCTION__, $_data_log),
|
||||||
'msg' => array('mailbox_modified', htmlspecialchars($username))
|
'msg' => array('mailbox_modified', htmlspecialchars($username))
|
||||||
);
|
);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
function user_get_alias_details($username) {
|
function user_get_alias_details($username) {
|
||||||
global $pdo;
|
global $pdo;
|
||||||
@ -1374,7 +1384,7 @@ function set_tfa($_data) {
|
|||||||
$_data['registration']->certificate,
|
$_data['registration']->certificate,
|
||||||
0
|
0
|
||||||
));
|
));
|
||||||
|
|
||||||
$_SESSION['return'][] = array(
|
$_SESSION['return'][] = array(
|
||||||
'type' => 'success',
|
'type' => 'success',
|
||||||
'log' => array(__FUNCTION__, $_data_log),
|
'log' => array(__FUNCTION__, $_data_log),
|
||||||
@ -1544,7 +1554,7 @@ function unset_tfa_key($_data) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (!is_numeric($id)) $access_denied = true;
|
if (!is_numeric($id)) $access_denied = true;
|
||||||
|
|
||||||
// set access_denied error
|
// set access_denied error
|
||||||
if ($access_denied){
|
if ($access_denied){
|
||||||
$_SESSION['return'][] = array(
|
$_SESSION['return'][] = array(
|
||||||
@ -1553,7 +1563,7 @@ function unset_tfa_key($_data) {
|
|||||||
'msg' => 'access_denied'
|
'msg' => 'access_denied'
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if it's last key
|
// check if it's last key
|
||||||
$stmt = $pdo->prepare("SELECT COUNT(*) AS `keys` FROM `tfa`
|
$stmt = $pdo->prepare("SELECT COUNT(*) AS `keys` FROM `tfa`
|
||||||
@ -1602,7 +1612,7 @@ function get_tfa($username = null, $id = null) {
|
|||||||
WHERE `username` = :username AND `active` = '1'");
|
WHERE `username` = :username AND `active` = '1'");
|
||||||
$stmt->execute(array(':username' => $username));
|
$stmt->execute(array(':username' => $username));
|
||||||
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
// no tfa methods found
|
// no tfa methods found
|
||||||
if (count($results) == 0) {
|
if (count($results) == 0) {
|
||||||
$data['name'] = 'none';
|
$data['name'] = 'none';
|
||||||
@ -1810,8 +1820,8 @@ function verify_tfa_login($username, $_data) {
|
|||||||
'msg' => array('webauthn_authenticator_failed')
|
'msg' => array('webauthn_authenticator_failed')
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($process_webauthn['publicKey']) || $process_webauthn['publicKey'] === false) {
|
if (empty($process_webauthn['publicKey']) || $process_webauthn['publicKey'] === false) {
|
||||||
$_SESSION['return'][] = array(
|
$_SESSION['return'][] = array(
|
||||||
'type' => 'danger',
|
'type' => 'danger',
|
||||||
@ -2173,7 +2183,7 @@ function cors($action, $data = null) {
|
|||||||
'msg' => 'access_denied'
|
'msg' => 'access_denied'
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$allowed_origins = isset($data['allowed_origins']) ? $data['allowed_origins'] : array($_SERVER['SERVER_NAME']);
|
$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;
|
$allowed_origins = !is_array($allowed_origins) ? array_filter(array_map('trim', explode("\n", $allowed_origins))) : $allowed_origins;
|
||||||
@ -2206,7 +2216,7 @@ function cors($action, $data = null) {
|
|||||||
$redis->hMSet('CORS_SETTINGS', array(
|
$redis->hMSet('CORS_SETTINGS', array(
|
||||||
'allowed_origins' => implode(', ', $allowed_origins),
|
'allowed_origins' => implode(', ', $allowed_origins),
|
||||||
'allowed_methods' => implode(', ', $allowed_methods)
|
'allowed_methods' => implode(', ', $allowed_methods)
|
||||||
));
|
));
|
||||||
} catch (RedisException $e) {
|
} catch (RedisException $e) {
|
||||||
$_SESSION['return'][] = array(
|
$_SESSION['return'][] = array(
|
||||||
'type' => 'danger',
|
'type' => 'danger',
|
||||||
@ -2258,10 +2268,10 @@ function cors($action, $data = null) {
|
|||||||
header('Access-Control-Allow-Headers: Accept, Content-Type, X-Api-Key, Origin');
|
header('Access-Control-Allow-Headers: Accept, Content-Type, X-Api-Key, Origin');
|
||||||
|
|
||||||
// Access-Control settings requested, this is just a preflight request
|
// 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_METHOD']) &&
|
||||||
isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) {
|
isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) {
|
||||||
|
|
||||||
$allowed_methods = explode(', ', $cors_settings["allowed_methods"]);
|
$allowed_methods = explode(', ', $cors_settings["allowed_methods"]);
|
||||||
if (in_array($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'], $allowed_methods, true))
|
if (in_array($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'], $allowed_methods, true))
|
||||||
// method allowed send 200 OK
|
// method allowed send 200 OK
|
||||||
@ -2315,7 +2325,7 @@ function reset_password($action, $data = null) {
|
|||||||
break;
|
break;
|
||||||
case 'issue':
|
case 'issue':
|
||||||
$username = $data;
|
$username = $data;
|
||||||
|
|
||||||
// perform cleanup
|
// perform cleanup
|
||||||
$stmt = $pdo->prepare("DELETE FROM `reset_password` WHERE created < DATE_SUB(NOW(), INTERVAL :lifetime MINUTE);");
|
$stmt = $pdo->prepare("DELETE FROM `reset_password` WHERE created < DATE_SUB(NOW(), INTERVAL :lifetime MINUTE);");
|
||||||
$stmt->execute(array(':lifetime' => $PW_RESET_TOKEN_LIFETIME));
|
$stmt->execute(array(':lifetime' => $PW_RESET_TOKEN_LIFETIME));
|
||||||
@ -2397,8 +2407,8 @@ function reset_password($action, $data = null) {
|
|||||||
$request_date = new DateTime();
|
$request_date = new DateTime();
|
||||||
$locale_date = locale_get_default();
|
$locale_date = locale_get_default();
|
||||||
$date_formatter = new IntlDateFormatter(
|
$date_formatter = new IntlDateFormatter(
|
||||||
$locale_date,
|
$locale_date,
|
||||||
IntlDateFormatter::FULL,
|
IntlDateFormatter::FULL,
|
||||||
IntlDateFormatter::FULL
|
IntlDateFormatter::FULL
|
||||||
);
|
);
|
||||||
$formatted_request_date = $date_formatter->format($request_date);
|
$formatted_request_date = $date_formatter->format($request_date);
|
||||||
@ -2514,7 +2524,7 @@ function reset_password($action, $data = null) {
|
|||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':username' => $username
|
':username' => $username
|
||||||
));
|
));
|
||||||
|
|
||||||
$_SESSION['return'][] = array(
|
$_SESSION['return'][] = array(
|
||||||
'type' => 'success',
|
'type' => 'success',
|
||||||
'log' => array(__FUNCTION__, $action, $_data_log),
|
'log' => array(__FUNCTION__, $action, $_data_log),
|
||||||
@ -2557,7 +2567,7 @@ function reset_password($action, $data = null) {
|
|||||||
$text = $data['text'];
|
$text = $data['text'];
|
||||||
$html = $data['html'];
|
$html = $data['html'];
|
||||||
$subject = $data['subject'];
|
$subject = $data['subject'];
|
||||||
|
|
||||||
if (!filter_var($from, FILTER_VALIDATE_EMAIL)) {
|
if (!filter_var($from, FILTER_VALIDATE_EMAIL)) {
|
||||||
$_SESSION['return'][] = array(
|
$_SESSION['return'][] = array(
|
||||||
'type' => 'danger',
|
'type' => 'danger',
|
||||||
@ -2590,7 +2600,7 @@ function reset_password($action, $data = null) {
|
|||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ini_set('max_execution_time', 0);
|
ini_set('max_execution_time', 0);
|
||||||
ini_set('max_input_time', 0);
|
ini_set('max_input_time', 0);
|
||||||
$mail = new PHPMailer;
|
$mail = new PHPMailer;
|
||||||
@ -2622,7 +2632,7 @@ function reset_password($action, $data = null) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$mail->ClearAllRecipients();
|
$mail->ClearAllRecipients();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -10,15 +10,37 @@ if (!empty($_GET['sso_token'])) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (isset($_POST["forced_pw_update"]) && !empty($_POST['new_password']) && !empty($_POST['new_password2'])) {
|
||||||
|
$result = edit_user_account(array(
|
||||||
|
'username' => $_SESSION['pending_mailcow_cc_username'],
|
||||||
|
'role' => $_SESSION['pending_mailcow_cc_role'],
|
||||||
|
'user_new_pass' => $_POST['new_password'],
|
||||||
|
'user_new_pass2' => $_POST['new_password2'],
|
||||||
|
'skip_old_password_check' => True
|
||||||
|
));
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
$_SESSION['mailcow_cc_username'] = $_SESSION['pending_mailcow_cc_username'];
|
||||||
|
$_SESSION['mailcow_cc_role'] = $_SESSION['pending_mailcow_cc_role'];
|
||||||
|
unset($_SESSION['pending_mailcow_cc_username']);
|
||||||
|
unset($_SESSION['pending_mailcow_cc_role']);
|
||||||
|
unset($_SESSION['pending_pw_update']);
|
||||||
|
}
|
||||||
|
|
||||||
|
header("Location: /");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($_POST["pw_reset_request"]) && !empty($_POST['username'])) {
|
if (isset($_POST["pw_reset_request"]) && !empty($_POST['username'])) {
|
||||||
reset_password("issue", $_POST['username']);
|
$resultreset_password("issue", $_POST['username']);
|
||||||
header("Location: /");
|
header("Location: /");
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
if (isset($_POST["pw_reset"])) {
|
if (isset($_POST["pw_reset"])) {
|
||||||
$username = reset_password("check", $_POST['token']);
|
$username = reset_password("check", $_POST['token']);
|
||||||
$reset_result = reset_password("reset", array(
|
$reset_result = reset_password("reset", array(
|
||||||
'new_password' => $_POST['new_password'],
|
'new_password' => $_POST['new_password'],
|
||||||
'new_password2' => $_POST['new_password2'],
|
'new_password2' => $_POST['new_password2'],
|
||||||
'token' => $_POST['token'],
|
'token' => $_POST['token'],
|
||||||
'username' => $username,
|
'username' => $username,
|
||||||
@ -47,13 +69,15 @@ if (isset($_POST["verify_tfa_login"])) {
|
|||||||
header("Location: /");
|
header("Location: /");
|
||||||
exit;
|
exit;
|
||||||
} else {
|
} else {
|
||||||
$_SESSION['mailcow_cc_username'] = $_SESSION['pending_mailcow_cc_username'];
|
if (!$_SESSION['pending_pw_update']) {
|
||||||
$_SESSION['mailcow_cc_role'] = $_SESSION['pending_mailcow_cc_role'];
|
$_SESSION['mailcow_cc_username'] = $_SESSION['pending_mailcow_cc_username'];
|
||||||
unset($_SESSION['pending_mailcow_cc_username']);
|
$_SESSION['mailcow_cc_role'] = $_SESSION['pending_mailcow_cc_role'];
|
||||||
unset($_SESSION['pending_mailcow_cc_role']);
|
unset($_SESSION['pending_mailcow_cc_username']);
|
||||||
unset($_SESSION['pending_tfa_methods']);
|
unset($_SESSION['pending_mailcow_cc_role']);
|
||||||
|
unset($_SESSION['pending_tfa_methods']);
|
||||||
header("Location: /user");
|
|
||||||
|
header("Location: /user");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unset($_SESSION['pending_pw_reset_token']);
|
unset($_SESSION['pending_pw_reset_token']);
|
||||||
@ -97,24 +121,30 @@ if (isset($_POST["login_user"]) && isset($_POST["pass_user"])) {
|
|||||||
header("Location: /mailbox");
|
header("Location: /mailbox");
|
||||||
}
|
}
|
||||||
elseif ($as == "user") {
|
elseif ($as == "user") {
|
||||||
$_SESSION['mailcow_cc_username'] = $login_user;
|
if ($_SESSION['pending_pw_update']) {
|
||||||
$_SESSION['mailcow_cc_role'] = "user";
|
$_SESSION['pending_mailcow_cc_username'] = $login_user;
|
||||||
$http_parameters = explode('&', $_SESSION['index_query_string']);
|
$_SESSION['pending_mailcow_cc_role'] = "user";
|
||||||
unset($_SESSION['index_query_string']);
|
} else {
|
||||||
if (in_array('mobileconfig', $http_parameters)) {
|
$_SESSION['mailcow_cc_username'] = $login_user;
|
||||||
if (in_array('only_email', $http_parameters)) {
|
$_SESSION['mailcow_cc_role'] = "user";
|
||||||
header("Location: /mobileconfig.php?only_email");
|
$http_parameters = explode('&', $_SESSION['index_query_string']);
|
||||||
die();
|
unset($_SESSION['index_query_string']);
|
||||||
}
|
if (in_array('mobileconfig', $http_parameters)) {
|
||||||
header("Location: /mobileconfig.php");
|
if (in_array('only_email', $http_parameters)) {
|
||||||
die();
|
header("Location: /mobileconfig.php?only_email");
|
||||||
|
die();
|
||||||
}
|
}
|
||||||
header("Location: /user");
|
header("Location: /mobileconfig.php");
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
header("Location: /user");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
elseif ($as != "pending") {
|
elseif ($as != "pending") {
|
||||||
unset($_SESSION['pending_mailcow_cc_username']);
|
unset($_SESSION['pending_mailcow_cc_username']);
|
||||||
unset($_SESSION['pending_mailcow_cc_role']);
|
unset($_SESSION['pending_mailcow_cc_role']);
|
||||||
unset($_SESSION['pending_tfa_methods']);
|
unset($_SESSION['pending_tfa_methods']);
|
||||||
|
unset($_SESSION['pending_pw_update']);
|
||||||
unset($_SESSION['mailcow_cc_username']);
|
unset($_SESSION['mailcow_cc_username']);
|
||||||
unset($_SESSION['mailcow_cc_role']);
|
unset($_SESSION['mailcow_cc_role']);
|
||||||
}
|
}
|
||||||
|
@ -211,8 +211,31 @@ function recursiveBase64StrToArrayBuffer(obj) {
|
|||||||
mailcow_alert_box('{{ alert_msg|raw|e("js") }}', '{{ alert_type }}');
|
mailcow_alert_box('{{ alert_msg|raw|e("js") }}', '{{ alert_type }}');
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
// Confirm PW Update modal
|
||||||
|
{% if pending_pw_update %}
|
||||||
|
new bootstrap.Modal(document.getElementById("ConfirmPWUpdateModal"), {
|
||||||
|
backdrop: 'static',
|
||||||
|
keyboard: false
|
||||||
|
}).show();
|
||||||
|
|
||||||
|
$('#ConfirmPWUpdateModal').on('hidden.bs.modal', function(){
|
||||||
|
// cancel pending login
|
||||||
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
cache: false,
|
||||||
|
dataType: 'script',
|
||||||
|
url: '/inc/ajax/destroy_pw_update.php',
|
||||||
|
complete: function(data){
|
||||||
|
window.location = window.location.href.split("#")[0];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
// Confirm TFA modal
|
// Confirm TFA modal
|
||||||
{% if pending_tfa_methods %}
|
{% if pending_tfa_methods %}
|
||||||
new bootstrap.Modal(document.getElementById("ConfirmTFAModal"), {
|
new bootstrap.Modal(document.getElementById("ConfirmTFAModal"), {
|
||||||
backdrop: 'static',
|
backdrop: 'static',
|
||||||
keyboard: false
|
keyboard: false
|
||||||
@ -235,7 +258,7 @@ function recursiveBase64StrToArrayBuffer(obj) {
|
|||||||
$(".totp-authenticator-selection").click(function(){
|
$(".totp-authenticator-selection").click(function(){
|
||||||
$(".totp-authenticator-selection").removeClass("active");
|
$(".totp-authenticator-selection").removeClass("active");
|
||||||
$(this).addClass("active");
|
$(this).addClass("active");
|
||||||
|
|
||||||
var id = $(this).children('input').first().val();
|
var id = $(this).children('input').first().val();
|
||||||
$("#totp_selected_id").val(id);
|
$("#totp_selected_id").val(id);
|
||||||
|
|
||||||
@ -244,7 +267,7 @@ function recursiveBase64StrToArrayBuffer(obj) {
|
|||||||
if ($('.totp-authenticator-selection').length == 1 &&
|
if ($('.totp-authenticator-selection').length == 1 &&
|
||||||
$('#pending_tfa_tab_yubi_otp').length == 0 &&
|
$('#pending_tfa_tab_yubi_otp').length == 0 &&
|
||||||
$('.webauthn-authenticator-selection').length == 0){
|
$('.webauthn-authenticator-selection').length == 0){
|
||||||
|
|
||||||
// select default if only one authenticator exists
|
// select default if only one authenticator exists
|
||||||
$('.totp-authenticator-selection').addClass("active");
|
$('.totp-authenticator-selection').addClass("active");
|
||||||
|
|
||||||
@ -257,7 +280,7 @@ function recursiveBase64StrToArrayBuffer(obj) {
|
|||||||
$('#pending_tfa_tab_totp').on('shown.bs.tab', function() {
|
$('#pending_tfa_tab_totp').on('shown.bs.tab', function() {
|
||||||
// autofocus
|
// autofocus
|
||||||
setTimeout(function() { $("#collapseTotpTFA").find('input[name="token"]').focus(); }, 200);
|
setTimeout(function() { $("#collapseTotpTFA").find('input[name="token"]').focus(); }, 200);
|
||||||
});
|
});
|
||||||
// validate Yubi OTP tfa
|
// validate Yubi OTP tfa
|
||||||
if ($('.webauthn-authenticator-selection').length == 0){
|
if ($('.webauthn-authenticator-selection').length == 0){
|
||||||
// autofocus
|
// autofocus
|
||||||
@ -276,10 +299,10 @@ function recursiveBase64StrToArrayBuffer(obj) {
|
|||||||
$(".webauthn-authenticator-selection").click(function(){
|
$(".webauthn-authenticator-selection").click(function(){
|
||||||
$(".webauthn-authenticator-selection").removeClass("active");
|
$(".webauthn-authenticator-selection").removeClass("active");
|
||||||
$(this).addClass("active");
|
$(this).addClass("active");
|
||||||
|
|
||||||
var id = $(this).children('input').first().val();
|
var id = $(this).children('input').first().val();
|
||||||
$("#webauthn_selected_id").val(id);
|
$("#webauthn_selected_id").val(id);
|
||||||
|
|
||||||
var webauthn_status_auth = document.getElementById('webauthn_status_auth');
|
var webauthn_status_auth = document.getElementById('webauthn_status_auth');
|
||||||
webauthn_status_auth.style.setProperty('display', 'flex', 'important');
|
webauthn_status_auth.style.setProperty('display', 'flex', 'important');
|
||||||
var webauthn_return_code = document.getElementById('webauthn_return_code');
|
var webauthn_return_code = document.getElementById('webauthn_return_code');
|
||||||
@ -302,7 +325,7 @@ function recursiveBase64StrToArrayBuffer(obj) {
|
|||||||
console.log(json);
|
console.log(json);
|
||||||
if (json.success === false) throw new Error();
|
if (json.success === false) throw new Error();
|
||||||
if (json.type === "error") throw new Error(json.msg);
|
if (json.type === "error") throw new Error(json.msg);
|
||||||
|
|
||||||
recursiveBase64StrToArrayBuffer(json);
|
recursiveBase64StrToArrayBuffer(json);
|
||||||
return json;
|
return json;
|
||||||
}).then(getCredentialArgs => {
|
}).then(getCredentialArgs => {
|
||||||
@ -329,7 +352,7 @@ function recursiveBase64StrToArrayBuffer(obj) {
|
|||||||
webauthn_return_code.style.setProperty('display', 'block', 'important');
|
webauthn_return_code.style.setProperty('display', 'block', 'important');
|
||||||
webauthn_return_code.innerHTML = lang_tfa.error_code + ': ' + err + ' ' + lang_tfa.reload_retry;
|
webauthn_return_code.innerHTML = lang_tfa.error_code + ': ' + err + ' ' + lang_tfa.reload_retry;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$('#ConfirmTFAModal').on('hidden.bs.modal', function(){
|
$('#ConfirmTFAModal').on('hidden.bs.modal', function(){
|
||||||
// cancel pending login
|
// cancel pending login
|
||||||
@ -343,7 +366,7 @@ function recursiveBase64StrToArrayBuffer(obj) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
// Validate FIDO2
|
// Validate FIDO2
|
||||||
@ -540,7 +563,7 @@ function recursiveBase64StrToArrayBuffer(obj) {
|
|||||||
Version: <a href="{{ mailcow_info.git_project_url }}/releases/tag/{{ mailcow_info.version_tag }}" target="_blank">{{ mailcow_info.version_tag }}
|
Version: <a href="{{ mailcow_info.git_project_url }}/releases/tag/{{ mailcow_info.version_tag }}" target="_blank">{{ mailcow_info.version_tag }}
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if mailcow_cc_username and mailcow_info.mailcow_branch|lower == "nightly" and mailcow_info.version_tag|default %}
|
{% if mailcow_cc_username and mailcow_info.mailcow_branch|lower == "nightly" and mailcow_info.version_tag|default %}
|
||||||
<span class="version">
|
<span class="version">
|
||||||
🛠️🐮 + 🐋 = 💕
|
🛠️🐮 + 🐋 = 💕
|
||||||
|
@ -139,8 +139,7 @@
|
|||||||
<h3 class="modal-title">{{ lang.tfa.tfa }}</h3>
|
<h3 class="modal-title">{{ lang.tfa.tfa }}</h3>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="modal-body p-0 pt-4">
|
<div class="modal-body p-0 pt-4">
|
||||||
<ul class="nav nav-tabs px-1" id="tabContent">
|
<ul class="nav nav-tabs px-1" id="tabContent">
|
||||||
{% if pending_tfa_authmechs["webauthn"] is defined and pending_tfa_authmechs["u2f"] is not defined %}
|
{% if pending_tfa_authmechs["webauthn"] is defined and pending_tfa_authmechs["u2f"] is not defined %}
|
||||||
@ -241,7 +240,7 @@
|
|||||||
<div role="tabpanel" class="tab-pane {% if pending_tfa_authmechs["totp"] %}active{% endif %}" id="tfa_tab_totp">
|
<div role="tabpanel" class="tab-pane {% if pending_tfa_authmechs["totp"] %}active{% endif %}" id="tfa_tab_totp">
|
||||||
<div class="card border-0" style="margin-bottom: 0px;">
|
<div class="card border-0" style="margin-bottom: 0px;">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form role="form" method="post">
|
<form role="form" method="post">
|
||||||
<legend class="mt-2 mb-2">
|
<legend class="mt-2 mb-2">
|
||||||
<i class="bi bi-shield-fill-check"></i>
|
<i class="bi bi-shield-fill-check"></i>
|
||||||
{{ lang.tfa.authenticators }}
|
{{ lang.tfa.authenticators }}
|
||||||
@ -311,6 +310,29 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if pending_pw_update %}
|
||||||
|
<div class="modal fade" id="ConfirmPWUpdateModal" tabindex="-1" role="dialog" aria-labelledby="ConfirmPWUpdateModalLabel">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h3 class="modal-title">{{ lang.user.change_password }}</h3>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
<form method="post" autofill="off">
|
||||||
|
<input type="password" autocorrect="off" autocapitalize="none" class="form-control mb-2" name="new_password" placeholder="{{ lang.login.new_password }}" />
|
||||||
|
<input type="password" autocorrect="off" autocapitalize="none" class="form-control mb-2" name="new_password2" placeholder="{{ lang.login.new_password_confirm }}" />
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-end mt-4" style="position: relative">
|
||||||
|
<button type="submit" class="btn btn-xs-lg d-block d-sm-inline btn-success" name="forced_pw_update">{{ lang.user.change_password }}</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
{% if mailcow_cc_role == 'admin' %}
|
{% if mailcow_cc_role == 'admin' %}
|
||||||
<div id="RestartContainer" class="modal fade" role="dialog">
|
<div id="RestartContainer" class="modal fade" role="dialog">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
|
Loading…
Reference in New Issue
Block a user