From f66150aa8b5d15061f1692b3d97ebbb66769e358 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Thu, 2 Apr 2026 13:56:49 +1300 Subject: [PATCH] (fix): defer event copy in UserEvents to fire-time for correct user context The UserEvents hook copied event state at resource-resolution time (before the init hook set the user), causing webhooks to receive null user IDs. Now stores the source queueForEvents as a reference and copies at fire-time when the user Document has been populated. Co-Authored-By: Claude Opus 4.6 (1M context) --- app/init/resources.php | 9 +++++---- src/Appwrite/Utopia/Database/Hooks/UserEvents.php | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/init/resources.php b/app/init/resources.php index b2d9b30644..c47e4226e9 100644 --- a/app/init/resources.php +++ b/app/init/resources.php @@ -672,10 +672,11 @@ Http::setResource('dbForProject', function (Group $pools, Database $dbForPlatfor ->addHook(new UserEvents( $project, $response, - $queueForEventsClone->from($queueForEvents), - $queueForFunctions->from($queueForEvents), - $queueForWebhooks->from($queueForEvents), - $queueForRealtime->from($queueForEvents), + $queueForEvents, + $queueForEventsClone, + $queueForFunctions, + $queueForWebhooks, + $queueForRealtime, )) ->addHook(new FunctionCache($project, $database)) ->addHook(new Permissions()); diff --git a/src/Appwrite/Utopia/Database/Hooks/UserEvents.php b/src/Appwrite/Utopia/Database/Hooks/UserEvents.php index a3eec08ca0..79f0d90bb9 100644 --- a/src/Appwrite/Utopia/Database/Hooks/UserEvents.php +++ b/src/Appwrite/Utopia/Database/Hooks/UserEvents.php @@ -21,6 +21,7 @@ class UserEvents implements Lifecycle public function __construct( private Document $project, private Response $response, + private Event $source, private Event $events, private Func $functions, private Webhook $webhooks, @@ -39,6 +40,7 @@ class UserEvents implements Lifecycle } $this->events + ->from($this->source) ->setProject($this->project) ->setEvent('users.[userId].create') ->setParam('userId', $data->getId())