1
0
mirror of https://github.com/mailcow/mailcow-dockerized.git synced 2026-05-13 02:52:25 +00:00

[Web] Add forced 2FA setup and password update enforcement

This commit is contained in:
FreddleSpl0it
2026-02-24 10:44:33 +01:00
parent 404e2f0190
commit ad5b94af5e
33 changed files with 810 additions and 285 deletions

View File

@@ -82,7 +82,7 @@ function admin_login($user, $pass){
}
$user = strtolower(trim($user));
$stmt = $pdo->prepare("SELECT `password` FROM `admin`
$stmt = $pdo->prepare("SELECT `password`, `attributes` FROM `admin`
WHERE `superadmin` = '1'
AND `active` = '1'
AND `username` = :user");
@@ -91,6 +91,13 @@ function admin_login($user, $pass){
// verify password
if (verify_hash($row['password'], $pass)) {
$admin_attrs = json_decode($row['attributes'], true) ?? [];
// Check force_pw_update
if (intval($admin_attrs['force_pw_update'] ?? 0) == 1) {
$_SESSION['pending_pw_update'] = true;
}
// check for tfa authenticators
$authenticators = get_tfa($user);
if (isset($authenticators['additional']) && is_array($authenticators['additional']) && count($authenticators['additional']) > 0) {
@@ -110,6 +117,10 @@ function admin_login($user, $pass){
// Reactivate TFA if it was set to "deactivate TFA for next login"
$stmt = $pdo->prepare("UPDATE `tfa` SET `active`='1' WHERE `username` = :user");
$stmt->execute(array(':user' => $user));
// Check force_tfa: only force setup if NO TFA exists at all
if (intval($admin_attrs['force_tfa'] ?? 0) == 1 && !tfa_exists($user)) {
$_SESSION['pending_tfa_setup'] = true;
}
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $user, '*'),
@@ -135,7 +146,7 @@ function domainadmin_login($user, $pass){
return false;
}
$stmt = $pdo->prepare("SELECT `password` FROM `admin`
$stmt = $pdo->prepare("SELECT `password`, `attributes` FROM `admin`
WHERE `superadmin` = '0'
AND `active`='1'
AND `username` = :user");
@@ -144,6 +155,13 @@ function domainadmin_login($user, $pass){
// verify password
if (verify_hash($row['password'], $pass) !== false) {
$admin_attrs = json_decode($row['attributes'], true) ?? [];
// Check force_pw_update
if (intval($admin_attrs['force_pw_update'] ?? 0) == 1) {
$_SESSION['pending_pw_update'] = true;
}
// check for tfa authenticators
$authenticators = get_tfa($user);
if (isset($authenticators['additional']) && is_array($authenticators['additional']) && count($authenticators['additional']) > 0) {
@@ -163,6 +181,10 @@ function domainadmin_login($user, $pass){
// Reactivate TFA if it was set to "deactivate TFA for next login"
$stmt = $pdo->prepare("UPDATE `tfa` SET `active`='1' WHERE `username` = :user");
$stmt->execute(array(':user' => $user));
// Check force_tfa: only force setup if NO TFA exists at all
if (intval($admin_attrs['force_tfa'] ?? 0) == 1 && !tfa_exists($user)) {
$_SESSION['pending_tfa_setup'] = true;
}
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $user, '*'),
@@ -286,6 +308,10 @@ function user_login($user, $pass, $extra = null){
// Reactivate TFA if it was set to "deactivate TFA for next login"
$stmt = $pdo->prepare("UPDATE `tfa` SET `active`='1' WHERE `username` = :user");
$stmt->execute(array(':user' => $user));
// Check force_tfa: only force setup if NO TFA exists at all
if (intval($row['attributes']['force_tfa']) == 1 && !tfa_exists($user)) {
$_SESSION['pending_tfa_setup'] = true;
}
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $user, '*', 'Provider: Keycloak'),
@@ -338,6 +364,10 @@ function user_login($user, $pass, $extra = null){
// Reactivate TFA if it was set to "deactivate TFA for next login"
$stmt = $pdo->prepare("UPDATE `tfa` SET `active`='1' WHERE `username` = :user");
$stmt->execute(array(':user' => $user));
// Check force_tfa: only force setup if NO TFA exists at all
if (intval($row['attributes']['force_tfa']) == 1 && !tfa_exists($user)) {
$_SESSION['pending_tfa_setup'] = true;
}
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $user, '*', 'Provider: LDAP'),
@@ -381,6 +411,10 @@ function user_login($user, $pass, $extra = null){
// Reactivate TFA if it was set to "deactivate TFA for next login"
$stmt = $pdo->prepare("UPDATE `tfa` SET `active`='1' WHERE `username` = :user");
$stmt->execute(array(':user' => $user));
// Check force_tfa: only force setup if NO TFA exists at all
if (intval($row['attributes']['force_tfa']) == 1 && !tfa_exists($user)) {
$_SESSION['pending_tfa_setup'] = true;
}
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $user, '*', 'Provider: mailcow'),