Skip to content

Commit 8f86948

Browse files
committed
Merge remote-tracking branch 'origin/master' into feature/emoji-reactions
2 parents 6a1795f + 0847b37 commit 8f86948

File tree

13 files changed

+120
-67
lines changed

13 files changed

+120
-67
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"ezyang/htmlpurifier": "^4.17",
4949
"garethp/php-ews": "dev-master",
5050
"henrique-borba/php-sieve-manager": "^1.0",
51-
"league/commonmark": "^2.4",
51+
"league/commonmark": "^2.7",
5252
"paragonie/random_compat": "^2.0.18",
5353
"php": ">=8.1",
5454
"react/async": "^4.3.0",

composer.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

modules/core/handler_modules.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1163,7 +1163,7 @@ public function process() {
11631163
$this->out('imap_service_name', $provider);
11641164
}
11651165
$this->out('just_saved_credentials', true);
1166-
Hm_Msgs::add("Server saved");
1166+
Hm_Msgs::add("Server saved. To preserve these settings after logout, please go to <a class='alert-link' href='/?page=save'>Save Settings</a>.");
11671167
}
11681168

11691169
if ($createProfile && $this->smtp_server_id && ($this->imap_server_id || $this->jmap_server_id)) {

modules/core/output_modules.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ protected function output() {
1818
$res = '<li class="menu_search mb-2"><form method="get">';
1919
$res .= '<div class="input-group">';
2020
if (!$this->get('hide_folder_icons')) {
21-
$res .= '<a href="?page=search" class="input-group-text" id="basic-addon1">' .
21+
$res .= '<a href="?page=search" class="input-group-text" id="basic-addon1">' .
2222
'<i class="bi bi-search"></i>' .
2323
'</a>';
2424
}
@@ -635,7 +635,7 @@ protected function output() {
635635
format_data_sources($this->get('data_sources', array()), $this);
636636

637637
if (!$this->get('disable_delete_prompt', DEFAULT_DISABLE_DELETE_PROMPT)) {
638-
$res .= 'var hm_delete_prompt = function() { return confirm("'.$this->trans('Are you sure?').'"); };';
638+
$res .= 'var hm_delete_prompt = function() { return confirm("'.$this->trans('Are you sure you wanto to delete this server?').'"); };';
639639
}
640640
else {
641641
$res .= 'var hm_delete_prompt = function() { return true; };';
@@ -1686,9 +1686,9 @@ protected function output() {
16861686
$share_folder_modal .= '</thead>';
16871687
$share_folder_modal .= '<tbody></tbody>';
16881688
$share_folder_modal .= '</table>';
1689-
1689+
16901690
$share_folder_modal .= '</div>';
1691-
1691+
16921692
$share_folder_modal .= '<div class="col-lg-4 col-md-12">';
16931693
$share_folder_modal .= '<form id="shareForm" action="" method="POST">';
16941694
$share_folder_modal .= '<input type="hidden" name="server_id" id="server_id" value="">';

modules/core/site.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ class Hm_Alert {
427427

428428
const messageElement = document.createElement('div');
429429
messageElement.className = 'flex-grow-1 pe-4';
430-
messageElement.textContent = message;
430+
messageElement.innerHTML = message;
431431

432432
alert.appendChild(iconContainer);
433433
alert.appendChild(messageElement);

modules/imap/functions.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ function format_imap_folder_section($folders, $id, $output_mod, $with_input = fa
135135

136136
foreach ($folders as $folder_name => $folder) {
137137
$folder_name = bin2hex($folder_name);
138-
$results .= '<li class="imap_'.$id.'_'.$output_mod->html_safe($folder_name).'">';
138+
$results .= '<li class="imap_'.$id.'_'.$output_mod->html_safe($folder_name).'" data-number-children="'.$output_mod->html_safe($folder['number_of_children']).'">';
139139
if ($folder['children']) {
140140
$results .= '<a href="#" class="imap_folder_link expand_link d-inline-flex" data-target="imap_'.$id.'_'.$output_mod->html_safe($folder_name).'"><i class="bi bi-plus-circle-fill"></i></a>';
141141
}

modules/imap/handler_modules.php

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ public function process() {
734734

735735
if ($ceo_use_detect_ceo_fraud && hex2bin($form['folder']) == 'INBOX') {
736736
if ($this->isCeoFraud($msg['to'], $msg['subject'], $msg['preview_msg'])) {
737-
737+
738738
$folder = "Suspicious emails";
739739
if (!count($mailbox->get_mailbox_status($folder))) {
740740
$mailbox->create_folder($folder);
@@ -750,7 +750,7 @@ public function process() {
750750
$total--;
751751
}
752752
}
753-
753+
754754
if ($msg) {
755755
if (! $include_preview && isset($msg['preview_msg'])) {
756756
$msg['preview_msg'] = "";
@@ -770,18 +770,18 @@ public function process() {
770770
$this->out('do_not_flag_as_read_on_open', $this->user_config->get('unread_on_open_setting', false));
771771
}
772772
}
773-
public function isCeoFraud($email, $subject, $msg) {
773+
public function isCeoFraud($email, $subject, $msg) {
774774
// 1. Check Suspicious Terms or Requests
775775
$suspiciousTerms = explode(",", $this->user_config->get("ceo_suspicious_terms_setting"));
776776
if ($this->detectSuspiciousTerms($msg, $suspiciousTerms) || $this->detectSuspiciousTerms($subject, $suspiciousTerms)) {
777-
777+
778778
// 2. check ceo_rate_limit
779779
$amounts = $this->extractAmountFromEmail($msg);
780780
$amountLimit = $this->user_config->get("ceo_amount_limit_setting");
781781
$isUpperAmount = array_reduce($amounts, function ($carry, $value) use ($amountLimit) {
782782
return $carry || $value > $amountLimit;
783783
}, false);
784-
784+
785785
if ($isUpperAmount) {
786786
if ($this->user_config->get("ceo_use_trusted_contact_setting")) {
787787
$contacts = $this->get('contact_store');
@@ -815,16 +815,16 @@ private function isEmailInTrustedDomainList($trustedDomain, $email) {
815815
}
816816
private function extractAmountFromEmail($emailBody) {
817817
$pattern = '/\b\d+(?:,\d+)?\.?\d*\s*(?:USD|dollars?|US\$?|EUR|euros?|€|JPY|yen|¥|GBP|pounds?|£|CAD|CAD\$|AUD|AUD\$)/i';
818-
818+
819819
preg_match_all($pattern, $emailBody, $matches);
820-
820+
821821
if ($matches) {
822-
return array_map(function($value) {
823-
return floatval(preg_replace('/[^0-9]/', '', $value));
822+
return array_map(function($value) {
823+
return floatval(preg_replace('/[^0-9]/', '', $value));
824824
}, $matches[0]);
825825
}
826826
}
827-
827+
828828
}
829829

830830
/**
@@ -1135,7 +1135,7 @@ public function process() {
11351135
* @param string $folder The folder where the messages currently reside.
11361136
* @param array $specials Special folder information for handling specific actions.
11371137
* @param array $server_details Details of the server, including its unique ID and settings.
1138-
*
1138+
*
11391139
* @return array Returns an associative array with:
11401140
* - 'error' => bool Indicates if an error occurred during the operation.
11411141
* - 'moved' => array List of moved message identifiers in a specific format.
@@ -1182,7 +1182,7 @@ private function perform_action($mailbox, $action_type, $uids, $folder, $special
11821182
* @param string $action_type The action type that determines which special folder to retrieve (e.g., 'delete', 'archive').
11831183
* @param array $specials An associative array of special folder names, like 'trash', 'archive', and 'junk'.
11841184
* @param array $server_details Details of the server, including its name.
1185-
*
1185+
*
11861186
* @return string|false Returns the special folder name if found, or false if no corresponding folder is configured.
11871187
*/
11881188
private function get_special_folder($action_type, $specials, $server_details) {
@@ -1273,7 +1273,7 @@ public function process() {
12731273
$offset = 0;
12741274
$list_page = 1;
12751275
$maxPerSource = round($limit / count($data_sources));
1276-
1276+
12771277
if (isset($this->request->get['list_page'])) {
12781278
$list_page = (int) $this->request->get['list_page'];
12791279
if ($list_page && $list_page > 1) {
@@ -1373,7 +1373,7 @@ public function process() {
13731373
$offsets = explode(',', $offsets);
13741374
}
13751375
$searchTerms[] = [search_since_based_on_setting($this->user_config), $date];
1376-
1376+
13771377
$result = getCombinedMessagesLists($data_sources, [
13781378
'cache' => $this->cache,
13791379
'session' => $this->session,
@@ -1463,7 +1463,7 @@ public function process() {
14631463
'type' => 'jmap',
14641464
'port' => false,
14651465
'tls' => false));
1466-
Hm_Msgs::add('Added server!');
1466+
Hm_Msgs::add("Added server!. To preserve these settings after logout, please go to <a class='alert-link' href='/?page=save'>Save Settings</a>.");
14671467
$this->session->record_unsaved('JMAP server added');
14681468
}
14691469
else {
@@ -1693,12 +1693,12 @@ class Hm_Handler_load_imap_folders_permissions extends Hm_Handler_Module {
16931693
*/
16941694
public function process() {
16951695
list($success, $form) = $this->process_form(array('imap_server_id','imap_folder_uid','imap_folder'));
1696-
1696+
16971697
if ($success && !empty($form['imap_server_id']) && !empty($form['imap_folder']) && !empty($form['imap_folder_uid'])) {
16981698
Hm_IMAP_List::init($this->user_config, $this->session);
16991699
$server = Hm_IMAP_List::dump($form['imap_server_id'], true);
17001700
$cache = Hm_IMAP_List::get_cache($this->cache, $form['imap_server_id']);
1701-
1701+
17021702
$imap = Hm_IMAP_List::connect($form['imap_server_id'], $cache, $server['user'], $server['pass']);
17031703
$permissions = $imap->get_acl($form['imap_folder']);
17041704
$this->out('imap_folders_permissions', $permissions);
@@ -1716,13 +1716,13 @@ class Hm_Handler_set_acl_to_imap_folders extends Hm_Handler_Module {
17161716
*/
17171717
public function process() {
17181718
list($success, $form) = $this->process_form(array('imap_server_id','imap_folder','identifier','permissions','action'));
1719-
1719+
17201720
if ($success && !empty($form['imap_server_id']) && !empty($form['identifier']) && !empty($form['permissions']) && !empty($form['action'])) {
17211721

17221722
Hm_IMAP_List::init($this->user_config, $this->session);
17231723
$server = Hm_IMAP_List::dump($form['imap_server_id'], true);
17241724
$cache = Hm_IMAP_List::get_cache($this->cache, $form['imap_server_id']);
1725-
1725+
17261726
$imap = Hm_IMAP_List::connect($form['imap_server_id'], $cache, $server['user'], $server['pass']);
17271727
if($form['action'] === 'add') {
17281728
$response = $imap->set_acl($form['imap_folder'], $form['identifier'], $form['permissions']);
@@ -1903,7 +1903,7 @@ public function process() {
19031903
if (isset($this->request->post['imap_connect'])) {
19041904
list($success, $form) = $this->process_form(array('imap_server_id'));
19051905
$imap_details = Hm_IMAP_List::dump($form['imap_server_id'], true);
1906-
if ($success && $imap_details) {
1906+
if ($success && $imap_details) {
19071907
if ($this->module_is_supported('sievefilters') && $this->user_config->get('enable_sieve_filter_setting', DEFAULT_ENABLE_SIEVE_FILTER)) {
19081908
try {
19091909
list($sieve_host, $sieve_port) = parse_sieve_config_host($imap_details['sieve_config_host']);
@@ -2325,9 +2325,15 @@ public function process() {
23252325
if (isset($this->request->post['hide_imap_server'])) {
23262326
list($success, $form) = $this->process_form(array('imap_server_id'));
23272327
if ($success) {
2328-
Hm_IMAP_List::toggle_hidden($form['imap_server_id'], (bool) $this->request->post['hide_imap_server']);
2329-
Hm_Msgs::add('Hidden status updated');
2330-
$this->session->record_unsaved(sprintf('%s server hidden status updated', imap_server_type($form['imap_server_id'])));
2328+
$action = (bool) $this->request->post['hide_imap_server'];
2329+
$server_type = imap_server_type($form['imap_server_id']);
2330+
Hm_IMAP_List::toggle_hidden($form['imap_server_id'], $action);
2331+
if ($action) {
2332+
Hm_Msgs::add(sprintf('%s server has been hidden', $server_type));
2333+
} else {
2334+
Hm_Msgs::add(sprintf('%s server is now visible', $server_type));
2335+
}
2336+
$this->session->record_unsaved(sprintf('%s server visibility updated', $server_type));
23312337
}
23322338
}
23332339
}
@@ -2495,7 +2501,7 @@ function process_ceo_use_detect_ceo_fraud_callback($val) { return $val; }
24952501
function process_ceo_use_trusted_contact_callback($val) { return $val; }
24962502
function process_ceo_suspicious_terms_callback($val) { return $val; }
24972503
function process_ceo_amount_limit_callback($val) { return $val; }
2498-
2504+
24992505
process_site_setting('ceo_use_detect_ceo_fraud', $this, 'process_ceo_use_detect_ceo_fraud_callback');
25002506
process_site_setting('ceo_use_trusted_contact', $this, 'process_ceo_use_trusted_contact_callback');
25012507
process_site_setting('ceo_suspicious_terms', $this, 'process_ceo_suspicious_terms_callback');

modules/imap/hm-imap.php

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ class Hm_IMAP extends Hm_IMAP_Cache {
182182
public $folder_state = false;
183183
private $scramAuthenticator;
184184
private $namespace_count = 0;
185+
186+
protected $list_sub_folders = [];
185187
/**
186188
* constructor
187189
*/
@@ -1923,16 +1925,31 @@ public function delete_mailbox($mailbox) {
19231925
$this->debug[] = 'Delete mailbox not permitted in read only mode';
19241926
return false;
19251927
}
1926-
$command = 'DELETE "'.str_replace('"', '\"', $this->utf7_encode($mailbox))."\"\r\n";
1927-
$this->send_command($command);
1928-
$result = $this->get_response(false);
1929-
$status = $this->check_response($result, false);
1930-
if ($status) {
1931-
return true;
1928+
$this->list_sub_folders[] = $mailbox;
1929+
$this->get_recursive_subfolders($mailbox, true);
1930+
$this->list_sub_folders = array_reverse($this->list_sub_folders);
1931+
foreach ($this->list_sub_folders as $key => $del_folder) {
1932+
$command = 'DELETE "'.str_replace('"', '\"', $this->utf7_encode($del_folder))."\"\r\n";
1933+
$this->send_command($command);
1934+
$result = $this->get_response(false);
1935+
$status = $this->check_response($result, false);
1936+
if ($status) {
1937+
unset($this->list_sub_folders[$key]);
1938+
} else {
1939+
$this->debug[] = str_replace('A'.$this->command_count, '', $result[0]);
1940+
return false;
1941+
}
19321942
}
1933-
else {
1934-
$this->debug[] = str_replace('A'.$this->command_count, '', $result[0]);
1935-
return false;
1943+
return true;
1944+
}
1945+
1946+
public function get_recursive_subfolders($parentFolder, $is_delete_action) {
1947+
$infoFolder = $this->get_folder_list_by_level($parentFolder, false, false, $is_delete_action);
1948+
if ($infoFolder) {
1949+
foreach (array_keys($infoFolder) as $folder) {
1950+
$this->list_sub_folders[] = $folder;
1951+
$this->get_recursive_subfolders($folder, $is_delete_action);
1952+
}
19361953
}
19371954
}
19381955

@@ -2669,7 +2686,7 @@ public function get_mailbox_page($mailbox, $sort, $rev, $filter, $offset=0, $lim
26692686
* @param string $level mailbox name or empty string for the top level
26702687
* @return array list of matching folders
26712688
*/
2672-
public function get_folder_list_by_level($level='', $only_subscribed=false, $with_input = false) {
2689+
public function get_folder_list_by_level($level='', $only_subscribed=false, $with_input = false, $is_delete_action = false) {
26732690
$result = array();
26742691
$folders = array();
26752692
if ($this->server_support_children_capability()) {
@@ -2692,6 +2709,9 @@ public function get_folder_list_by_level($level='', $only_subscribed=false, $wit
26922709
if ($with_input) {
26932710
$result[$name]['special'] = $folder['special'];
26942711
}
2712+
if ($folder['can_have_kids'] && !$is_delete_action) {
2713+
$result[$name]['number_of_children'] = count($this->get_folder_list_by_level($folder['name'], false, false, $is_delete_action));
2714+
}
26952715
}
26962716
if ($only_subscribed || $with_input) {
26972717
$subscribed_folders = array_column($this->get_mailbox_list(true, children_capability:$this->server_support_children_capability()), 'name');

modules/imap_folders/modules.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ protected function output() {
422422
<a href="#" class="close">'.$this->trans('Cancel').'</a>
423423
</li>
424424
</ul>
425+
<input type="hidden" value="" id="children_number" />
425426
<input type="hidden" value="" id="delete_source" />
426427
<input type="button" id="delete_folder" class="btn btn-danger" value="'.$this->trans('Delete').'">
427428
</div></div>';

0 commit comments

Comments
 (0)