Compare commits

..

1 Commits

Author SHA1 Message Date
FreddleSpl0it 32014dfcec [Web] Add password change acl 2026-05-06 11:01:15 +02:00
13 changed files with 37 additions and 28 deletions
+6 -9
View File
@@ -1,8 +1,7 @@
# Whitelist generated by Postwhite v3.4 on Fri May 1 00:43:37 UTC 2026
# Whitelist generated by Postwhite v3.4 on Wed Apr 1 00:33:31 UTC 2026
# https://github.com/stevejenkins/postwhite/
# 2249 total rules
# 2246 total rules
2a00:1450:4000::/36 permit
2a00:1450:4864::/56 permit
2a01:111:f400::/48 permit
2a01:111:f403:2800::/53 permit
2a01:111:f403:8000::/51 permit
@@ -32,7 +31,6 @@
2a02:a60:0:5::/64 permit
2a0f:f640::/56 permit
2c0f:fb50:4000::/36 permit
2c0f:fb50:4864::/56 permit
2.207.151.32/27 permit
2.207.151.53 permit
2.207.217.30 permit
@@ -62,8 +60,8 @@
8.40.222.0/23 permit
8.40.222.250/31 permit
12.130.86.238 permit
13.107.213.40 permit
13.107.246.40 permit
13.107.213.38 permit
13.107.246.38 permit
13.108.16.0/20 permit
13.110.208.0/21 permit
13.110.209.0/24 permit
@@ -281,7 +279,6 @@
50.56.130.221 permit
50.56.130.222 permit
50.112.246.219 permit
51.83.17.38 permit
52.1.14.157 permit
52.5.230.59 permit
52.6.74.205 permit
@@ -1681,7 +1678,6 @@
169.148.144.0/25 permit
169.148.144.10 permit
169.148.146.0/23 permit
169.148.174.10 permit
169.148.175.3 permit
169.148.179.3 permit
169.148.188.0/24 permit
@@ -2231,7 +2227,6 @@
2001:748:400:3301::4 permit
2404:6800:4000::/36 permit
2404:6800:4864::/56 permit
2603:1061:14:72::1 permit
2607:13c0:0001:0000:0000:0000:0000:7000/116 permit
2607:13c0:0002:0000:0000:0000:0000:1000/116 permit
2607:13c0:0004:0000:0000:0000:0000:0000/116 permit
@@ -2248,6 +2243,8 @@
2620:10d:c09c:400::8:1 permit
2620:119:50c0:207::/64 permit
2620:119:50c0:207::215 permit
2620:1ec:46::38 permit
2620:1ec:bdf::38 permit
2800:3f0:4000::/36 permit
2800:3f0:4864::/56 permit
49.12.4.251 permit # checks.mailcow.email
+8
View File
@@ -1035,6 +1035,14 @@ function edit_user_account($_data) {
// edit password
$is_forced_pw_update = !empty($_SESSION['pending_pw_update']);
if (((!empty($password_old) || $is_forced_pw_update) && !empty($_data['user_new_pass']) && !empty($_data['user_new_pass2']))) {
if (!$is_forced_pw_update && (!isset($_SESSION['acl']['pw_change']) || $_SESSION['acl']['pw_change'] != "1")) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_data_log),
'msg' => 'access_denied'
);
return false;
}
// Only verify old password if this is NOT a forced password update
if (!$is_forced_pw_update) {
$stmt = $pdo->prepare("SELECT `password` FROM `mailbox`
+8 -2
View File
@@ -1331,6 +1331,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$_data['quarantine_notification'] = (in_array('quarantine_notification', $_data['acl'])) ? 1 : 0;
$_data['quarantine_category'] = (in_array('quarantine_category', $_data['acl'])) ? 1 : 0;
$_data['app_passwds'] = (in_array('app_passwds', $_data['acl'])) ? 1 : 0;
$_data['pw_change'] = (in_array('pw_change', $_data['acl'])) ? 1 : 0;
$_data['pw_reset'] = (in_array('pw_reset', $_data['acl'])) ? 1 : 0;
} else {
$_data['spam_alias'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_spam_alias']);
@@ -1347,15 +1348,16 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$_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_change'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_pw_change']);
$_data['pw_reset'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_pw_reset']);
}
try {
$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_change`, `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) ");
:pushover, :quarantine, :quarantine_attachments, :quarantine_notification, :quarantine_category, :app_passwds, :pw_change, :pw_reset) ");
$stmt->execute(array(
':username' => $username,
':spam_alias' => $_data['spam_alias'],
@@ -1372,6 +1374,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
':quarantine_notification' => $_data['quarantine_notification'],
':quarantine_category' => $_data['quarantine_category'],
':app_passwds' => $_data['app_passwds'],
':pw_change' => $_data['pw_change'],
':pw_reset' => $_data['pw_reset']
));
}
@@ -1792,6 +1795,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$attr['acl_quarantine_notification'] = (in_array('quarantine_notification', $_data['acl'])) ? 1 : 0;
$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_change'] = (in_array('pw_change', $_data['acl'])) ? 1 : 0;
$attr['acl_pw_reset'] = (in_array('pw_reset', $_data['acl'])) ? 1 : 0;
} else {
$_data['acl'] = (array)$_data['acl'];
@@ -1809,6 +1813,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$attr['acl_quarantine_notification'] = 0;
$attr['acl_quarantine_category'] = 0;
$attr['acl_app_passwds'] = 0;
$attr['acl_pw_change'] = 0;
}
@@ -3862,6 +3867,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$attr['acl_quarantine_notification'] = (in_array('quarantine_notification', $_data['acl'])) ? 1 : 0;
$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_change'] = (in_array('pw_change', $_data['acl'])) ? 1 : 0;
$attr['acl_pw_reset'] = (in_array('pw_reset', $_data['acl'])) ? 1 : 0;
} else {
foreach ($is_now as $key => $value){
+3 -1
View File
@@ -4,7 +4,7 @@ function init_db_schema()
try {
global $pdo;
$db_version = "19022026_1220";
$db_version = "16042026_1402";
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
@@ -513,6 +513,7 @@ function init_db_schema()
"quarantine_notification" => "TINYINT(1) NOT NULL DEFAULT '1'",
"quarantine_category" => "TINYINT(1) NOT NULL DEFAULT '1'",
"app_passwds" => "TINYINT(1) NOT NULL DEFAULT '1'",
"pw_change" => "TINYINT(1) NOT NULL DEFAULT '1'",
"pw_reset" => "TINYINT(1) NOT NULL DEFAULT '1'",
),
"keys" => array(
@@ -1478,6 +1479,7 @@ function init_db_schema()
"acl_quarantine_notification" => 1,
"acl_quarantine_category" => 1,
"acl_app_passwds" => 1,
"acl_pw_change" => 1,
)
);
$stmt = $pdo->prepare("SELECT id FROM `templates` WHERE `type` = :type AND `template` = :template");
+3
View File
@@ -403,6 +403,9 @@ $(document).ready(function() {
if (template.acl_app_passwds == 1){
acl.push("app_passwds");
}
if (template.acl_pw_change == 1){
acl.push("pw_change");
}
if (template.acl_pw_reset == 1){
acl.push("pw_reset");
}
+1 -13
View File
@@ -1,17 +1,5 @@
{
"acl": {
"login_as": "E-poçt qutusu istifadəçisi olaraq daxil ol",
"alias_domains": "Alternativ domenlər əlavə et",
"app_passwds": "Tətbiq parollarını idarə et",
"bcc_maps": "BCC yönləndirmə xəritələri",
"delimiter_action": "Ayırıcı əməliyyatı",
"domain_desc": "Domen təsvirini dəyiş",
"domain_relayhost": "Domen üçün relay serveri dəyiş",
"eas_reset": "EAS cihazlarını sıfırla",
"extend_sender_acl": "Göndərən ACL-ni xarici ünvanlarla genişləndirməyə icazə ver",
"filters": "Filtrlər",
"mailbox_relayhost": "E-poçt qutusu üçün relay serveri dəyiş",
"prohibited": "ACL tərəfindən məhdudlaşdırılıb",
"protocol_access": "Protokol girişini dəyiş"
"login_as": "E-poçt qutusu istifadəçisi olaraq daxil ol"
}
}
+1
View File
@@ -14,6 +14,7 @@
"prohibited": "Untersagt durch Richtlinie",
"protocol_access": "Ändern der erlaubten Protokolle",
"pushover": "Pushover",
"pw_change": "Passwortänderung erlauben",
"pw_reset": "Verwalten der E-Mail zur Passwortwiederherstellung erlauben",
"quarantine": "Quarantäne-Aktionen",
"quarantine_attachments": "Anhänge aus Quarantäne",
+1
View File
@@ -14,6 +14,7 @@
"prohibited": "Prohibited by ACL",
"protocol_access": "Change protocol access",
"pushover": "Pushover",
"pw_change": "Allow password change",
"pw_reset": "Allow to reset mailcow user password",
"quarantine": "Quarantine actions",
"quarantine_attachments": "Quarantine attachments",
+1 -2
View File
@@ -27,8 +27,7 @@
"tls_policy": "Versleutelingsbeleid",
"unlimited_quota": "Onbeperkte quota voor mailboxen",
"domain_desc": "Wijzig domeinbeschrijving",
"pw_reset": "Toegang om mailcow gebruikers wachtwoord te resetten",
"domain_relayhost": "Verander relayhost voor een domein"
"pw_reset": "Toegang om mailcow gebruikers wachtwoord te resetten"
},
"add": {
"activate_filter_warn": "Alle andere filters worden gedeactiveerd zolang deze geactiveerd is.",
+1 -1
View File
@@ -1226,7 +1226,7 @@
"decimal": ".",
"emptyTable": "Brak danych w tabeli",
"expand_all": "Rozszerz wszystko",
"info": "Wyświetlanie od _START_ do _END_ z _TOTAL_ wpisów",
"info": "Wyświetlanie od START do END z TOTAL wpisów",
"infoEmpty": "Wyświetlanie od 0 do 0 z 0 wpisów",
"infoFiltered": "(filtrowane z _MAX_ suma wpisów)",
"thousands": ",",
@@ -131,6 +131,7 @@
<option value="quarantine_notification" {% if template.attributes.acl_quarantine_notification == '1' %} selected{% endif %}>{{ lang.acl["quarantine_notification"] }}</option>
<option value="quarantine_category" {% if template.attributes.acl_quarantine_category == '1' %} selected{% endif %}>{{ lang.acl["quarantine_category"] }}</option>
<option value="app_passwds" {% if template.attributes.acl_app_passwds == '1' %} selected{% endif %}>{{ lang.acl["app_passwds"] }}</option>
<option value="pw_change" {% if template.attributes.acl_pw_change == '1' %} selected{% endif %}>{{ lang.acl["pw_change"] }}</option>
<option value="pw_reset" {% if template.attributes.acl_pw_reset == '1' %} selected{% endif %}>{{ lang.acl["pw_reset"] }}</option>
</select>
</div>
+1
View File
@@ -172,6 +172,7 @@
<option value="quarantine_notification" selected>{{ lang.acl["quarantine_notification"] }}</option>
<option value="quarantine_category" selected>{{ lang.acl["quarantine_category"] }}</option>
<option value="app_passwds" selected>{{ lang.acl["app_passwds"] }}</option>
<option value="pw_change" selected>{{ lang.acl["pw_change"] }}</option>
<option value="pw_reset" selected>{{ lang.acl["pw_reset"] }}</option>
</select>
</div>
@@ -108,7 +108,9 @@
<div class="row">
<div class="col-12 col-md-3 d-flex"></div>
<div class="col-12 col-md-9 d-flex flex-wrap">
{% if acl.pw_change == 1 %}
<a class="btn btn-secondary" href="#pwChangeModal" data-bs-toggle="modal"><i class="bi bi-pencil-fill"></i> {{ lang.user.change_password }}</a>
{% endif %}
{% if acl.pw_reset == 1 %}
<a class="btn btn-secondary ms-4" href="#pwRecoveryEmailModal" data-bs-toggle="modal"><i class="bi bi-pencil-fill"></i> {{ lang.user.pw_recovery_email }}</a></p>
{% endif %}