Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge all to 2.x #1323

Open
wants to merge 38 commits into
base: 2.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
28b39ac
Correct sieve connection when using scheme (#1199)
Shadow243 Oct 18, 2024
452652a
Correct imap buttons on servers page & trigger change sieve_mode_tls …
Shadow243 Oct 19, 2024
1b23ba6
[ENH] Added functionality to enable or disable Sieve Filters with tog…
josaphatim Oct 18, 2024
e61afbb
Merge pull request #1289 from Shadow243/imap_sieve_mode_tls
Shadow243 Oct 19, 2024
4da09be
Merge pull request #1104 from amaninyumu1/add-a-toggle-top-activate-d…
kroky Oct 21, 2024
2de1754
Fix some page handlers issues (#1288)
jacob-js Oct 21, 2024
3c4da44
Edit Tag module readme
Shadow243 Oct 21, 2024
8e8b583
Merge pull request #1293 from Shadow243/edit-tags-readme
marclaporte Oct 21, 2024
4b77913
Correct pagination while displaying contacts
Shadow243 Jul 19, 2024
6a646f5
Merge pull request #1125 from Shadow243/correct-contact-group
kroky Oct 22, 2024
5110703
Indicate session-limited actions via a popover (#1295)
jacob-js Oct 22, 2024
ece927d
Fix moving messages between folders via drag-and-drop (#1233)
GedeonTS Oct 22, 2024
a548bdd
Change the frequency at which messages are prefetched (#1297)
jacob-js Oct 23, 2024
729dc43
Inform the world about JMAP and EWS
marclaporte Oct 24, 2024
d8a0eb6
Add a privacy settings section with the external images whitelist config
jacob-js Oct 24, 2024
0fc8416
[FIX]Fix deprecated warnings for preg_match() and mb_strtolower() in …
Baraka24 Oct 14, 2024
f0f478c
WIP: Add sender to the whitelist when the user choses to always allow…
jacob-js Oct 25, 2024
926d3ca
Merge pull request #1281 from Baraka24/fix-deprecated-warnings
kambereBr Oct 27, 2024
d267abe
Fix sieve tls on Quickly add an account from popular E-mail providers
Shadow243 Oct 27, 2024
cf27b9d
Merge pull request #1303 from Shadow243/fixed-nux-service-error
Shadow243 Oct 27, 2024
cc3eb91
Allow the exclusion of certain JS libraries from being bundled when i…
jacob-js Oct 28, 2024
7dcbbfb
The settings are still not saved in the session
jacob-js Oct 28, 2024
cd8cc15
Remove the duplicate of cash.min.js and fix js libs exclusion (#1305)
jacob-js Oct 29, 2024
06330df
The updated privacy setting is saved
jacob-js Oct 30, 2024
b2b62e7
Images are displayed respectively to the whitelist setting
jacob-js Oct 30, 2024
1096095
Merge pull request #1299 from jacob-js/images-whitelist-setting
kroky Oct 31, 2024
abdd8aa
Slight adjustments to the menu on mobile viewports to work properly w…
jacob-js Oct 31, 2024
71967b5
[FIX]Bulk-import accounts using yaml or csv template: Allow both text…
Baraka24 Nov 1, 2024
b4a721d
[FIX]Displaying multiple messages with the same content for a given a…
christer77 Jun 30, 2024
e0881af
[ENH]message list: Preview of message when viewing message list
christer77 Sep 13, 2024
b34489d
Removed forget/save actions
josaphatim Nov 1, 2024
132d526
[FIX].env.example: DISABLE_ORIGIN_CHECK assigns twice
Baraka24 Nov 3, 2024
070976c
Merge pull request #1310 from Baraka24/ajust-MIME-type-check
Shadow243 Nov 3, 2024
77fdde8
Merge pull request #1316 from Baraka24/remove-DISABLE_ORIGIN_CHECK-as…
Shadow243 Nov 3, 2024
508db58
Merge pull request #1311 from josaphatim/removed-save-forgot-server-b…
kroky Nov 4, 2024
8f47ea9
Merge pull request #1241 from christer77/Preview-of-message-when-view…
kroky Nov 4, 2024
ff0b66c
Merge pull request #1106 from christer77/Fix-Displaying-multiple-mess…
kroky Nov 5, 2024
7a4a4d4
Tweak the sidebar for a modern look and feel (#1313)
jacob-js Nov 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ IMAP_AUTH_SERVER=localhost
IMAP_AUTH_PORT=143
IMAP_AUTH_TLS=
IMAP_AUTH_SIEVE_CONF_HOST=
IMAP_AUTH_SIEVE_TLS_MODE=true

DEFAULT_SMTP_NAME=
DEFAULT_SMTP_SERVER=
Expand All @@ -28,8 +29,6 @@ USER_CONFIG_TYPE=file
USER_SETTINGS_DIR=/var/lib/hm3/users
ATTACHMENT_DIR=/var/lib/hm3/attachments

DISABLE_ORIGIN_CHECK=false

ADMIN_USERS=

COOKIE_DOMAIN=
Expand Down Expand Up @@ -74,7 +73,7 @@ ENCRYPT_LOCAL_STORAGE=

DISABLE_IP_CHECK=false

DISABLE_ORIGIN_CHECK=true
DISABLE_ORIGIN_CHECK=false

ALLOW_EXTERNAL_IMAGE_SOURCES=true

Expand Down Expand Up @@ -207,4 +206,6 @@ FANCY_LOGIN=false
#Windows CA certificates
#Get ON https://curl.se/ca/cacert.pem
#Depending on your PHP Directory, e.g. "c:\php\extras\ssl\cacert.pem"
WIN_CACERT_DIR=
WIN_CACERT_DIR=

JS_EXCLUDE_DEPS=
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
#### Cypht
[https://cypht.org](https://cypht.org)

All your E-mail, from all your accounts, in one place. Cypht is like a news
reader, but for E-mail. Cypht does not replace your existing accounts - it
All your email, from all your accounts, in one place. Supports IMAP/SMTP,
[JMAP](https://github.com/cypht-org/cypht/issues/180) and
[soon EWS](https://github.com/cypht-org/cypht/issues/247). Cypht is like a
news reader, but for E-mail. Cypht does not replace your existing accounts - it
combines them into one. And it's also a news reader.

![screenshot](https://github.com/cypht-org/cypht-website/blob/master/img/Inbox.PNG "Inbox View").
Expand Down
14 changes: 12 additions & 2 deletions config/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,18 @@
/*
|
| The hostname/IP address and port sieve is listening on. Example: example.org:4190
| Note: Add tls:// prefix to enable explicit STARTTLS
| Keep this blank to disable sieve filter support on login
|
*/
'imap_auth_sieve_conf_host' => env('IMAP_AUTH_SIEVE_CONF_HOST', 'tls://mail.gandi.net:4190'),
'imap_auth_sieve_conf_host' => env('IMAP_AUTH_SIEVE_CONF_HOST', ''),

/*
|
| this will add the tls:// prefix to the sieve host if set to true
| to make this work make sure you set DEFAULT_SETTING_ENABLE_SIEVE_FILTER to true
|
*/
'imap_auth_sieve_tls_mode' => env('IMAP_AUTH_SIEVE_TLS_MODE', true),

/*
| -------------------
Expand Down Expand Up @@ -1309,4 +1317,6 @@
| Use this setting switch between the legacy login page and the fancy one
*/
'fancy_login' => env('FANCY_LOGIN', false),

'js_exclude_deps' => env('JS_EXCLUDE_DEPS', ''),
];
7 changes: 5 additions & 2 deletions lib/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ class Hm_Auth_IMAP extends Hm_Auth {
public function __construct($config) {
$this->site_config = $config;
require_once APP_PATH.'modules/imap/hm-imap.php';
include_once APP_PATH.'modules/sievefilters/hm-sieve.php';
}

/* IMAP authentication server settings */
Expand Down Expand Up @@ -194,7 +195,7 @@ private function check_connection($imap) {
*/
public function check_credentials($user, $pass) {
$imap = new Hm_IMAP();
list($server, $port, $tls, $sieve_config) = get_auth_config($this->site_config, 'imap');
list($server, $port, $tls, $sieve_config, $sieve_tls_mode) = get_auth_config($this->site_config, 'imap');
if (!$user || !$pass || !$server || !$port) {
Hm_Debug::add($imap->show_debug(true));
Hm_Debug::add('Invalid IMAP auth configuration settings');
Expand All @@ -203,7 +204,8 @@ public function check_credentials($user, $pass) {
$this->imap_settings = ['server' => $server, 'port' => $port,
'tls' => $tls, 'username' => $user, 'password' => $pass,
'no_caps' => false, 'blacklisted_extensions' => ['enable'],
'sieve_config_host' => $sieve_config
'sieve_config_host' => $sieve_config,
'sieve_tls' => $sieve_tls_mode
];
return $this->check_connection($imap);
}
Expand Down Expand Up @@ -319,6 +321,7 @@ function get_auth_config($config, $prefix) {
$ret = [$server, $port, $tls];
if ($prefix == 'imap') {
$ret[] = $config->get($prefix.'_auth_sieve_conf_host', false);
$ret[] = $config->get($prefix.'_auth_sieve_tls_mode', false);
}
return $ret;
}
1 change: 1 addition & 0 deletions lib/framework.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
require APP_PATH.'lib/servers.php';
require APP_PATH.'lib/api.php';
require APP_PATH.'lib/webdav_formats.php';
require APP_PATH.'lib/js_libs.php';

require_once APP_PATH.'modules/core/functions.php';

Expand Down
32 changes: 32 additions & 0 deletions lib/js_libs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

define('JS_LIBS', [
'bootstrap' => 'vendor/twbs/bootstrap/dist/js/bootstrap.bundle.min.js',
'cash' => 'third_party/cash.min.js',
'resumable' => 'third_party/resumable.min.js',
'ays-beforeunload-shim' => 'third_party/ays-beforeunload-shim.js',
'jquery-are-you-sure' => 'third_party/jquery.are-you-sure.js',
'sortable' => 'third_party/sortable.min.js'
]);

function get_js_libs($exclude_deps = []) {
$js_lib = '';

foreach (JS_LIBS as $dep) {
if (!in_array($dep, $exclude_deps)) {
$js_lib .= '<script type="text/javascript" src="'.WEB_ROOT.$dep.'"></script>';
}
}
return $js_lib;
}

function get_js_libs_content($exclude_deps = []) {
$js_lib = '';

foreach (JS_LIBS as $key => $dep) {
if (!in_array($key, $exclude_deps)) {
$js_lib .= file_get_contents(APP_PATH.$dep);
}
}
return $js_lib;
}
20 changes: 14 additions & 6 deletions lib/module.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,22 @@ trait Hm_Handler_Validate {
* @return bool
*/
public function validate_method($session, $request) {
if (!in_array(mb_strtolower($request->method), ['get', 'post'], true)) {
if ($session->loaded) {
$session->destroy($request);
Hm_Debug::add(sprintf('LOGGED OUT: invalid method %s', $request->method));
if (!empty($request->method) && is_string($request->method)) {
if (!in_array(mb_strtolower($request->method), ['get', 'post'], true)) {
if ($session->loaded) {
$session->destroy($request);
Hm_Debug::add(sprintf('LOGGED OUT: invalid method %s', $request->method));
}
return false;
}
return false;
return true;
}
return true;
// Handle the case where method is null or invalid
if ($session->loaded) {
$session->destroy($request);
Hm_Debug::add('LOGGED OUT: missing or invalid request method');
}
return false;
}

/**
Expand Down
3 changes: 2 additions & 1 deletion lib/modules_exec.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ public function merge_response($request, $session, $page) {
'router_login_state' => $session->is_active(),
'router_url_path' => $request->path,
'router_module_list' => $this->site_config->get_modules(),
'router_app_name' => $this->site_config->get('app_name', 'HM3')
'router_app_name' => $this->site_config->get('app_name', 'HM3'),
'router_js_exclude_deps' => $this->site_config->get('js_exclude_deps'),
));
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/request.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ private function is_mobile() {
$this->mobile = true;
return;
}
if (array_key_exists('HTTP_USER_AGENT', $this->server)) {
if (!empty($this->server['HTTP_USER_AGENT'])) {
if (preg_match("/(iphone|ipod|ipad|android|blackberry|webos|opera mini)/i", $this->server['HTTP_USER_AGENT'])) {
$this->mobile = true;
}
Expand Down
2 changes: 1 addition & 1 deletion modules/account/modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ protected function output() {
if ($this->get('internal_users')) {
$res = '<li class="menu_change_password"><a class="unread_link" href="?page=change_password">';
if (!$this->get('hide_folder_icons')) {
$res .= '<i class="bi bi-key-fill fs-5 me-2"></i>';
$res .= '<i class="bi bi-key-fill menu-icon"></i>';
}
$res .= $this->trans('Password').'</a></li>';
$this->concat('formatted_folder_list', $res);
Expand Down
2 changes: 1 addition & 1 deletion modules/calendar/modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class Hm_Output_calendar_page_link extends Hm_Output_Module {
protected function output() {
$res = '<li class="menu_calendar"><a class="unread_link" href="?page=calendar">';
if (!$this->get('hide_folder_icons')) {
$res .= '<i class="bi bi-calendar-week-fill fs-5 me-2"></i>';
$res .= '<i class="bi bi-calendar-week-fill menu-icon"></i>';
}
$res .= $this->trans('Calendar').'</a></li>';
if ($this->format == 'HTML5') {
Expand Down
56 changes: 54 additions & 2 deletions modules/contacts/hm-contacts.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,65 @@ public function reset() {
$this->data = array();
}

public function page($page, $size) {
public function page($page, $size, $data = null) {
if ($page < 1) {
return array();
}
return array_slice($this->data, (($page - 1)*$size), $size, true);
if ($data === null) {
$data = $this->data;
}
return array_slice($data, (($page - 1)*$size), $size, true);
}

public function group_by($column = 'group') {
if (!is_string($column) && !is_int($column) && !is_float($column)) {
trigger_error('group_by(): The key should be a string, an integer, or a float', E_USER_ERROR);
return null;
}

$_key = $column;
$grouped = [];
$defaultGroup = 'Collected Recipients';

foreach ($this->data as $value) {
$columnValue = null;

if (is_array($value) && isset($value[$_key])) {
$columnValue = $value[$_key];
}
elseif (is_object($value) && method_exists($value, 'value') && $value->value($_key)) {
$columnValue = $value->value($_key);
}

if ($columnValue === null) {
$columnValue = $defaultGroup;
}

$grouped[$columnValue][] = $value;
}

if (func_num_args() > 1) {
$args = func_get_args();
foreach ($grouped as $key => $values) {
$params = array_merge([ $values ], array_slice($args, 1));
$grouped[$key] = call_user_func_array([ $this, 'group_by' ], $params);
}
}

return $grouped;
}



public function paginate_grouped($column, $page, $size) {
$grouped = $this->group_by($column);
$paginated = [];
foreach ($grouped as $key => $group) {
$paginated[$key] = $this->page($page, $size, $group);
}
return $paginated;
}

public function sort($fld) {
$this->sort_fld = $fld;
uasort($this->data, array($this, 'sort_callback'));
Expand Down
Loading