From abcb0a4b3e2b82479ffbbde9e9e46ab2bc89d276 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Tue, 28 Jul 2026 19:39:48 +0200 Subject: [PATCH] feat: emit user.updated on OAuth profile sync With OAUTH_UPDATE_NAME_ON_LOGIN, OAUTH_UPDATE_EMAIL_ON_LOGIN or OAUTH_UPDATE_PICTURE_ON_LOGIN enabled, OWUI rewrites the stored name, email and profile picture from the IdP claims on every SSO login. Those writes emitted nothing, so an account whose email or display name is driven entirely by the IdP could change underneath every event consumer without a single event. Emits one user.updated per login carrying data.updated_fields, published only when at least one field was actually persisted, so a login that changes nothing stays silent. This matches how the admin user-update endpoint reports the same fields, and the payload carries source "oauth" and data.provider like the other events on this callback. --- backend/open_webui/utils/oauth.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/backend/open_webui/utils/oauth.py b/backend/open_webui/utils/oauth.py index fce053dae8..3bc6f5f1b0 100644 --- a/backend/open_webui/utils/oauth.py +++ b/backend/open_webui/utils/oauth.py @@ -1955,6 +1955,8 @@ class OAuthManager: data={'role': determined_role, 'provider': provider}, ) + synced_fields = [] + if auth_config.OAUTH_UPDATE_NAME_ON_LOGIN: username_claim = auth_config.OAUTH_USERNAME_CLAIM if username_claim: @@ -1962,6 +1964,7 @@ class OAuthManager: if new_name and new_name != user.name: await Users.update_user_by_id(user.id, {'name': new_name}, db=db) user.name = new_name + synced_fields.append('name') log.debug('Updated name for user %s', user.email) if auth_config.OAUTH_UPDATE_EMAIL_ON_LOGIN: @@ -1977,6 +1980,7 @@ class OAuthManager: else: await Auths.update_email_by_id(user.id, new_email.lower(), db=db) user.email = new_email.lower() + synced_fields.append('email') log.debug('Updated email for user %s', user.id) # Update profile picture if enabled and different from current @@ -1992,7 +1996,18 @@ class OAuthManager: ) if processed_picture_url != user.profile_image_url: await Users.update_user_profile_image_url_by_id(user.id, processed_picture_url, db=db) + synced_fields.append('profile_image_url') log.debug('Updated profile picture for user %s', user.email) + + if synced_fields: + await publish_event( + request, + EVENTS.USER_UPDATED, + actor=user, + subject_id=user.id, + source='oauth', + data={'updated_fields': synced_fields, 'provider': provider}, + ) else: # If the user does not exist, check if signups are enabled if auth_config.ENABLE_OAUTH_SIGNUP: