Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package evolution-ews for openSUSE:Factory 
checked in at 2026-05-25 21:52:18
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/evolution-ews (Old)
 and      /work/SRC/openSUSE:Factory/.evolution-ews.new.2084 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "evolution-ews"

Mon May 25 21:52:18 2026 rev:158 rq:1354856 version:3.60.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/evolution-ews/evolution-ews.changes      
2026-04-15 16:05:20.612905462 +0200
+++ /work/SRC/openSUSE:Factory/.evolution-ews.new.2084/evolution-ews.changes    
2026-05-25 21:53:18.364333575 +0200
@@ -1,0 +2,16 @@
+Fri May 22 05:32:12 UTC 2026 - Bjørn Lie <[email protected]>
+
+- Update to version 3.60.2:
+  + Bug Fixes:
+    - m365:
+      . Skip Out of Office check for shared mailboxes
+      . GOA account can delay OAuth2 support addition
+    - Truncated file stored in the (mail) cache
+  + Miscellaneous:
+    - e-m365-connection: Ensure soup message body is filled on
+      retry
+    - Calendar: Use icaldurationtype_as_utc_seconds() for libical
+      4.x
+    - OAuth2: Uses its own error domain
+
+-------------------------------------------------------------------

Old:
----
  evolution-ews-3.60.1.tar.xz

New:
----
  evolution-ews-3.60.2.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ evolution-ews.spec ++++++
--- /var/tmp/diff_new_pack.i1YbeW/_old  2026-05-25 21:53:20.000400854 +0200
+++ /var/tmp/diff_new_pack.i1YbeW/_new  2026-05-25 21:53:20.000400854 +0200
@@ -20,7 +20,7 @@
 %define _version %(echo %{version} | grep -E -o '[0-9]+\.[0-9]+\.[0-9]+')
 
 Name:           evolution-ews
-Version:        3.60.1
+Version:        3.60.2
 Release:        0
 Summary:        Exchange Connector for Evolution, compatible with Exchange 
2007 and later
 License:        LGPL-2.1-only

++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.i1YbeW/_old  2026-05-25 21:53:20.036402335 +0200
+++ /var/tmp/diff_new_pack.i1YbeW/_new  2026-05-25 21:53:20.040402499 +0200
@@ -1,6 +1,6 @@
-mtime: 1775827844
-commit: 1c71ec7c9334458cfcb45b92d04fc00339362dc3a120453bb9669a1794f33b01
+mtime: 1779428056
+commit: 09987044b377b9f9e34bfa641d17d2ab12b41a2d4f0c27e8c0dadaa778b1c48a
 url: https://src.opensuse.org/GNOME/evolution-ews
-revision: 1c71ec7c9334458cfcb45b92d04fc00339362dc3a120453bb9669a1794f33b01
+revision: 09987044b377b9f9e34bfa641d17d2ab12b41a2d4f0c27e8c0dadaa778b1c48a
 projectscmsync: https://src.opensuse.org/GNOME/_ObsPrj
 

++++++ _service ++++++
--- /var/tmp/diff_new_pack.i1YbeW/_old  2026-05-25 21:53:20.064403486 +0200
+++ /var/tmp/diff_new_pack.i1YbeW/_new  2026-05-25 21:53:20.068403651 +0200
@@ -3,7 +3,7 @@
   <service name="obs_scm" mode="manual">
     <param name="scm">git</param>
     <param name="url">https://gitlab.gnome.org/GNOME/evolution-ews.git</param>
-    <param name="revision">3.60.1</param>
+    <param name="revision">3.60.2</param>
     <param name="versionformat">@PARENT_TAG@+@TAG_OFFSET@</param>
     <param name="versionrewrite-pattern">(.*)\+0</param>
     <param name="versionrewrite-replacement">\1</param>

++++++ build.specials.obscpio ++++++

++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore      2026-05-22 07:34:16.000000000 +0200
@@ -0,0 +1,5 @@
+*.obscpio
+*.osc
+_build.*
+.pbuild
+osc-collab.*

++++++ evolution-ews-3.60.1.tar.xz -> evolution-ews-3.60.2.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/evolution-ews-3.60.1/CMakeLists.txt 
new/evolution-ews-3.60.2/CMakeLists.txt
--- old/evolution-ews-3.60.1/CMakeLists.txt     2026-04-10 09:42:23.000000000 
+0200
+++ new/evolution-ews-3.60.2/CMakeLists.txt     2026-05-22 06:08:29.000000000 
+0200
@@ -4,7 +4,7 @@
 cmake_policy(VERSION 3.15)
 
 project(evolution-ews
-       VERSION 3.60.1
+       VERSION 3.60.2
        LANGUAGES C)
 set(PROJECT_BUGREPORT "https://gitlab.gnome.org/GNOME/evolution-ews/issues/";)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/evolution-ews-3.60.1/NEWS 
new/evolution-ews-3.60.2/NEWS
--- old/evolution-ews-3.60.1/NEWS       2026-04-10 09:42:23.000000000 +0200
+++ new/evolution-ews-3.60.2/NEWS       2026-05-22 06:08:29.000000000 +0200
@@ -1,3 +1,16 @@
+Evolution-EWS 3.60.2 2026-05-22
+-------------------------------
+
+Bug Fixes:
+       I#333 - m365: Skip Out of Office check for shared mailboxes
+       I#335 - m365: GOA account can delay OAuth2 support addition
+       evo-I#3302 - Truncated file stored in the (mail) cache
+
+Miscellaneous:
+       e-m365-connection: Ensure soup message body is filled on retry
+       Calendar: Use icaldurationtype_as_utc_seconds() for libical 4.x
+       OAuth2: Uses its own error domain
+
 Evolution-EWS 3.60.1 2026-04-10
 -------------------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-ews-3.60.1/src/EWS/calendar/e-cal-backend-ews-utils.c 
new/evolution-ews-3.60.2/src/EWS/calendar/e-cal-backend-ews-utils.c
--- old/evolution-ews-3.60.1/src/EWS/calendar/e-cal-backend-ews-utils.c 
2026-04-10 09:42:23.000000000 +0200
+++ new/evolution-ews-3.60.2/src/EWS/calendar/e-cal-backend-ews-utils.c 
2026-05-22 06:08:29.000000000 +0200
@@ -37,7 +37,7 @@
 #if !ICAL_CHECK_VERSION(3, 99, 99)
 #define ICalPropertyClassenum ICalProperty_Class
 #define i_cal_duration_new_from_seconds i_cal_duration_new_from_int
-#define i_cal_duration_as_seconds i_cal_duration_as_int
+#define i_cal_duration_as_utc_seconds i_cal_duration_as_int
 #endif
 
 /*
@@ -325,7 +325,7 @@
 
                trigger = e_cal_component_alarm_get_trigger (alarm);
                if (trigger && e_cal_component_alarm_trigger_get_kind (trigger) 
== E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START) {
-                       dur_int = (i_cal_duration_as_seconds 
(e_cal_component_alarm_trigger_get_duration (trigger)) / SECS_IN_MINUTE) * -1;
+                       dur_int = (i_cal_duration_as_utc_seconds 
(e_cal_component_alarm_trigger_get_duration (trigger)) / SECS_IN_MINUTE) * -1;
                }
        }
        e_cal_component_alarm_free (alarm);
@@ -360,7 +360,7 @@
 
                trigger = e_cal_component_alarm_get_trigger (alarm);
                if (trigger && e_cal_component_alarm_trigger_get_kind (trigger) 
== E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START) {
-                       dur_int = (i_cal_duration_as_seconds 
(e_cal_component_alarm_trigger_get_duration (trigger)) / SECS_IN_MINUTE) * -1;
+                       dur_int = (i_cal_duration_as_utc_seconds 
(e_cal_component_alarm_trigger_get_duration (trigger)) / SECS_IN_MINUTE) * -1;
                        e_ews_request_write_int_parameter (request, 
"ReminderMinutesBeforeStart", NULL, dur_int);
                        if (with_due_by) {
                                ICalTime *dtstart;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-ews-3.60.1/src/EWS/camel/camel-ews-folder.c 
new/evolution-ews-3.60.2/src/EWS/camel/camel-ews-folder.c
--- old/evolution-ews-3.60.1/src/EWS/camel/camel-ews-folder.c   2026-04-10 
09:42:23.000000000 +0200
+++ new/evolution-ews-3.60.2/src/EWS/camel/camel-ews-folder.c   2026-05-22 
06:08:29.000000000 +0200
@@ -2650,6 +2650,7 @@
                        CamelMessageInfo *info;
                        CamelMessageInfo *clone;
                        const EwsId *id;
+                       gchar *tmp_fname, *cur_fname, *dirname;
 
                        if (e_ews_item_get_item_type (l->data) == 
E_EWS_ITEM_TYPE_ERROR) {
                                if (!local_error)
@@ -2664,8 +2665,11 @@
                        if (message == NULL)
                                continue;
 
+                       /* Write to "tmp" first; rename to "cur" only after the 
write
+                          completes, so an interrupted copy never leaves a 
truncated
+                          "cur" file that would be treated as a valid cached 
message. */
                        stream = ews_data_cache_add (
-                               CAMEL_EWS_FOLDER (destination)->cache, "cur", 
id->id, NULL);
+                               CAMEL_EWS_FOLDER (destination)->cache, "tmp", 
id->id, NULL);
                        if (stream == NULL) {
                                g_object_unref (message);
 
@@ -2675,14 +2679,32 @@
                        camel_data_wrapper_write_to_stream_sync (
                                CAMEL_DATA_WRAPPER (message), stream, 
cancellable, NULL);
 
+                       g_clear_object (&stream);
+
                        info = camel_folder_summary_get 
(camel_folder_get_folder_summary (source), uids->pdata[i]);
                        if (info == NULL) {
-                               g_object_unref (stream);
+                               ews_data_cache_remove (CAMEL_EWS_FOLDER 
(destination)->cache, "tmp", id->id, NULL);
                                g_object_unref (message);
 
                                continue;
                        }
 
+                       tmp_fname = ews_data_cache_get_filename 
(CAMEL_EWS_FOLDER (destination)->cache, "tmp", id->id, NULL);
+                       cur_fname = ews_data_cache_get_filename 
(CAMEL_EWS_FOLDER (destination)->cache, "cur", id->id, NULL);
+                       dirname = g_path_get_dirname (cur_fname);
+                       g_mkdir_with_parents (dirname, 0700);
+                       g_free (dirname);
+
+                       if (g_rename (tmp_fname, cur_fname) != 0) {
+                               gint errsv = errno;
+                               g_warning ("%s: Failed to rename '%s' to '%s': 
%s",
+                                       G_STRFUNC, tmp_fname, cur_fname, 
g_strerror (errsv));
+                       }
+
+                       ews_data_cache_remove (CAMEL_EWS_FOLDER 
(destination)->cache, "tmp", id->id, NULL);
+                       g_free (tmp_fname);
+                       g_free (cur_fname);
+
                        clone = camel_message_info_clone (info, NULL);
 
                        if (camel_ews_summary_add_message 
(camel_folder_get_folder_summary (destination), id->id, id->change_key, clone, 
message))
@@ -2690,7 +2712,6 @@
 
                        g_clear_object (&clone);
                        g_clear_object (&info);
-                       g_object_unref (stream);
                        g_object_unref (message);
                }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-ews-3.60.1/src/EWS/common/e-ews-connection.c 
new/evolution-ews-3.60.2/src/EWS/common/e-ews-connection.c
--- old/evolution-ews-3.60.1/src/EWS/common/e-ews-connection.c  2026-04-10 
09:42:23.000000000 +0200
+++ new/evolution-ews-3.60.2/src/EWS/common/e-ews-connection.c  2026-05-22 
06:08:29.000000000 +0200
@@ -436,8 +436,8 @@
 
        if (!pd.prepare_data) {
                if (error && (g_error_matches (*error, E_SOUP_SESSION_ERROR, 
SOUP_STATUS_UNAUTHORIZED) ||
-                             /* Returned by the OAuth2 service when the token 
cannot be refreshed */
-                             g_error_matches (*error, G_IO_ERROR, 
G_IO_ERROR_CONNECTION_REFUSED))) {
+                             g_error_matches (*error, E_OAUTH2_SERVICE_ERROR, 
E_OAUTH2_SERVICE_ERROR_TOKEN_EXPIRED) ||
+                             g_error_matches (*error, E_OAUTH2_SERVICE_ERROR, 
E_OAUTH2_SERVICE_ERROR_REFRESH_FAILED))) {
                        (*error)->domain = EWS_CONNECTION_ERROR;
                        (*error)->code = 
EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED;
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-ews-3.60.1/src/Microsoft365/calendar/e-cal-backend-m365-utils.c 
new/evolution-ews-3.60.2/src/Microsoft365/calendar/e-cal-backend-m365-utils.c
--- 
old/evolution-ews-3.60.1/src/Microsoft365/calendar/e-cal-backend-m365-utils.c   
    2026-04-10 09:42:23.000000000 +0200
+++ 
new/evolution-ews-3.60.2/src/Microsoft365/calendar/e-cal-backend-m365-utils.c   
    2026-05-22 06:08:29.000000000 +0200
@@ -22,7 +22,7 @@
 #if !ICAL_CHECK_VERSION(3, 99, 99)
 #define ICalPropertyClassenum ICalProperty_Class
 #define i_cal_duration_new_from_seconds i_cal_duration_new_from_int
-#define i_cal_duration_as_seconds i_cal_duration_as_int
+#define i_cal_duration_as_utc_seconds i_cal_duration_as_int
 #endif
 
 static void
@@ -2097,7 +2097,7 @@
                        if (success) {
                                new_duration = 
e_cal_component_alarm_trigger_get_duration (new_trigger);
 
-                               success = new_duration && 
i_cal_duration_as_seconds (new_duration) <= 0;
+                               success = new_duration && 
i_cal_duration_as_utc_seconds (new_duration) <= 0;
                        }
 
                        if (!success) {
@@ -2141,7 +2141,7 @@
                                        case I_CAL_VEVENT_COMPONENT:
                                                old_duration = 
e_cal_component_alarm_trigger_get_duration (old_trigger);
 
-                                               changed = !old_duration || 
i_cal_duration_as_seconds (new_duration) != i_cal_duration_as_seconds 
(old_duration);
+                                               changed = !old_duration || 
i_cal_duration_as_utc_seconds (new_duration) != i_cal_duration_as_utc_seconds 
(old_duration);
                                                break;
                                        case I_CAL_VTODO_COMPONENT:
                                                old_absolute_time = 
e_cal_component_alarm_trigger_get_absolute_time (old_trigger);
@@ -2167,7 +2167,7 @@
                        switch (kind) {
                        case I_CAL_VEVENT_COMPONENT:
                                e_m365_event_add_is_reminder_on (builder, TRUE);
-                               e_m365_event_add_reminder_minutes_before_start 
(builder, i_cal_duration_as_seconds (new_duration) / -60);
+                               e_m365_event_add_reminder_minutes_before_start 
(builder, i_cal_duration_as_utc_seconds (new_duration) / -60);
                                break;
                        case I_CAL_VTODO_COMPONENT:
                                izone = i_cal_time_get_timezone 
(new_absolute_time);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-ews-3.60.1/src/Microsoft365/camel/camel-m365-folder.c 
new/evolution-ews-3.60.2/src/Microsoft365/camel/camel-m365-folder.c
--- old/evolution-ews-3.60.1/src/Microsoft365/camel/camel-m365-folder.c 
2026-04-10 09:42:23.000000000 +0200
+++ new/evolution-ews-3.60.2/src/Microsoft365/camel/camel-m365-folder.c 
2026-05-22 06:08:29.000000000 +0200
@@ -8,6 +8,7 @@
 #include <string.h>
 
 #include <glib/gi18n-lib.h>
+#include <glib/gstdio.h>
 
 #include "e-ews-common-utils.h"
 
@@ -85,31 +86,6 @@
        return checksum;
 }
 
-static CamelStream *
-m365_folder_cache_add (CamelM365Folder *m365_folder,
-                      const gchar *id,
-                      GError **error)
-{
-       GIOStream *base_stream;
-       CamelStream *stream = NULL;
-       GChecksum *checksum;
-
-       checksum = m365_folder_cache_new_checksum (id);
-
-       LOCK_CACHE (m365_folder);
-       base_stream = camel_data_cache_add (m365_folder->priv->cache, 
M365_LOCAL_CACHE_PATH, g_checksum_get_string (checksum), error);
-       UNLOCK_CACHE (m365_folder);
-
-       g_checksum_free (checksum);
-
-       if (base_stream) {
-               stream = camel_stream_new (base_stream);
-               g_object_unref (base_stream);
-       }
-
-       return stream;
-}
-
 static gint
 m365_folder_cache_remove (CamelM365Folder *m365_folder,
                          const gchar *id,
@@ -324,7 +300,22 @@
        g_mutex_unlock (&m365_folder->priv->get_message_lock);
 
        if (success && !message) {
-               cache_stream = m365_folder_cache_add (m365_folder, uid, error);
+               GChecksum *checksum;
+               GIOStream *base_stream;
+               gchar *tmp_filename, *cur_filename;
+
+               /* Write to "tmp" first; rename to "cur" only on success so an
+                  interrupted download never leaves a truncated "cur" file. */
+               checksum = m365_folder_cache_new_checksum (uid);
+
+               LOCK_CACHE (m365_folder);
+               base_stream = camel_data_cache_add (m365_folder->priv->cache, 
"tmp", g_checksum_get_string (checksum), error);
+               tmp_filename = camel_data_cache_get_filename 
(m365_folder->priv->cache, "tmp", g_checksum_get_string (checksum));
+               cur_filename = camel_data_cache_get_filename 
(m365_folder->priv->cache, M365_LOCAL_CACHE_PATH, g_checksum_get_string 
(checksum));
+               UNLOCK_CACHE (m365_folder);
+
+               cache_stream = base_stream != NULL ? camel_stream_new 
(base_stream) : NULL;
+               g_clear_object (&base_stream);
 
                success = cache_stream != NULL;
 
@@ -343,13 +334,35 @@
                        success = FALSE;
                }
 
+               /* Close the write stream before committing so the rename is 
safe
+                  on all platforms and all data is flushed to disk. */
+               g_clear_object (&cache_stream);
+
                if (success) {
-                       /* First free the cache stream, thus the follwing call 
opens a new instance,
-                          which is rewinded at the beginning of the stream. */
-                       g_clear_object (&cache_stream);
+                       gchar *dirname;
+                       gint saved_errno;
 
-                       message = m365_folder_get_message_from_cache 
(m365_folder, uid, cancellable, error);
+                       dirname = g_path_get_dirname (cur_filename);
+                       g_mkdir_with_parents (dirname, 0700);
+                       g_free (dirname);
+
+                       if (g_rename (tmp_filename, cur_filename) == 0) {
+                               camel_data_cache_remove 
(m365_folder->priv->cache, "tmp", g_checksum_get_string (checksum), NULL);
+                               message = m365_folder_get_message_from_cache 
(m365_folder, uid, cancellable, error);
+                       } else {
+                               saved_errno = errno;
+                               camel_data_cache_remove 
(m365_folder->priv->cache, "tmp", g_checksum_get_string (checksum), NULL);
+                               g_set_error (error, CAMEL_ERROR, 
CAMEL_ERROR_GENERIC,
+                                       "Failed to store message '%s': %s", 
uid, g_strerror (saved_errno));
+                               success = FALSE;
+                       }
+               } else {
+                       camel_data_cache_remove (m365_folder->priv->cache, 
"tmp", g_checksum_get_string (checksum), NULL);
                }
+
+               g_checksum_free (checksum);
+               g_free (tmp_filename);
+               g_free (cur_filename);
        }
 
        g_clear_object (&cache_stream);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-ews-3.60.1/src/Microsoft365/camel/camel-m365-store.c 
new/evolution-ews-3.60.2/src/Microsoft365/camel/camel-m365-store.c
--- old/evolution-ews-3.60.1/src/Microsoft365/camel/camel-m365-store.c  
2026-04-10 09:42:23.000000000 +0200
+++ new/evolution-ews-3.60.2/src/Microsoft365/camel/camel-m365-store.c  
2026-05-22 06:08:29.000000000 +0200
@@ -508,6 +508,7 @@
        CamelM365Store *self = user_data;
        EM365AutomaticRepliesSetting *setting = NULL;
        EM365Connection *cnc;
+       GError *local_error = NULL;
 
        cnc = camel_m365_store_ref_connection (self);
        if (!cnc)
@@ -515,16 +516,47 @@
 
        camel_operation_push_message (cancellable, _("Checking “Out of Office” 
settings"));
 
-       if (e_m365_connection_get_automatic_replies_setting_sync (cnc, NULL,  
&setting, cancellable, error) && setting) {
+       if (e_m365_connection_get_automatic_replies_setting_sync (cnc, NULL,  
&setting, cancellable, &local_error) && setting) {
                camel_m365_store_set_has_ooo_set (self, 
e_m365_automatic_replies_setting_get_status (setting) == 
E_M365_AUTOMATIC_REPLIES_STATUS_ALWAYS_ENABLED);
                g_clear_pointer (&setting, json_object_unref);
        }
 
+       /* This can be returned for shared mailboxes */
+       if (g_error_matches (local_error, E_M365_ERROR, 
E_M365_ERROR_ACCESS_DENIED))
+               g_clear_error (&local_error);
+       else if (local_error)
+               g_propagate_error (error, local_error);
+
        camel_operation_pop_message (cancellable);
        g_clear_object (&cnc);
 }
 
 static gboolean
+m365_store_is_shared_mailbox (CamelM365Store *self)
+{
+       CamelSettings *settings;
+       gboolean is_shared = FALSE;
+
+       settings = camel_service_ref_settings (CAMEL_SERVICE (self));
+
+       if (CAMEL_IS_M365_SETTINGS (settings)) {
+               CamelM365Settings *m365_settings = CAMEL_M365_SETTINGS 
(settings);
+
+               if (camel_m365_settings_get_use_impersonation (m365_settings)) {
+                       const gchar *impersonate_user;
+
+                       impersonate_user = 
camel_m365_settings_get_impersonate_user (m365_settings);
+
+                       is_shared = impersonate_user && *impersonate_user;
+               }
+       }
+
+       g_clear_object (&settings);
+
+       return is_shared;
+}
+
+static gboolean
 m365_store_connect_sync (CamelService *service,
                         GCancellable *cancellable,
                         GError **error)
@@ -567,7 +599,7 @@
 
                        state = camel_m365_store_get_ooo_alert_state 
(m365_store);
 
-                       if (state == CAMEL_M365_STORE_OOO_ALERT_STATE_UNKNOWN) {
+                       if (state == CAMEL_M365_STORE_OOO_ALERT_STATE_UNKNOWN 
&& !m365_store_is_shared_mailbox (m365_store)) {
                                camel_session_submit_job (
                                        session, _("Checking “Out of Office” 
settings"),
                                        m365_update_has_ooo_set,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-ews-3.60.1/src/Microsoft365/common/e-m365-connection.c 
new/evolution-ews-3.60.2/src/Microsoft365/common/e-m365-connection.c
--- old/evolution-ews-3.60.1/src/Microsoft365/common/e-m365-connection.c        
2026-04-10 09:42:23.000000000 +0200
+++ new/evolution-ews-3.60.2/src/Microsoft365/common/e-m365-connection.c        
2026-05-22 06:08:29.000000000 +0200
@@ -966,6 +966,9 @@
        } else if (g_strcmp0 (code, "ErrorInvalidIdMalformed") == 0) {
                domain = E_M365_ERROR;
                status_code = E_M365_ERROR_ID_MALFORMED;
+       } else if (g_strcmp0 (code, "ErrorAccessDenied") == 0) {
+               domain = E_M365_ERROR;
+               status_code = E_M365_ERROR_ACCESS_DENIED;
        } else if (g_strcmp0 (code, "SyncStateNotFound") == 0) {
                domain = E_M365_ERROR;
                status_code = E_M365_ERROR_SYNC_STATE_NOT_FOUND;
@@ -1279,6 +1282,8 @@
                if (need_retry) {
                        success = FALSE;
                        g_clear_error (error);
+
+                       g_signal_emit_by_name (message, "restarted");
                }
        }
 
@@ -1539,8 +1544,8 @@
                } else if (e_soup_session_get_ssl_error_details (E_SOUP_SESSION 
(cnc->priv->soup_session), out_certificate_pem, out_certificate_errors)) {
                        result = E_SOURCE_AUTHENTICATION_ERROR_SSL_FAILED;
                } else if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, 
SOUP_STATUS_UNAUTHORIZED) ||
-                          /* Returned by the OAuth2 service when the token 
cannot be refreshed */
-                          g_error_matches (local_error, G_IO_ERROR, 
G_IO_ERROR_CONNECTION_REFUSED)) {
+                          g_error_matches (local_error, 
E_OAUTH2_SERVICE_ERROR, E_OAUTH2_SERVICE_ERROR_TOKEN_EXPIRED) ||
+                          g_error_matches (local_error, 
E_OAUTH2_SERVICE_ERROR, E_OAUTH2_SERVICE_ERROR_REFRESH_FAILED)) {
                        LOCK (cnc);
 
                        if (cnc->priv->impersonate_user) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-ews-3.60.1/src/Microsoft365/common/e-m365-connection.h 
new/evolution-ews-3.60.2/src/Microsoft365/common/e-m365-connection.h
--- old/evolution-ews-3.60.1/src/Microsoft365/common/e-m365-connection.h        
2026-04-10 09:42:23.000000000 +0200
+++ new/evolution-ews-3.60.2/src/Microsoft365/common/e-m365-connection.h        
2026-05-22 06:08:29.000000000 +0200
@@ -54,7 +54,8 @@
 typedef enum {
        E_M365_ERROR_ID_MALFORMED,
        E_M365_ERROR_SYNC_STATE_NOT_FOUND,
-       E_M365_ERROR_ITEM_NOT_FOUND
+       E_M365_ERROR_ITEM_NOT_FOUND,
+       E_M365_ERROR_ACCESS_DENIED
 } EM365Error;
 
 #define        E_M365_ERROR e_m365_error_quark ()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-ews-3.60.1/src/Microsoft365/evolution/e-mail-config-m365-notebook.c
 
new/evolution-ews-3.60.2/src/Microsoft365/evolution/e-mail-config-m365-notebook.c
--- 
old/evolution-ews-3.60.1/src/Microsoft365/evolution/e-mail-config-m365-notebook.c
   2026-04-10 09:42:23.000000000 +0200
+++ 
new/evolution-ews-3.60.2/src/Microsoft365/evolution/e-mail-config-m365-notebook.c
   2026-05-22 06:08:29.000000000 +0200
@@ -7,6 +7,8 @@
 
 #include <mail/e-mail-config-notebook.h>
 
+#include "common/camel-m365-settings.h"
+
 #include "e-mail-config-m365-ooo-page.h"
 #include "e-mail-config-m365-notebook.h"
 
@@ -22,6 +24,33 @@
        return E_MAIL_CONFIG_NOTEBOOK (e_extension_get_extensible (E_EXTENSION 
(self)));
 }
 
+static gboolean
+mail_config_m365_notebook_is_shared_mailbox (ESource *collection_source)
+{
+       CamelSettings *settings;
+       CamelM365Settings *m365_settings;
+       ESourceCamel *extension;
+       const gchar *extension_name;
+       const gchar *impersonate_user;
+
+       extension_name = e_source_camel_get_extension_name ("Microsoft365");
+       extension = e_source_get_extension (collection_source, extension_name);
+
+       settings = e_source_camel_get_settings (extension);
+
+       if (!settings || !CAMEL_IS_M365_SETTINGS (settings))
+               return FALSE;
+
+       m365_settings = CAMEL_M365_SETTINGS (settings);
+
+       if (!camel_m365_settings_get_use_impersonation (m365_settings))
+               return FALSE;
+
+       impersonate_user = camel_m365_settings_get_impersonate_user 
(m365_settings);
+
+       return impersonate_user && *impersonate_user;
+}
+
 static void
 mail_config_m365_notebook_constructed (GObject *object)
 {
@@ -53,7 +82,7 @@
        backend_ext = e_source_get_extension (account_source, extension_name);
        backend_name = e_source_backend_get_backend_name (backend_ext);
 
-       if (g_strcmp0 (backend_name, "microsoft365") == 0) {
+       if (g_strcmp0 (backend_name, "microsoft365") == 0 && 
!mail_config_m365_notebook_is_shared_mailbox (collection_source)) {
                EMailConfigPage *page;
 
                page = e_mail_config_m365_ooo_page_new (registry, 
account_source, identity_source, collection_source);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-ews-3.60.1/src/Microsoft365/registry/e-m365-backend.c 
new/evolution-ews-3.60.2/src/Microsoft365/registry/e-m365-backend.c
--- old/evolution-ews-3.60.1/src/Microsoft365/registry/e-m365-backend.c 
2026-04-10 09:42:23.000000000 +0200
+++ new/evolution-ews-3.60.2/src/Microsoft365/registry/e-m365-backend.c 
2026-05-22 06:08:29.000000000 +0200
@@ -26,6 +26,7 @@
        gboolean need_update_folders;
 
        gulong source_changed_id;
+       gulong oauth2_support_handler_id;
 };
 
 G_DEFINE_DYNAMIC_TYPE_EXTENDED (EM365Backend, e_m365_backend, 
E_TYPE_COLLECTION_BACKEND, 0,
@@ -55,6 +56,20 @@
 static void m365_backend_populate (ECollectionBackend *backend);
 
 static void
+m365_backend_oauth2_support_ready_cb (GObject *source,
+                                     GParamSpec *pspec,
+                                     EM365Backend *m365_backend)
+{
+       if (m365_backend->priv->oauth2_support_handler_id) {
+               g_signal_handler_disconnect (source, 
m365_backend->priv->oauth2_support_handler_id);
+               m365_backend->priv->oauth2_support_handler_id = 0;
+       }
+
+       if (e_backend_get_online (E_BACKEND (m365_backend)))
+               e_backend_schedule_authenticate (E_BACKEND (m365_backend), 
NULL);
+}
+
+static void
 m365_backend_source_changed_cb (ESource *source,
                                EM365Backend *backend)
 {
@@ -96,8 +111,35 @@
 
        m365_backend_claim_old_resources (collection_backend);
 
-       if (e_backend_get_online (backend))
-               e_backend_schedule_authenticate (backend, NULL);
+       if (e_backend_get_online (backend)) {
+               gboolean is_external = FALSE;
+
+               if (e_source_has_extension (source, 
E_SOURCE_EXTENSION_AUTHENTICATION)) {
+                       ESourceAuthentication *auth_extension;
+
+                       auth_extension = e_source_get_extension (source, 
E_SOURCE_EXTENSION_AUTHENTICATION);
+                       is_external = e_source_authentication_get_is_external 
(auth_extension);
+               }
+
+               /* For GOA-managed sources, oauth2_support is set 
asynchronously. If it hasn't
+                  been set yet, wait for it before scheduling authentication 
to avoid a spurious
+                  "does not support OAuth 2.0 authentication" error. */
+               if (is_external && E_IS_SERVER_SIDE_SOURCE (source)) {
+                       EOAuth2Support *oauth2_support;
+
+                       oauth2_support = 
e_server_side_source_ref_oauth2_support (E_SERVER_SIDE_SOURCE (source));
+                       if (oauth2_support) {
+                               g_clear_object (&oauth2_support);
+                               e_backend_schedule_authenticate (backend, NULL);
+                       } else if 
(!m365_backend->priv->oauth2_support_handler_id) {
+                               m365_backend->priv->oauth2_support_handler_id = 
g_signal_connect (
+                                       source, "notify::oauth2-support",
+                                       G_CALLBACK 
(m365_backend_oauth2_support_ready_cb), m365_backend);
+                       }
+               } else {
+                       e_backend_schedule_authenticate (backend, NULL);
+               }
+       }
 
        e_collection_backend_thaw_populate (collection_backend);
 }
@@ -957,6 +999,11 @@
                m365_backend->priv->source_changed_id = 0;
        }
 
+       if (source && m365_backend->priv->oauth2_support_handler_id) {
+               g_signal_handler_disconnect (source, 
m365_backend->priv->oauth2_support_handler_id);
+               m365_backend->priv->oauth2_support_handler_id = 0;
+       }
+
        /* Chain up to parent's method. */
        G_OBJECT_CLASS (e_m365_backend_parent_class)->dispose (object);
 }

++++++ evolution-ews.obsinfo ++++++
--- /var/tmp/diff_new_pack.i1YbeW/_old  2026-05-25 21:53:20.824434741 +0200
+++ /var/tmp/diff_new_pack.i1YbeW/_new  2026-05-25 21:53:20.828434905 +0200
@@ -1,5 +1,5 @@
 name: evolution-ews
-version: 3.60.1
-mtime: 1775806943
-commit: 63370324044f652f016f82a8461d47cfd24ebd63
+version: 3.60.2
+mtime: 1779422909
+commit: e83b6a98572fe6e031f3b70355d98cdf06a62274
 

Reply via email to