diff --git a/CHANGELOG.md b/CHANGELOG.md index d5672b9d5..69d6bd9cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,31 @@ This file documents all notable changes made to ITFlow. +## [26.07] + +### Major Changes +- Migrated from Webklex php Library to IMAPEngine. +- Major Rewrite of the mail settings page to better support Microsoft 365 and Google OAUTH2. + +### Bug fixes +- Many Security Fixes. +- Microsoft 365 and Google can now specify Licensed User. +- Clients - Only show 3 Tags per line instead of streching all the way across. +- Login: Make Email field email type instead of text. +- Fixed Invoice Late Overdue notices now shows correct balance when late fees are attached and if partial invoice was paid. +- User Preferences Avatar: Fix creating user upload directory if doesn't exist, and remove Avatar now properly deletes the old avatar image. +- Do not send an in-app alert on successful cron execution, keep it in logging only. +- Fix Issues with Clients Signing in via Entra in the client Portal, items were broken because CSRF token was not being generated. + +### New Features & Updates +- Clients: Removed Entity Stat Counter was slow and unused. +- Added Monospace text in areas where it deserves it like, IPs, Amounts Costs in Tabular data forms etc. +- Cicking into the client section no longer turns the main nav and text gray, it keeps the configured theme across the app. It was implmented long ago to differentiate between the client section and the main section of ITFLow but didn't work very well. +- Bump Sortablejs from 1.15.6 to 1.15.7. +- Bump TinyMCE from 8.5.0 to 8.6.0. +- Bump Fullcalendar from 6.1.20 to 7.0.0 amd convert existing code to comply with 7.0, also make calendar more printable. +- Bump PHPMailer from 7.0.2 to 7.1.1. + ## [26.05.1] Stable Release - Security Fixes. diff --git a/admin/app_log.php b/admin/app_log.php index 9b6ba812a..a50c6d5be 100644 --- a/admin/app_log.php +++ b/admin/app_log.php @@ -151,7 +151,7 @@ ?> - + diff --git a/admin/audit_log.php b/admin/audit_log.php index 928264d56..0cb9a32aa 100644 --- a/admin/audit_log.php +++ b/admin/audit_log.php @@ -254,7 +254,7 @@ ?> - + @@ -262,7 +262,7 @@ - + $log_user_browser"; ?> diff --git a/admin/mail_queue.php b/admin/mail_queue.php index af0995a3d..0bddb5a5f 100644 --- a/admin/mail_queue.php +++ b/admin/mail_queue.php @@ -133,9 +133,9 @@ } elseif($email_status == 1) { $email_status_display = "
Sending
"; } elseif($email_status == 2) { - $email_status_display = "
Failed
$email_failed_at"; + $email_status_display = "
Failed
$email_failed_at"; } else { - $email_status_display = "
Sent
$email_sent_at"; + $email_status_display = "
Sent
$email_sent_at"; } ?> @@ -148,7 +148,7 @@ - + $email_from_name"?> $email_recipient_name"?> diff --git a/admin/post/settings_mail.php b/admin/post/settings_mail.php index bd24ca001..ee297f6cc 100644 --- a/admin/post/settings_mail.php +++ b/admin/post/settings_mail.php @@ -76,7 +76,7 @@ } if (isset($_POST['edit_mail_smtp_settings'])) { - + validateCSRFToken($_POST['csrf_token']); $config_smtp_provider = sanitizeInput($_POST['config_smtp_provider']); @@ -110,15 +110,15 @@ "); logAction("Settings", "Edit", "$session_name edited SMTP settings"); - + flash_alert("SMTP Mail Settings updated"); - + redirect(); } if (isset($_POST['edit_mail_imap_settings'])) { - + validateCSRFToken($_POST['csrf_token']); $config_imap_provider = sanitizeInput($_POST['config_imap_provider']); @@ -152,9 +152,9 @@ "); logAction("Settings", "Edit", "$session_name edited IMAP settings"); - + flash_alert("IMAP Mail Settings updated"); - + redirect(); } @@ -190,7 +190,7 @@ validateCSRFToken($_POST['csrf_token']); $test_email = intval($_POST['test_email']); - + if($test_email == 1) { $email_from = sanitizeInput($config_mail_from_email); $email_from_name = sanitizeInput($config_mail_from_name); @@ -219,7 +219,7 @@ 'body' => $body ] ]; - + $mail = addToMailQueue($data); if ($mail === true) { diff --git a/admin/settings_mail.php b/admin/settings_mail.php index ffae37b07..317c4c854 100644 --- a/admin/settings_mail.php +++ b/admin/settings_mail.php @@ -1,590 +1,536 @@ - -
-
-

SMTP Mail Settings (For Sending Email)

-
-
-
- - - -
- -
-
- -
- -
- - Choose your SMTP provider. OAuth options ignore the SMTP password here. - -
+// ---- Tiny status dot for tab labels ---------------------------------------- +function mail_status_dot($on) { + return $on + ? '' + : ''; +} + +$smtp_on = !empty($config_smtp_provider); +$imap_on = !empty($config_imap_provider); +$oauth_needed = in_array($config_smtp_provider, ['google_oauth', 'microsoft_oauth'], true) + || in_array($config_imap_provider, ['google_oauth', 'microsoft_oauth'], true); + +// ---- OAuth callback URI (for Entra App Registration) ------------------------ +if (defined('BASE_URL') && !empty(BASE_URL)) { + $mail_oauth_callback_uri = rtrim((string) BASE_URL, '/') . '/admin/oauth_microsoft_mail_callback.php'; +} else { + $mail_oauth_callback_uri = 'https://' . rtrim((string) $config_base_url, '/') . '/admin/oauth_microsoft_mail_callback.php'; +} + +// ---- Readiness checks (drive the Tests tab) -------------------------------- +$smtp_standard_ready = !empty($config_smtp_host) && !empty($config_smtp_port) + && !empty($config_mail_from_email) && !empty($config_mail_from_name); + +$smtp_oauth_ready = in_array($config_smtp_provider, ['google_oauth', 'microsoft_oauth'], true) + && !empty($config_mail_from_email) && !empty($config_mail_from_name) + && !empty($config_mail_oauth_client_id) && !empty($config_mail_oauth_client_secret) + && !empty($config_mail_oauth_refresh_token) + && ($config_smtp_provider !== 'microsoft_oauth' || !empty($config_mail_oauth_tenant_id)); + +$imap_standard_ready = !empty($config_imap_username) && !empty($config_imap_password) + && !empty($config_imap_host) && !empty($config_imap_port); + +$imap_oauth_ready = in_array($config_imap_provider, ['google_oauth', 'microsoft_oauth'], true) + && !empty($config_imap_username) + && !empty($config_mail_oauth_client_id) && !empty($config_mail_oauth_client_secret) + && !empty($config_mail_oauth_refresh_token) + && ($config_imap_provider !== 'microsoft_oauth' || !empty($config_mail_oauth_tenant_id)); + +$oauth_provider_for_test = ''; +if (in_array($config_imap_provider, ['google_oauth', 'microsoft_oauth'], true)) { + $oauth_provider_for_test = $config_imap_provider; +} elseif (in_array($config_smtp_provider, ['google_oauth', 'microsoft_oauth'], true)) { + $oauth_provider_for_test = $config_smtp_provider; +} + +$oauth_has_required_fields = !empty($oauth_provider_for_test) + && !empty($config_mail_oauth_client_id) && !empty($config_mail_oauth_client_secret) + && !empty($config_mail_oauth_refresh_token) + && ($oauth_provider_for_test !== 'microsoft_oauth' || !empty($config_mail_oauth_tenant_id)); + +$send_ready = $smtp_standard_ready || $smtp_oauth_ready; +$imap_ready = $imap_standard_ready || $imap_oauth_ready; +?> + +
+
+

Mail Configuration

+
+
+ + + +
+ + +
+ + - -
- +
-
- -
- +
+
+ Choose your outbound mail provider.
-
- -
-
- +
+
+
+ +
+
+ +
- -
-
- -
- -
-
- +
+ +
+
+ +
+
+
+ +
+
+ +
-
-
- -
-
- +
+
+ +
+
+
- + Leave blank if no authentication is required.
-
- -
-
+
-
- -
- -
- -
+
+ +
-
- -
+ - +
+ + +
- -
-
+ +
+
+ -
-
-

IMAP Mail Settings (For Monitoring Ticket Inbox)

-
-
- - - -
- -
-
- -
- -
- - Select your mailbox provider. OAuth options ignore the IMAP password here. - -
-
@@ -164,7 +164,7 @@
- +
@@ -174,7 +174,7 @@
- +
diff --git a/agent/modals/network/network_edit.php b/agent/modals/network/network_edit.php index 54b861b70..a34e8023e 100644 --- a/agent/modals/network/network_edit.php +++ b/agent/modals/network/network_edit.php @@ -2,6 +2,8 @@ require_once '../../../includes/modal_header.php'; +enforceUserPermission('module_support', 2); + $network_id = intval($_GET['id']); $sql = mysqli_query($mysqli, "SELECT * FROM networks WHERE network_id = $network_id LIMIT 1"); @@ -19,7 +21,10 @@ $network_location_id = intval($row['network_location_id']); $client_id = intval($row['network_client_id']); +enforceClientAccess(); + ob_start(); + ?>
@@ -119,7 +124,7 @@
- +
@@ -129,7 +134,7 @@
- +
@@ -139,7 +144,7 @@
- +
@@ -153,7 +158,7 @@
- +
@@ -163,7 +168,7 @@
- + diff --git a/agent/modals/payment/payment_add.php b/agent/modals/payment/payment_add.php index 28a1dfcba..cfb0b61d3 100644 --- a/agent/modals/payment/payment_add.php +++ b/agent/modals/payment/payment_add.php @@ -157,7 +157,7 @@ - +
diff --git a/agent/modals/payment/payment_bulk_add.php b/agent/modals/payment/payment_bulk_add.php index a4fe1edbf..c3ad9aa37 100644 --- a/agent/modals/payment/payment_bulk_add.php +++ b/agent/modals/payment/payment_bulk_add.php @@ -159,7 +159,7 @@
- +
diff --git a/agent/modals/rack/rack_edit.php b/agent/modals/rack/rack_edit.php index 28d980ad9..84d427a26 100644 --- a/agent/modals/rack/rack_edit.php +++ b/agent/modals/rack/rack_edit.php @@ -2,6 +2,8 @@ require_once '../../../includes/modal_header.php'; +enforceUserPermission('module_support', 2); + $rack_id = intval($_GET['id']); $sql = mysqli_query($mysqli, "SELECT * FROM racks WHERE rack_id = $rack_id LIMIT 1"); @@ -20,9 +22,12 @@ $rack_created_at = nullable_htmlentities($row['rack_created_at']); $client_id = intval($row['rack_client_id']); -// Generate the HTML form content using output buffering. +enforceClientAccess(); + ob_start(); + ?> +