From 944129551006ba4f2cc042716b78fc1889cc1d03 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 14 Dec 2025 01:43:35 +0000 Subject: [PATCH 01/23] Feat: Audits upgrade --- app/controllers/api/messaging.php | 22 ++++++---- app/controllers/api/projects.php | 3 +- app/controllers/api/teams.php | 4 +- app/controllers/api/users.php | 4 +- app/http.php | 7 ++- app/init/resources.php | 11 ++++- composer.json | 6 +-- composer.lock | 43 +++++++++++-------- .../Collections/Documents/Logs/XList.php | 4 +- .../Http/Databases/Collections/Logs/XList.php | 12 +++--- .../Databases/Http/Databases/Logs/XList.php | 12 +++--- .../Databases/Http/TablesDB/Logs/XList.php | 12 +++--- src/Appwrite/Platform/Workers/Audits.php | 4 +- 13 files changed, 85 insertions(+), 59 deletions(-) diff --git a/app/controllers/api/messaging.php b/app/controllers/api/messaging.php index 771dd0e6a5..eed12c3376 100644 --- a/app/controllers/api/messaging.php +++ b/app/controllers/api/messaging.php @@ -1145,7 +1145,8 @@ App::get('/v1/messaging/providers/:providerId/logs') ->inject('dbForProject') ->inject('locale') ->inject('geodb') - ->action(function (string $providerId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { + ->inject('audit') + ->action(function (string $providerId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit) { $provider = $dbForProject->getDocument('providers', $providerId); if ($provider->isEmpty()) { @@ -1158,9 +1159,12 @@ App::get('/v1/messaging/providers/:providerId/logs') throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } - $audit = new Audit($dbForProject); + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + $resource = 'provider/' . $providerId; - $logs = $audit->getLogsByResource($resource, $queries); + $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); $output = []; foreach ($logs as $i => &$log) { @@ -2549,7 +2553,8 @@ App::get('/v1/messaging/topics/:topicId/logs') ->inject('dbForProject') ->inject('locale') ->inject('geodb') - ->action(function (string $topicId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { + ->inject('audit') + ->action(function (string $topicId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit) { $topic = $dbForProject->getDocument('topics', $topicId); if ($topic->isEmpty()) { @@ -2562,7 +2567,6 @@ App::get('/v1/messaging/topics/:topicId/logs') throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } - $audit = new Audit($dbForProject); $resource = 'topic/' . $topicId; $logs = $audit->getLogsByResource($resource, $queries); @@ -2966,7 +2970,8 @@ App::get('/v1/messaging/subscribers/:subscriberId/logs') ->inject('dbForProject') ->inject('locale') ->inject('geodb') - ->action(function (string $subscriberId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { + ->inject('audit') + ->action(function (string $subscriberId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit) { $subscriber = $dbForProject->getDocument('subscribers', $subscriberId); if ($subscriber->isEmpty()) { @@ -2979,7 +2984,6 @@ App::get('/v1/messaging/subscribers/:subscriberId/logs') throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } - $audit = new Audit($dbForProject); $resource = 'subscriber/' . $subscriberId; $logs = $audit->getLogsByResource($resource, $queries); @@ -3761,7 +3765,8 @@ App::get('/v1/messaging/messages/:messageId/logs') ->inject('dbForProject') ->inject('locale') ->inject('geodb') - ->action(function (string $messageId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { + ->inject('audit') + ->action(function (string $messageId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit) { $message = $dbForProject->getDocument('messages', $messageId); if ($message->isEmpty()) { @@ -3774,7 +3779,6 @@ App::get('/v1/messaging/messages/:messageId/logs') throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } - $audit = new Audit($dbForProject); $resource = 'message/' . $messageId; $logs = $audit->getLogsByResource($resource, $queries); diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 37f7fdbc8b..364a7914b4 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -247,7 +247,8 @@ App::post('/v1/projects') } if ($create || $projectTables) { - $audit = new Audit($dbForProject); + $adapter = new \Utopia\Audit\Adapters\Database($dbForProject); + $audit = new Audit($adapter); $audit->setup(); } diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 5f45c38fed..04a43577ad 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -1464,7 +1464,8 @@ App::get('/v1/teams/:teamId/logs') ->inject('dbForProject') ->inject('locale') ->inject('geodb') - ->action(function (string $teamId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { + ->inject('audit') + ->action(function (string $teamId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit) { $team = $dbForProject->getDocument('teams', $teamId); @@ -1478,7 +1479,6 @@ App::get('/v1/teams/:teamId/logs') throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } - $audit = new Audit($dbForProject); $resource = 'team/' . $team->getId(); $logs = $audit->getLogsByResource($resource, $queries); diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index e49b0631d3..161b5a3298 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -945,7 +945,8 @@ App::get('/v1/users/:userId/logs') ->inject('dbForProject') ->inject('locale') ->inject('geodb') - ->action(function (string $userId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { + ->inject('audit') + ->action(function (string $userId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit) { $user = $dbForProject->getDocument('users', $userId); @@ -958,7 +959,6 @@ App::get('/v1/users/:userId/logs') throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } - $audit = new Audit($dbForProject); $logs = $audit->getLogsByUser($user->getSequence(), $queries); $output = []; foreach ($logs as $i => &$log) { diff --git a/app/http.php b/app/http.php index 1bd3e97e69..5bee2c1309 100644 --- a/app/http.php +++ b/app/http.php @@ -12,6 +12,7 @@ use Swoole\Process; use Swoole\Table; use Swoole\Timer; use Utopia\App; +use Utopia\Audit\Adapter\Database as AdapterDatabase; use Utopia\Audit\Audit; use Utopia\CLI\Console; use Utopia\Compression\Compression; @@ -261,7 +262,8 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg // create appwrite database, `dbForPlatform` is a direct access call. createDatabase($app, 'dbForPlatform', 'appwrite', $collections['console'], $pools, function (Database $dbForPlatform) use ($collections) { if ($dbForPlatform->getCollection(Audit::COLLECTION)->isEmpty()) { - $audit = new Audit($dbForPlatform); + $adapter = new AdapterDatabase($dbForPlatform); + $audit = new Audit($adapter); $audit->setup(); } @@ -390,7 +392,8 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg } if ($dbForProject->getCollection(Audit::COLLECTION)->isEmpty()) { - $audit = new Audit($dbForProject); + $adapter = new AdapterDatabase($dbForProject); + $audit = new Audit($adapter); $audit->setup(); } diff --git a/app/init/resources.php b/app/init/resources.php index 6351dae478..ba525091b6 100644 --- a/app/init/resources.php +++ b/app/init/resources.php @@ -4,7 +4,7 @@ use Ahc\Jwt\JWT; use Ahc\Jwt\JWTException; use Appwrite\Auth\Key; use Appwrite\Databases\TransactionState; -use Appwrite\Event\Audit; +use Appwrite\Event\Audit as AuditEvent; use Appwrite\Event\Build; use Appwrite\Event\Certificate; use Appwrite\Event\Database as EventDatabase; @@ -30,6 +30,8 @@ use Appwrite\Utopia\Response; use Executor\Executor; use Utopia\Abuse\Adapters\TimeLimit\Redis as TimeLimitRedis; use Utopia\App; +use Utopia\Audit\Adapter\Database as AdapterDatabase; +use Utopia\Audit\Audit; use Utopia\Auth\Hashes\Argon2; use Utopia\Auth\Hashes\Sha; use Utopia\Auth\Proofs\Code; @@ -146,7 +148,7 @@ App::setResource('queueForStatsUsage', function (Publisher $publisher) { return new StatsUsage($publisher); }, ['publisher']); App::setResource('queueForAudits', function (Publisher $publisher) { - return new Audit($publisher); + return new AuditEvent($publisher); }, ['publisher']); App::setResource('queueForFunctions', function (Publisher $publisher) { return new Func($publisher); @@ -652,6 +654,11 @@ App::setResource('getLogsDB', function (Group $pools, Cache $cache) { }; }, ['pools', 'cache']); +App::setResource('audit', function ($dbForProject) { + $adapter = new AdapterDatabase($dbForProject); + return new Audit($adapter); +}, ['dbForProject']); + App::setResource('telemetry', fn () => new NoTelemetry()); App::setResource('cache', function (Group $pools, Telemetry $telemetry) { diff --git a/composer.json b/composer.json index d32b739311..e00d5832cb 100644 --- a/composer.json +++ b/composer.json @@ -47,12 +47,12 @@ "appwrite/php-clamav": "2.0.*", "utopia-php/abuse": "1.*", "utopia-php/analytics": "0.10.*", - "utopia-php/audit": "1.*", + "utopia-php/audit": "2.*", "utopia-php/auth": "0.5.*", "utopia-php/cache": "0.13.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "1.*.*", - "utopia-php/database": "3.*", + "utopia-php/database": "3.5.0 as 4.0.0", "utopia-php/detector": "0.2.*", "utopia-php/domains": "0.9.*", "utopia-php/emails": "0.6.*", @@ -109,4 +109,4 @@ "tbachert/spi": true } } -} +} \ No newline at end of file diff --git a/composer.lock b/composer.lock index 47a32cf774..f1ab2dc20d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7c9cb03eb5267f1e7a3ffc037ae22b6a", + "content-hash": "bdc28f33867a1e231528daa7dc812702", "packages": [ { "name": "adhocore/jwt", @@ -3552,21 +3552,23 @@ }, { "name": "utopia-php/audit", - "version": "1.0.2", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "8c17065c2473d4ca799f65585ca74eb53e1be211" + "reference": "bac717c6096594eed3949a7d47b87700e7573c8b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/8c17065c2473d4ca799f65585ca74eb53e1be211", - "reference": "8c17065c2473d4ca799f65585ca74eb53e1be211", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/bac717c6096594eed3949a7d47b87700e7573c8b", + "reference": "bac717c6096594eed3949a7d47b87700e7573c8b", "shasum": "" }, "require": { "php": ">=8.0", - "utopia-php/database": "*" + "utopia-php/database": "4.*", + "utopia-php/fetch": "^0.4.2", + "utopia-php/validators": "^0.1.0" }, "require-dev": { "laravel/pint": "1.*", @@ -3593,9 +3595,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/1.0.2" + "source": "https://github.com/utopia-php/audit/tree/2.0.0" }, - "time": "2025-10-20T07:14:26+00:00" + "time": "2025-12-13T23:17:26+00:00" }, { "name": "utopia-php/auth", @@ -4264,16 +4266,16 @@ }, { "name": "utopia-php/framework", - "version": "0.33.34", + "version": "0.33.35", "source": { "type": "git", "url": "https://github.com/utopia-php/http.git", - "reference": "76def92594c32504ec80eaacdb60ff8fad73c856" + "reference": "82b139fb04f30045db51b0d322224f222da32313" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/http/zipball/76def92594c32504ec80eaacdb60ff8fad73c856", - "reference": "76def92594c32504ec80eaacdb60ff8fad73c856", + "url": "https://api.github.com/repos/utopia-php/http/zipball/82b139fb04f30045db51b0d322224f222da32313", + "reference": "82b139fb04f30045db51b0d322224f222da32313", "shasum": "" }, "require": { @@ -4306,9 +4308,9 @@ ], "support": { "issues": "https://github.com/utopia-php/http/issues", - "source": "https://github.com/utopia-php/http/tree/0.33.34" + "source": "https://github.com/utopia-php/http/tree/0.33.35" }, - "time": "2025-12-08T07:55:31+00:00" + "time": "2025-12-12T08:33:52+00:00" }, { "name": "utopia-php/image", @@ -8941,9 +8943,16 @@ "time": "2024-03-07T20:33:40+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "utopia-php/database", + "version": "3.5.0.0", + "alias": "4.0.0", + "alias_normalized": "4.0.0.0" + } + ], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -8967,5 +8976,5 @@ "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php index 47f5247831..292bed4c36 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php @@ -72,10 +72,11 @@ class XList extends Action ->inject('dbForProject') ->inject('locale') ->inject('geodb') + ->inject('audit') ->callback($this->action(...)); } - public function action(string $databaseId, string $collectionId, string $documentId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb): void + public function action(string $databaseId, string $collectionId, string $documentId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void { $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { @@ -98,7 +99,6 @@ class XList extends Action throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } - $audit = new Audit($dbForProject); $type = $this->getCollectionsEventsContext(); $context = $this->getContext(); $resource = "database/$databaseId/$type/$collectionId/$context/{$document->getId()}"; diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php index a45daa32a4..2244bfd2d7 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php @@ -67,14 +67,15 @@ class XList extends Action ->param('databaseId', '', new UID(), 'Database ID.') ->param('collectionId', '', new UID(), 'Collection ID.') ->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true) - ->inject('response') - ->inject('dbForProject') - ->inject('locale') - ->inject('geodb') + ->inject('response') + ->inject('dbForProject') + ->inject('locale') + ->inject('geodb') + ->inject('audit') ->callback($this->action(...)); } - public function action(string $databaseId, string $collectionId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb): void + public function action(string $databaseId, string $collectionId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void { $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -95,7 +96,6 @@ class XList extends Action throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } - $audit = new Audit($dbForProject); $context = $this->getContext(); $resource = "database/$databaseId/$context/$collectionId"; $logs = $audit->getLogsByResource($resource, $queries); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php index a794ec325e..42081127d5 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php @@ -63,14 +63,15 @@ class XList extends Action ]) ->param('databaseId', '', new UID(), 'Database ID.') ->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true) - ->inject('response') - ->inject('dbForProject') - ->inject('locale') - ->inject('geodb') + ->inject('response') + ->inject('dbForProject') + ->inject('locale') + ->inject('geodb') + ->inject('audit') ->callback($this->action(...)); } - public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb): void + public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void { $database = $dbForProject->getDocument('databases', $databaseId); @@ -84,7 +85,6 @@ class XList extends Action throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } - $audit = new Audit($dbForProject); $resource = 'database/' . $databaseId; $logs = $audit->getLogsByResource($resource, $queries); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php index 53476dbae1..ed2aaa848c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php @@ -58,14 +58,15 @@ class XList extends Action ]) ->param('databaseId', '', new UID(), 'Database ID.') ->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true) - ->inject('response') - ->inject('dbForProject') - ->inject('locale') - ->inject('geodb') + ->inject('response') + ->inject('dbForProject') + ->inject('locale') + ->inject('geodb') + ->inject('audit') ->callback($this->action(...)); } - public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb): void + public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void { $database = $dbForProject->getDocument('databases', $databaseId); @@ -79,7 +80,6 @@ class XList extends Action throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } - $audit = new Audit($dbForProject); $resource = 'database/' . $databaseId; $logs = $audit->getLogsByResource($resource, $queries); diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index be542e7811..2f0364e408 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -5,6 +5,7 @@ namespace Appwrite\Platform\Workers; use Exception; use Throwable; use Utopia\Audit\Audit; +use Utopia\Audit\Adapters\Database as AdapterDatabase; use Utopia\CLI\Console; use Utopia\Database\Document; use Utopia\Database\Exception\Authorization; @@ -136,7 +137,8 @@ class Audits extends Action $projectDocument = $projectLogs['project']; $dbForProject = $getProjectDB($projectDocument); - $audit = new Audit($dbForProject); + $adapter = new AdapterDatabase($dbForProject); + $audit = new Audit($adapter); $audit->logBatch($projectLogs['logs']); Console::success('Audit logs processed successfully'); From c50db111d61305080bf65364a2d8b237931d4080 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 14 Dec 2025 02:19:53 +0000 Subject: [PATCH 02/23] format --- .../Platform/Modules/Databases/Http/Databases/Logs/XList.php | 2 +- src/Appwrite/Platform/Workers/Audits.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php index 42081127d5..be30a0fad8 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php @@ -71,7 +71,7 @@ class XList extends Action ->callback($this->action(...)); } - public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void + public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void { $database = $dbForProject->getDocument('databases', $databaseId); diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index 2f0364e408..369a67116d 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -4,8 +4,8 @@ namespace Appwrite\Platform\Workers; use Exception; use Throwable; -use Utopia\Audit\Audit; use Utopia\Audit\Adapters\Database as AdapterDatabase; +use Utopia\Audit\Audit; use Utopia\CLI\Console; use Utopia\Database\Document; use Utopia\Database\Exception\Authorization; From a0599d26582141f6b034748b21a64723aa7e9890 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 14 Dec 2025 02:31:24 +0000 Subject: [PATCH 03/23] Upgrade audit --- composer.json | 4 ++-- composer.lock | 41 ++++++++++++++++++----------------------- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/composer.json b/composer.json index e00d5832cb..be88d8ae5e 100644 --- a/composer.json +++ b/composer.json @@ -47,12 +47,12 @@ "appwrite/php-clamav": "2.0.*", "utopia-php/abuse": "1.*", "utopia-php/analytics": "0.10.*", - "utopia-php/audit": "2.*", + "utopia-php/audit": "dev-feat-db-3.x", "utopia-php/auth": "0.5.*", "utopia-php/cache": "0.13.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "1.*.*", - "utopia-php/database": "3.5.0 as 4.0.0", + "utopia-php/database": "3.*.*", "utopia-php/detector": "0.2.*", "utopia-php/domains": "0.9.*", "utopia-php/emails": "0.6.*", diff --git a/composer.lock b/composer.lock index f1ab2dc20d..3e6b49307f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bdc28f33867a1e231528daa7dc812702", + "content-hash": "d26b9cee30ab2cc3bc5873ac911918d1", "packages": [ { "name": "adhocore/jwt", @@ -3552,21 +3552,21 @@ }, { "name": "utopia-php/audit", - "version": "2.0.0", + "version": "dev-feat-db-3.x", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "bac717c6096594eed3949a7d47b87700e7573c8b" + "reference": "5b5a5440eb37ee6c6b7fc717868e6965b19c003f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/bac717c6096594eed3949a7d47b87700e7573c8b", - "reference": "bac717c6096594eed3949a7d47b87700e7573c8b", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/5b5a5440eb37ee6c6b7fc717868e6965b19c003f", + "reference": "5b5a5440eb37ee6c6b7fc717868e6965b19c003f", "shasum": "" }, "require": { "php": ">=8.0", - "utopia-php/database": "4.*", + "utopia-php/database": "3.*", "utopia-php/fetch": "^0.4.2", "utopia-php/validators": "^0.1.0" }, @@ -3595,9 +3595,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/2.0.0" + "source": "https://github.com/utopia-php/audit/tree/feat-db-3.x" }, - "time": "2025-12-13T23:17:26+00:00" + "time": "2025-12-14T02:29:51+00:00" }, { "name": "utopia-php/auth", @@ -3898,16 +3898,16 @@ }, { "name": "utopia-php/database", - "version": "3.5.0", + "version": "3.6.0", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "5da71b65a6123ce2e78795522b05b7458aabfbd7" + "reference": "af15066255a5fd7bd2926de37bcbf3d8500fc155" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/5da71b65a6123ce2e78795522b05b7458aabfbd7", - "reference": "5da71b65a6123ce2e78795522b05b7458aabfbd7", + "url": "https://api.github.com/repos/utopia-php/database/zipball/af15066255a5fd7bd2926de37bcbf3d8500fc155", + "reference": "af15066255a5fd7bd2926de37bcbf3d8500fc155", "shasum": "" }, "require": { @@ -3950,9 +3950,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/3.5.0" + "source": "https://github.com/utopia-php/database/tree/3.6.0" }, - "time": "2025-11-18T08:11:01+00:00" + "time": "2025-12-08T05:23:04+00:00" }, { "name": "utopia-php/detector", @@ -8943,16 +8943,11 @@ "time": "2024-03-07T20:33:40+00:00" } ], - "aliases": [ - { - "package": "utopia-php/database", - "version": "3.5.0.0", - "alias": "4.0.0", - "alias_normalized": "4.0.0.0" - } - ], + "aliases": [], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": { + "utopia-php/audit": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { From 30083598c6df64cc0ec41a7c1d4ba51615346c15 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 14 Dec 2025 02:33:17 +0000 Subject: [PATCH 04/23] fix audit --- app/http.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/http.php b/app/http.php index 5bee2c1309..cedfcdf1f3 100644 --- a/app/http.php +++ b/app/http.php @@ -13,6 +13,7 @@ use Swoole\Table; use Swoole\Timer; use Utopia\App; use Utopia\Audit\Adapter\Database as AdapterDatabase; +use Utopia\Audit\Adapter\SQL as AuditAdapterSQL; use Utopia\Audit\Audit; use Utopia\CLI\Console; use Utopia\Compression\Compression; @@ -261,7 +262,7 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg // create appwrite database, `dbForPlatform` is a direct access call. createDatabase($app, 'dbForPlatform', 'appwrite', $collections['console'], $pools, function (Database $dbForPlatform) use ($collections) { - if ($dbForPlatform->getCollection(Audit::COLLECTION)->isEmpty()) { + if ($dbForPlatform->getCollection(SQL::COLLECTION)->isEmpty()) { $adapter = new AdapterDatabase($dbForPlatform); $audit = new Audit($adapter); $audit->setup(); @@ -391,7 +392,7 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg Console::success('[Setup] - Skip: metadata table already exists'); } - if ($dbForProject->getCollection(Audit::COLLECTION)->isEmpty()) { + if ($dbForProject->getCollection(AuditAdapterSQL::COLLECTION)->isEmpty()) { $adapter = new AdapterDatabase($dbForProject); $audit = new Audit($adapter); $audit->setup(); From 2dcb1317786732a6fe8a61ea2a73aeb7d4c32af3 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 14 Dec 2025 02:34:33 +0000 Subject: [PATCH 05/23] fix collection name --- app/http.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/http.php b/app/http.php index cedfcdf1f3..b7f857da48 100644 --- a/app/http.php +++ b/app/http.php @@ -262,7 +262,7 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg // create appwrite database, `dbForPlatform` is a direct access call. createDatabase($app, 'dbForPlatform', 'appwrite', $collections['console'], $pools, function (Database $dbForPlatform) use ($collections) { - if ($dbForPlatform->getCollection(SQL::COLLECTION)->isEmpty()) { + if ($dbForPlatform->getCollection(AuditAdapterSQL::COLLECTION)->isEmpty()) { $adapter = new AdapterDatabase($dbForPlatform); $audit = new Audit($adapter); $audit->setup(); From b83125a41ec806321a26ade27a8e6a195f5d5575 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 14 Dec 2025 07:22:39 +0000 Subject: [PATCH 06/23] Fix audits creation --- app/controllers/api/projects.php | 8 +++++--- composer.lock | 22 +++++++++++----------- src/Appwrite/Platform/Workers/Deletes.php | 6 +++--- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 364a7914b4..ed6fa20eba 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -21,6 +21,7 @@ use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use PHPMailer\PHPMailer\PHPMailer; use Utopia\App; +use Utopia\Audit\Adapter\Database as AdapterDatabase; use Utopia\Audit\Audit; use Utopia\Cache\Cache; use Utopia\Config\Config; @@ -247,14 +248,15 @@ App::post('/v1/projects') } if ($create || $projectTables) { - $adapter = new \Utopia\Audit\Adapters\Database($dbForProject); + $adapter = new AdapterDatabase($dbForProject); $audit = new Audit($adapter); $audit->setup(); } if (!$create && $sharedTablesV1) { - $attributes = \array_map(fn ($attribute) => new Document($attribute), Audit::ATTRIBUTES); - $indexes = \array_map(fn (array $index) => new Document($index), Audit::INDEXES); + $adapter = new AdapterDatabase($dbForProject); + $attributes = $adapter->getAttributeDocuments(); + $indexes = $adapter->getIndexDocuments(); $dbForProject->createDocument(Database::METADATA, new Document([ '$id' => ID::custom('audit'), '$permissions' => [Permission::create(Role::any())], diff --git a/composer.lock b/composer.lock index 3e6b49307f..279ad2427b 100644 --- a/composer.lock +++ b/composer.lock @@ -2453,20 +2453,20 @@ }, { "name": "ramsey/uuid", - "version": "4.9.1", + "version": "4.9.2", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "81f941f6f729b1e3ceea61d9d014f8b6c6800440" + "reference": "8429c78ca35a09f27565311b98101e2826affde0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/81f941f6f729b1e3ceea61d9d014f8b6c6800440", - "reference": "81f941f6f729b1e3ceea61d9d014f8b6c6800440", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/8429c78ca35a09f27565311b98101e2826affde0", + "reference": "8429c78ca35a09f27565311b98101e2826affde0", "shasum": "" }, "require": { - "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14", + "brick/math": "^0.8.16 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14", "php": "^8.0", "ramsey/collection": "^1.2 || ^2.0" }, @@ -2525,9 +2525,9 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.9.1" + "source": "https://github.com/ramsey/uuid/tree/4.9.2" }, - "time": "2025-09-04T20:59:21+00:00" + "time": "2025-12-14T04:43:48+00:00" }, { "name": "spomky-labs/otphp", @@ -3556,12 +3556,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "5b5a5440eb37ee6c6b7fc717868e6965b19c003f" + "reference": "bea15e59f63d1b0fceabf53bf73bed3962d176d5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/5b5a5440eb37ee6c6b7fc717868e6965b19c003f", - "reference": "5b5a5440eb37ee6c6b7fc717868e6965b19c003f", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/bea15e59f63d1b0fceabf53bf73bed3962d176d5", + "reference": "bea15e59f63d1b0fceabf53bf73bed3962d176d5", "shasum": "" }, "require": { @@ -3597,7 +3597,7 @@ "issues": "https://github.com/utopia-php/audit/issues", "source": "https://github.com/utopia-php/audit/tree/feat-db-3.x" }, - "time": "2025-12-14T02:29:51+00:00" + "time": "2025-12-14T06:56:09+00:00" }, { "name": "utopia-php/auth", diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 38624367c9..40e8d45153 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -9,7 +9,7 @@ use Appwrite\Extend\Exception; use Executor\Executor; use Throwable; use Utopia\Abuse\Adapters\TimeLimit\Database as AbuseDatabase; -use Utopia\Audit\Audit; +use Utopia\Audit\Adapter\SQL; use Utopia\Cache\Adapter\Filesystem; use Utopia\Cache\Cache; use Utopia\CLI\Console; @@ -517,7 +517,7 @@ class Deletes extends Action $projectCollectionIds = [ ...\array_keys(Config::getParam('collections', [])['projects']), - Audit::COLLECTION, + SQL::COLLECTION, AbuseDatabase::COLLECTION, ]; @@ -786,7 +786,7 @@ class Deletes extends Action $dbForProject = $getProjectDB($project); try { - $this->deleteByGroup(Audit::COLLECTION, [ + $this->deleteByGroup(SQL::COLLECTION, [ Query::select([...$this->selects, 'time']), Query::lessThan('time', $auditRetention), Query::orderDesc('time'), From f270e47b48ba7450bdf0c6d6f2e8ca40a89cea85 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 14 Dec 2025 07:50:21 +0000 Subject: [PATCH 07/23] more fixes to audit queries --- app/controllers/api/account.php | 10 +++++---- app/controllers/api/messaging.php | 22 ++++++++++++++----- app/controllers/api/teams.php | 7 ++++-- .../Collections/Documents/Logs/XList.php | 7 ++++-- .../Http/Databases/Collections/Logs/XList.php | 17 ++++++++------ .../Databases/Http/Databases/Logs/XList.php | 17 ++++++++------ .../Databases/Http/TablesDB/Logs/XList.php | 17 ++++++++------ 7 files changed, 62 insertions(+), 35 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index ada4a98de9..df1c6a35aa 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -2972,7 +2972,8 @@ App::get('/v1/account/logs') ->inject('locale') ->inject('geodb') ->inject('dbForProject') - ->action(function (array $queries, bool $includeTotal, Response $response, Document $user, Locale $locale, Reader $geodb, Database $dbForProject) { + ->inject('audit') + ->action(function (array $queries, bool $includeTotal, Response $response, Document $user, Locale $locale, Reader $geodb, Database $dbForProject, Audit $audit) { try { $queries = Query::parseQueries($queries); @@ -2980,9 +2981,10 @@ App::get('/v1/account/logs') throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } - $audit = new EventAudit($dbForProject); - - $logs = $audit->getLogsByUser($user->getSequence(), $queries); + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + $logs = $audit->getLogsByUser($user->getSequence(), offset: $offset, limit: $limit); $output = []; diff --git a/app/controllers/api/messaging.php b/app/controllers/api/messaging.php index eed12c3376..72abce087b 100644 --- a/app/controllers/api/messaging.php +++ b/app/controllers/api/messaging.php @@ -1211,7 +1211,7 @@ App::get('/v1/messaging/providers/:providerId/logs') } $response->dynamic(new Document([ - 'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0, + 'total' => $includeTotal ? $audit->countLogsByResource($resource, $filterQueries) : 0, 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); @@ -2568,7 +2568,10 @@ App::get('/v1/messaging/topics/:topicId/logs') } $resource = 'topic/' . $topicId; - $logs = $audit->getLogsByResource($resource, $queries); + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); $output = []; @@ -2616,7 +2619,7 @@ App::get('/v1/messaging/topics/:topicId/logs') } $response->dynamic(new Document([ - 'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0, + 'total' => $includeTotal ? $audit->countLogsByResource($resource) : 0, 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); @@ -2985,7 +2988,10 @@ App::get('/v1/messaging/subscribers/:subscriberId/logs') } $resource = 'subscriber/' . $subscriberId; - $logs = $audit->getLogsByResource($resource, $queries); + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); $output = []; @@ -3033,7 +3039,7 @@ App::get('/v1/messaging/subscribers/:subscriberId/logs') } $response->dynamic(new Document([ - 'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0, + 'total' => $includeTotal ? $audit->countLogsByResource($resource) : 0, 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); @@ -3780,7 +3786,11 @@ App::get('/v1/messaging/messages/:messageId/logs') } $resource = 'message/' . $messageId; - $logs = $audit->getLogsByResource($resource, $queries); + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + $filterQueries = $grouped['filters'] ?? []; + $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); $output = []; diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 04a43577ad..cc35f0d264 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -1480,7 +1480,10 @@ App::get('/v1/teams/:teamId/logs') } $resource = 'team/' . $team->getId(); - $logs = $audit->getLogsByResource($resource, $queries); + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); $output = []; @@ -1527,7 +1530,7 @@ App::get('/v1/teams/:teamId/logs') } } $response->dynamic(new Document([ - 'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0, + 'total' => $includeTotal ? $audit->countLogsByResource($resource) : 0, 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php index 292bed4c36..e0b595ebd1 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php @@ -103,7 +103,10 @@ class XList extends Action $context = $this->getContext(); $resource = "database/$databaseId/$type/$collectionId/$context/{$document->getId()}"; - $logs = $audit->getLogsByResource($resource, $queries); + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); $output = []; @@ -152,7 +155,7 @@ class XList extends Action $response->dynamic(new Document([ 'logs' => $output, - 'total' => $audit->countLogsByResource($resource, $queries), + 'total' => $audit->countLogsByResource($resource), ]), $this->getResponseModel()); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php index 2244bfd2d7..73c615697a 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php @@ -67,11 +67,11 @@ class XList extends Action ->param('databaseId', '', new UID(), 'Database ID.') ->param('collectionId', '', new UID(), 'Collection ID.') ->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true) - ->inject('response') - ->inject('dbForProject') - ->inject('locale') - ->inject('geodb') - ->inject('audit') + ->inject('response') + ->inject('dbForProject') + ->inject('locale') + ->inject('geodb') + ->inject('audit') ->callback($this->action(...)); } @@ -98,7 +98,10 @@ class XList extends Action $context = $this->getContext(); $resource = "database/$databaseId/$context/$collectionId"; - $logs = $audit->getLogsByResource($resource, $queries); + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); $output = []; @@ -147,7 +150,7 @@ class XList extends Action $response->dynamic(new Document([ 'logs' => $output, - 'total' => $audit->countLogsByResource($resource, $queries), + 'total' => $audit->countLogsByResource($resource), ]), $this->getResponseModel()); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php index be30a0fad8..1d828977c4 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php @@ -63,11 +63,11 @@ class XList extends Action ]) ->param('databaseId', '', new UID(), 'Database ID.') ->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true) - ->inject('response') - ->inject('dbForProject') - ->inject('locale') - ->inject('geodb') - ->inject('audit') + ->inject('response') + ->inject('dbForProject') + ->inject('locale') + ->inject('geodb') + ->inject('audit') ->callback($this->action(...)); } @@ -86,7 +86,10 @@ class XList extends Action } $resource = 'database/' . $databaseId; - $logs = $audit->getLogsByResource($resource, $queries); + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); $output = []; @@ -133,7 +136,7 @@ class XList extends Action } $response->dynamic(new Document([ - 'total' => $audit->countLogsByResource($resource, $queries), + 'total' => $audit->countLogsByResource($resource), 'logs' => $output, ]), UtopiaResponse::MODEL_LOG_LIST); } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php index ed2aaa848c..b37d38dfe1 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php @@ -58,11 +58,11 @@ class XList extends Action ]) ->param('databaseId', '', new UID(), 'Database ID.') ->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true) - ->inject('response') - ->inject('dbForProject') - ->inject('locale') - ->inject('geodb') - ->inject('audit') + ->inject('response') + ->inject('dbForProject') + ->inject('locale') + ->inject('geodb') + ->inject('audit') ->callback($this->action(...)); } @@ -81,7 +81,10 @@ class XList extends Action } $resource = 'database/' . $databaseId; - $logs = $audit->getLogsByResource($resource, $queries); + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); $output = []; @@ -128,7 +131,7 @@ class XList extends Action } $response->dynamic(new Document([ - 'total' => $audit->countLogsByResource($resource, $queries), + 'total' => $audit->countLogsByResource($resource), 'logs' => $output, ]), UtopiaResponse::MODEL_LOG_LIST); } From 1199c1fc5240328b0305d8bd35d14acd7267596d Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 14 Dec 2025 07:57:37 +0000 Subject: [PATCH 08/23] fix typo --- src/Appwrite/Platform/Workers/Audits.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index 369a67116d..c64591632d 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -4,7 +4,7 @@ namespace Appwrite\Platform\Workers; use Exception; use Throwable; -use Utopia\Audit\Adapters\Database as AdapterDatabase; +use Utopia\Audit\Adapter\Database as AdapterDatabase; use Utopia\Audit\Audit; use Utopia\CLI\Console; use Utopia\Database\Document; From 667285d53606df7b879016a8b1478005b918a4bc Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 14 Dec 2025 07:58:16 +0000 Subject: [PATCH 09/23] fix tyupe --- app/controllers/api/account.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index df1c6a35aa..62bc4231b6 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -37,7 +37,7 @@ use libphonenumber\PhoneNumberUtil; use MaxMind\Db\Reader; use Utopia\Abuse\Abuse; use Utopia\App; -use Utopia\Audit\Audit as EventAudit; +use Utopia\Audit\Audit; use Utopia\Auth\Hashes\Sha; use Utopia\Auth\Proofs\Code as ProofsCode; use Utopia\Auth\Proofs\Password as ProofsPassword; From 2043470bd01936d8d2c4df14c3dc352e8b661908 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 14 Dec 2025 08:00:31 +0000 Subject: [PATCH 10/23] fix typo --- app/controllers/api/account.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 62bc4231b6..c40c374c91 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -3013,7 +3013,7 @@ App::get('/v1/account/logs') } $response->dynamic(new Document([ - 'total' => $includeTotal ? $audit->countLogsByUser($user->getSequence(), $queries) : 0, + 'total' => $includeTotal ? $audit->countLogsByUser($user->getSequence()) : 0, 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); From 2437d2be779c3176dc23d1301fc7f560f0d1e4a0 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 14 Dec 2025 08:30:22 +0000 Subject: [PATCH 11/23] Upgrade audit and fix --- composer.lock | 8 ++++---- src/Appwrite/Platform/Workers/Audits.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index 279ad2427b..e0633c82dc 100644 --- a/composer.lock +++ b/composer.lock @@ -3556,12 +3556,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "bea15e59f63d1b0fceabf53bf73bed3962d176d5" + "reference": "a83dec21b3b9b7fc85fd8cf92563b2fd174a39cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/bea15e59f63d1b0fceabf53bf73bed3962d176d5", - "reference": "bea15e59f63d1b0fceabf53bf73bed3962d176d5", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/a83dec21b3b9b7fc85fd8cf92563b2fd174a39cb", + "reference": "a83dec21b3b9b7fc85fd8cf92563b2fd174a39cb", "shasum": "" }, "require": { @@ -3597,7 +3597,7 @@ "issues": "https://github.com/utopia-php/audit/issues", "source": "https://github.com/utopia-php/audit/tree/feat-db-3.x" }, - "time": "2025-12-14T06:56:09+00:00" + "time": "2025-12-14T08:29:40+00:00" }, { "name": "utopia-php/auth", diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index c64591632d..3349367adf 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -103,7 +103,7 @@ class Audits extends Action 'mode' => $mode, 'data' => $auditPayload, ], - 'timestamp' => date("Y-m-d H:i:s", $message->getTimestamp()), + 'time' => date("Y-m-d H:i:s", $message->getTimestamp()), ]; if (isset($this->logs[$project->getSequence()])) { From 99966b5a247cc05507bb935ea4cc66e26474d857 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 14 Dec 2025 08:35:40 +0000 Subject: [PATCH 12/23] upgrade audit --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index e0633c82dc..1f0fdc69e0 100644 --- a/composer.lock +++ b/composer.lock @@ -3556,12 +3556,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "a83dec21b3b9b7fc85fd8cf92563b2fd174a39cb" + "reference": "c0a0d1679231c4c979f950458c273b04971b5f08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/a83dec21b3b9b7fc85fd8cf92563b2fd174a39cb", - "reference": "a83dec21b3b9b7fc85fd8cf92563b2fd174a39cb", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/c0a0d1679231c4c979f950458c273b04971b5f08", + "reference": "c0a0d1679231c4c979f950458c273b04971b5f08", "shasum": "" }, "require": { @@ -3597,7 +3597,7 @@ "issues": "https://github.com/utopia-php/audit/issues", "source": "https://github.com/utopia-php/audit/tree/feat-db-3.x" }, - "time": "2025-12-14T08:29:40+00:00" + "time": "2025-12-14T08:34:27+00:00" }, { "name": "utopia-php/auth", From 1a205c3f3ba765ad19890cd1e1e2bb20c938ee08 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 14 Dec 2025 08:50:39 +0000 Subject: [PATCH 13/23] upgrade audit --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 1f0fdc69e0..0a6a2a1f72 100644 --- a/composer.lock +++ b/composer.lock @@ -3556,12 +3556,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "c0a0d1679231c4c979f950458c273b04971b5f08" + "reference": "4f77e217c86f0cb27d2b51b5e462411ae3579f80" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/c0a0d1679231c4c979f950458c273b04971b5f08", - "reference": "c0a0d1679231c4c979f950458c273b04971b5f08", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/4f77e217c86f0cb27d2b51b5e462411ae3579f80", + "reference": "4f77e217c86f0cb27d2b51b5e462411ae3579f80", "shasum": "" }, "require": { @@ -3597,7 +3597,7 @@ "issues": "https://github.com/utopia-php/audit/issues", "source": "https://github.com/utopia-php/audit/tree/feat-db-3.x" }, - "time": "2025-12-14T08:34:27+00:00" + "time": "2025-12-14T08:49:56+00:00" }, { "name": "utopia-php/auth", From 0037305e16be571e8ccb42c1097a7eac461694b2 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 15 Dec 2025 02:12:35 +0000 Subject: [PATCH 14/23] Fix: failing tests --- app/controllers/api/messaging.php | 22 +++++-------------- app/controllers/api/projects.php | 8 +++---- app/controllers/api/teams.php | 7 ++---- .../Collections/Documents/Logs/XList.php | 7 ++---- .../Http/Databases/Collections/Logs/XList.php | 17 ++++++-------- .../Databases/Http/Databases/Logs/XList.php | 19 +++++++--------- .../Databases/Http/TablesDB/Logs/XList.php | 17 ++++++-------- src/Appwrite/Platform/Workers/Audits.php | 4 ++-- .../Account/AccountCustomClientTest.php | 2 ++ 9 files changed, 39 insertions(+), 64 deletions(-) diff --git a/app/controllers/api/messaging.php b/app/controllers/api/messaging.php index 72abce087b..eed12c3376 100644 --- a/app/controllers/api/messaging.php +++ b/app/controllers/api/messaging.php @@ -1211,7 +1211,7 @@ App::get('/v1/messaging/providers/:providerId/logs') } $response->dynamic(new Document([ - 'total' => $includeTotal ? $audit->countLogsByResource($resource, $filterQueries) : 0, + 'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0, 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); @@ -2568,10 +2568,7 @@ App::get('/v1/messaging/topics/:topicId/logs') } $resource = 'topic/' . $topicId; - $grouped = Query::groupByType($queries); - $limit = $grouped['limit'] ?? 25; - $offset = $grouped['offset'] ?? 0; - $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); + $logs = $audit->getLogsByResource($resource, $queries); $output = []; @@ -2619,7 +2616,7 @@ App::get('/v1/messaging/topics/:topicId/logs') } $response->dynamic(new Document([ - 'total' => $includeTotal ? $audit->countLogsByResource($resource) : 0, + 'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0, 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); @@ -2988,10 +2985,7 @@ App::get('/v1/messaging/subscribers/:subscriberId/logs') } $resource = 'subscriber/' . $subscriberId; - $grouped = Query::groupByType($queries); - $limit = $grouped['limit'] ?? 25; - $offset = $grouped['offset'] ?? 0; - $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); + $logs = $audit->getLogsByResource($resource, $queries); $output = []; @@ -3039,7 +3033,7 @@ App::get('/v1/messaging/subscribers/:subscriberId/logs') } $response->dynamic(new Document([ - 'total' => $includeTotal ? $audit->countLogsByResource($resource) : 0, + 'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0, 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); @@ -3786,11 +3780,7 @@ App::get('/v1/messaging/messages/:messageId/logs') } $resource = 'message/' . $messageId; - $grouped = Query::groupByType($queries); - $limit = $grouped['limit'] ?? 25; - $offset = $grouped['offset'] ?? 0; - $filterQueries = $grouped['filters'] ?? []; - $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); + $logs = $audit->getLogsByResource($resource, $queries); $output = []; diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index ed6fa20eba..364a7914b4 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -21,7 +21,6 @@ use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use PHPMailer\PHPMailer\PHPMailer; use Utopia\App; -use Utopia\Audit\Adapter\Database as AdapterDatabase; use Utopia\Audit\Audit; use Utopia\Cache\Cache; use Utopia\Config\Config; @@ -248,15 +247,14 @@ App::post('/v1/projects') } if ($create || $projectTables) { - $adapter = new AdapterDatabase($dbForProject); + $adapter = new \Utopia\Audit\Adapters\Database($dbForProject); $audit = new Audit($adapter); $audit->setup(); } if (!$create && $sharedTablesV1) { - $adapter = new AdapterDatabase($dbForProject); - $attributes = $adapter->getAttributeDocuments(); - $indexes = $adapter->getIndexDocuments(); + $attributes = \array_map(fn ($attribute) => new Document($attribute), Audit::ATTRIBUTES); + $indexes = \array_map(fn (array $index) => new Document($index), Audit::INDEXES); $dbForProject->createDocument(Database::METADATA, new Document([ '$id' => ID::custom('audit'), '$permissions' => [Permission::create(Role::any())], diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index cc35f0d264..04a43577ad 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -1480,10 +1480,7 @@ App::get('/v1/teams/:teamId/logs') } $resource = 'team/' . $team->getId(); - $grouped = Query::groupByType($queries); - $limit = $grouped['limit'] ?? 25; - $offset = $grouped['offset'] ?? 0; - $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); + $logs = $audit->getLogsByResource($resource, $queries); $output = []; @@ -1530,7 +1527,7 @@ App::get('/v1/teams/:teamId/logs') } } $response->dynamic(new Document([ - 'total' => $includeTotal ? $audit->countLogsByResource($resource) : 0, + 'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0, 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php index e0b595ebd1..292bed4c36 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php @@ -103,10 +103,7 @@ class XList extends Action $context = $this->getContext(); $resource = "database/$databaseId/$type/$collectionId/$context/{$document->getId()}"; - $grouped = Query::groupByType($queries); - $limit = $grouped['limit'] ?? 25; - $offset = $grouped['offset'] ?? 0; - $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); + $logs = $audit->getLogsByResource($resource, $queries); $output = []; @@ -155,7 +152,7 @@ class XList extends Action $response->dynamic(new Document([ 'logs' => $output, - 'total' => $audit->countLogsByResource($resource), + 'total' => $audit->countLogsByResource($resource, $queries), ]), $this->getResponseModel()); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php index 73c615697a..2244bfd2d7 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php @@ -67,11 +67,11 @@ class XList extends Action ->param('databaseId', '', new UID(), 'Database ID.') ->param('collectionId', '', new UID(), 'Collection ID.') ->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true) - ->inject('response') - ->inject('dbForProject') - ->inject('locale') - ->inject('geodb') - ->inject('audit') + ->inject('response') + ->inject('dbForProject') + ->inject('locale') + ->inject('geodb') + ->inject('audit') ->callback($this->action(...)); } @@ -98,10 +98,7 @@ class XList extends Action $context = $this->getContext(); $resource = "database/$databaseId/$context/$collectionId"; - $grouped = Query::groupByType($queries); - $limit = $grouped['limit'] ?? 25; - $offset = $grouped['offset'] ?? 0; - $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); + $logs = $audit->getLogsByResource($resource, $queries); $output = []; @@ -150,7 +147,7 @@ class XList extends Action $response->dynamic(new Document([ 'logs' => $output, - 'total' => $audit->countLogsByResource($resource), + 'total' => $audit->countLogsByResource($resource, $queries), ]), $this->getResponseModel()); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php index 1d828977c4..42081127d5 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php @@ -63,15 +63,15 @@ class XList extends Action ]) ->param('databaseId', '', new UID(), 'Database ID.') ->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true) - ->inject('response') - ->inject('dbForProject') - ->inject('locale') - ->inject('geodb') - ->inject('audit') + ->inject('response') + ->inject('dbForProject') + ->inject('locale') + ->inject('geodb') + ->inject('audit') ->callback($this->action(...)); } - public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void + public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void { $database = $dbForProject->getDocument('databases', $databaseId); @@ -86,10 +86,7 @@ class XList extends Action } $resource = 'database/' . $databaseId; - $grouped = Query::groupByType($queries); - $limit = $grouped['limit'] ?? 25; - $offset = $grouped['offset'] ?? 0; - $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); + $logs = $audit->getLogsByResource($resource, $queries); $output = []; @@ -136,7 +133,7 @@ class XList extends Action } $response->dynamic(new Document([ - 'total' => $audit->countLogsByResource($resource), + 'total' => $audit->countLogsByResource($resource, $queries), 'logs' => $output, ]), UtopiaResponse::MODEL_LOG_LIST); } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php index b37d38dfe1..ed2aaa848c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php @@ -58,11 +58,11 @@ class XList extends Action ]) ->param('databaseId', '', new UID(), 'Database ID.') ->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true) - ->inject('response') - ->inject('dbForProject') - ->inject('locale') - ->inject('geodb') - ->inject('audit') + ->inject('response') + ->inject('dbForProject') + ->inject('locale') + ->inject('geodb') + ->inject('audit') ->callback($this->action(...)); } @@ -81,10 +81,7 @@ class XList extends Action } $resource = 'database/' . $databaseId; - $grouped = Query::groupByType($queries); - $limit = $grouped['limit'] ?? 25; - $offset = $grouped['offset'] ?? 0; - $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); + $logs = $audit->getLogsByResource($resource, $queries); $output = []; @@ -131,7 +128,7 @@ class XList extends Action } $response->dynamic(new Document([ - 'total' => $audit->countLogsByResource($resource), + 'total' => $audit->countLogsByResource($resource, $queries), 'logs' => $output, ]), UtopiaResponse::MODEL_LOG_LIST); } diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index 3349367adf..2f0364e408 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -4,8 +4,8 @@ namespace Appwrite\Platform\Workers; use Exception; use Throwable; -use Utopia\Audit\Adapter\Database as AdapterDatabase; use Utopia\Audit\Audit; +use Utopia\Audit\Adapters\Database as AdapterDatabase; use Utopia\CLI\Console; use Utopia\Database\Document; use Utopia\Database\Exception\Authorization; @@ -103,7 +103,7 @@ class Audits extends Action 'mode' => $mode, 'data' => $auditPayload, ], - 'time' => date("Y-m-d H:i:s", $message->getTimestamp()), + 'timestamp' => date("Y-m-d H:i:s", $message->getTimestamp()), ]; if (isset($this->logs[$project->getSequence()])) { diff --git a/tests/e2e/Services/Account/AccountCustomClientTest.php b/tests/e2e/Services/Account/AccountCustomClientTest.php index 457799f991..a1cc718aad 100644 --- a/tests/e2e/Services/Account/AccountCustomClientTest.php +++ b/tests/e2e/Services/Account/AccountCustomClientTest.php @@ -288,6 +288,8 @@ class AccountCustomClientTest extends Scope 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, ])); + var_dump($response['body']['logs']); + $this->assertEquals(200, $response['headers']['status-code']); $this->assertIsArray($response['body']['logs']); $this->assertNotEmpty($response['body']['logs']); From 69ad4ae9303d48ca7578d1cae7bf6e8aabedbb5f Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 15 Dec 2025 02:15:45 +0000 Subject: [PATCH 15/23] Fix format --- app/controllers/api/projects.php | 4 ++-- .../Http/Databases/Collections/Logs/XList.php | 10 +++++----- .../Modules/Databases/Http/Databases/Logs/XList.php | 12 ++++++------ .../Modules/Databases/Http/TablesDB/Logs/XList.php | 10 +++++----- src/Appwrite/Platform/Workers/Audits.php | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 364a7914b4..ad8ed2047f 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -295,7 +295,7 @@ App::post('/v1/projects') // Hook allowing instant project mirroring during migration // Outside of migration, hook is not registered and has no effect - $hooks->trigger('afterProjectCreation', [ $project, $pools, $cache ]); + $hooks->trigger('afterProjectCreation', [$project, $pools, $cache]); $response ->setStatusCode(Response::STATUS_CODE_CREATED) @@ -2666,7 +2666,7 @@ App::patch('/v1/projects/:projectId/auth/session-invalidation') $auths = $project->getAttribute('auths', []); $auths['invalidateSessions'] = $enabled; $dbForPlatform->updateDocument('projects', $project->getId(), $project - ->setAttribute('auths', $auths)); + ->setAttribute('auths', $auths)); $response->dynamic($project, Response::MODEL_PROJECT); }); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php index 2244bfd2d7..a67af6cff1 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php @@ -67,11 +67,11 @@ class XList extends Action ->param('databaseId', '', new UID(), 'Database ID.') ->param('collectionId', '', new UID(), 'Collection ID.') ->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true) - ->inject('response') - ->inject('dbForProject') - ->inject('locale') - ->inject('geodb') - ->inject('audit') + ->inject('response') + ->inject('dbForProject') + ->inject('locale') + ->inject('geodb') + ->inject('audit') ->callback($this->action(...)); } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php index 42081127d5..6b2878ce9a 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php @@ -63,15 +63,15 @@ class XList extends Action ]) ->param('databaseId', '', new UID(), 'Database ID.') ->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true) - ->inject('response') - ->inject('dbForProject') - ->inject('locale') - ->inject('geodb') - ->inject('audit') + ->inject('response') + ->inject('dbForProject') + ->inject('locale') + ->inject('geodb') + ->inject('audit') ->callback($this->action(...)); } - public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void + public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void { $database = $dbForProject->getDocument('databases', $databaseId); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php index ed2aaa848c..1315d35330 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php @@ -58,11 +58,11 @@ class XList extends Action ]) ->param('databaseId', '', new UID(), 'Database ID.') ->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true) - ->inject('response') - ->inject('dbForProject') - ->inject('locale') - ->inject('geodb') - ->inject('audit') + ->inject('response') + ->inject('dbForProject') + ->inject('locale') + ->inject('geodb') + ->inject('audit') ->callback($this->action(...)); } diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index 2f0364e408..369a67116d 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -4,8 +4,8 @@ namespace Appwrite\Platform\Workers; use Exception; use Throwable; -use Utopia\Audit\Audit; use Utopia\Audit\Adapters\Database as AdapterDatabase; +use Utopia\Audit\Audit; use Utopia\CLI\Console; use Utopia\Database\Document; use Utopia\Database\Exception\Authorization; From 2d3e34fd5aa91d0910cade2b487e8e5fc4d94ea7 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 15 Dec 2025 02:20:10 +0000 Subject: [PATCH 16/23] fix namespace --- app/controllers/api/projects.php | 2 +- src/Appwrite/Platform/Workers/Audits.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index ad8ed2047f..4b54ac1037 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -247,7 +247,7 @@ App::post('/v1/projects') } if ($create || $projectTables) { - $adapter = new \Utopia\Audit\Adapters\Database($dbForProject); + $adapter = new \Utopia\Audit\Adapter\Database($dbForProject); $audit = new Audit($adapter); $audit->setup(); } diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index 369a67116d..c64591632d 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -4,7 +4,7 @@ namespace Appwrite\Platform\Workers; use Exception; use Throwable; -use Utopia\Audit\Adapters\Database as AdapterDatabase; +use Utopia\Audit\Adapter\Database as AdapterDatabase; use Utopia\Audit\Audit; use Utopia\CLI\Console; use Utopia\Database\Document; From ace9d8674414300bbe5c849f238be8244c6cbef2 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 15 Dec 2025 02:41:56 +0000 Subject: [PATCH 17/23] fix attribute --- src/Appwrite/Platform/Workers/Audits.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index c64591632d..3349367adf 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -103,7 +103,7 @@ class Audits extends Action 'mode' => $mode, 'data' => $auditPayload, ], - 'timestamp' => date("Y-m-d H:i:s", $message->getTimestamp()), + 'time' => date("Y-m-d H:i:s", $message->getTimestamp()), ]; if (isset($this->logs[$project->getSequence()])) { From dc3459edd0cf816ac69fd1c3eaddc7c6103ab7ac Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 15 Dec 2025 02:43:27 +0000 Subject: [PATCH 18/23] remove dump --- tests/e2e/Services/Account/AccountCustomClientTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/e2e/Services/Account/AccountCustomClientTest.php b/tests/e2e/Services/Account/AccountCustomClientTest.php index a1cc718aad..457799f991 100644 --- a/tests/e2e/Services/Account/AccountCustomClientTest.php +++ b/tests/e2e/Services/Account/AccountCustomClientTest.php @@ -288,8 +288,6 @@ class AccountCustomClientTest extends Scope 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, ])); - var_dump($response['body']['logs']); - $this->assertEquals(200, $response['headers']['status-code']); $this->assertIsArray($response['body']['logs']); $this->assertNotEmpty($response['body']['logs']); From 801219374c6924da15abca4d316f4d25c707e694 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 15 Dec 2025 02:50:21 +0000 Subject: [PATCH 19/23] Fix queries --- app/controllers/api/messaging.php | 26 ++++++++++++++----- app/controllers/api/teams.php | 8 ++++-- app/controllers/api/users.php | 8 ++++-- .../Collections/Documents/Logs/XList.php | 9 +++++-- .../Http/Databases/Collections/Logs/XList.php | 8 ++++-- .../Databases/Http/Databases/Logs/XList.php | 9 +++++-- .../Databases/Http/TablesDB/Logs/XList.php | 8 ++++-- 7 files changed, 57 insertions(+), 19 deletions(-) diff --git a/app/controllers/api/messaging.php b/app/controllers/api/messaging.php index eed12c3376..e1e595d992 100644 --- a/app/controllers/api/messaging.php +++ b/app/controllers/api/messaging.php @@ -1211,7 +1211,7 @@ App::get('/v1/messaging/providers/:providerId/logs') } $response->dynamic(new Document([ - 'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0, + 'total' => $includeTotal ? $audit->countLogsByResource($resource) : 0, 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); @@ -2567,8 +2567,12 @@ App::get('/v1/messaging/topics/:topicId/logs') throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + $resource = 'topic/' . $topicId; - $logs = $audit->getLogsByResource($resource, $queries); + $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); $output = []; @@ -2616,7 +2620,7 @@ App::get('/v1/messaging/topics/:topicId/logs') } $response->dynamic(new Document([ - 'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0, + 'total' => $includeTotal ? $audit->countLogsByResource($resource) : 0, 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); @@ -2984,8 +2988,12 @@ App::get('/v1/messaging/subscribers/:subscriberId/logs') throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + $resource = 'subscriber/' . $subscriberId; - $logs = $audit->getLogsByResource($resource, $queries); + $logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset); $output = []; @@ -3033,7 +3041,7 @@ App::get('/v1/messaging/subscribers/:subscriberId/logs') } $response->dynamic(new Document([ - 'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0, + 'total' => $includeTotal ? $audit->countLogsByResource($resource) : 0, 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); @@ -3779,8 +3787,12 @@ App::get('/v1/messaging/messages/:messageId/logs') throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + $resource = 'message/' . $messageId; - $logs = $audit->getLogsByResource($resource, $queries); + $logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset); $output = []; @@ -3828,7 +3840,7 @@ App::get('/v1/messaging/messages/:messageId/logs') } $response->dynamic(new Document([ - 'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0, + 'total' => $includeTotal ? $audit->countLogsByResource($resource) : 0, 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 04a43577ad..800e404027 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -1479,8 +1479,12 @@ App::get('/v1/teams/:teamId/logs') throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + $resource = 'team/' . $team->getId(); - $logs = $audit->getLogsByResource($resource, $queries); + $logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit); $output = []; @@ -1527,7 +1531,7 @@ App::get('/v1/teams/:teamId/logs') } } $response->dynamic(new Document([ - 'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0, + 'total' => $includeTotal ? $audit->countLogsByResource($resource) : 0, 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 161b5a3298..de05f78223 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -959,7 +959,11 @@ App::get('/v1/users/:userId/logs') throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } - $logs = $audit->getLogsByUser($user->getSequence(), $queries); + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + + $logs = $audit->getLogsByUser($user->getSequence(), limit: $limit, offset: $offset); $output = []; foreach ($logs as $i => &$log) { $log['userAgent'] = (!empty($log['userAgent'])) ? $log['userAgent'] : 'UNKNOWN'; @@ -999,7 +1003,7 @@ App::get('/v1/users/:userId/logs') } $response->dynamic(new Document([ - 'total' => $includeTotal ? $audit->countLogsByUser($user->getSequence(), $queries) : 0, + 'total' => $includeTotal ? $audit->countLogsByUser($user->getSequence()) : 0, 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php index 292bed4c36..a4dd38ef67 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php @@ -103,7 +103,12 @@ class XList extends Action $context = $this->getContext(); $resource = "database/$databaseId/$type/$collectionId/$context/{$document->getId()}"; - $logs = $audit->getLogsByResource($resource, $queries); + + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + + $logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset); $output = []; @@ -152,7 +157,7 @@ class XList extends Action $response->dynamic(new Document([ 'logs' => $output, - 'total' => $audit->countLogsByResource($resource, $queries), + 'total' => $audit->countLogsByResource($resource), ]), $this->getResponseModel()); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php index a67af6cff1..0f5a57c6e9 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php @@ -96,9 +96,13 @@ class XList extends Action throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + $context = $this->getContext(); $resource = "database/$databaseId/$context/$collectionId"; - $logs = $audit->getLogsByResource($resource, $queries); + $logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset); $output = []; @@ -147,7 +151,7 @@ class XList extends Action $response->dynamic(new Document([ 'logs' => $output, - 'total' => $audit->countLogsByResource($resource, $queries), + 'total' => $audit->countLogsByResource($resource), ]), $this->getResponseModel()); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php index 6b2878ce9a..319f07db1c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Logs/XList.php @@ -85,8 +85,13 @@ class XList extends Action throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } + + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + $resource = 'database/' . $databaseId; - $logs = $audit->getLogsByResource($resource, $queries); + $logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset); $output = []; @@ -133,7 +138,7 @@ class XList extends Action } $response->dynamic(new Document([ - 'total' => $audit->countLogsByResource($resource, $queries), + 'total' => $audit->countLogsByResource($resource), 'logs' => $output, ]), UtopiaResponse::MODEL_LOG_LIST); } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php index 1315d35330..88745555d9 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Logs/XList.php @@ -80,8 +80,12 @@ class XList extends Action throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } + $grouped = Query::groupByType($queries); + $limit = $grouped['limit'] ?? 25; + $offset = $grouped['offset'] ?? 0; + $resource = 'database/' . $databaseId; - $logs = $audit->getLogsByResource($resource, $queries); + $logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset); $output = []; @@ -128,7 +132,7 @@ class XList extends Action } $response->dynamic(new Document([ - 'total' => $audit->countLogsByResource($resource, $queries), + 'total' => $audit->countLogsByResource($resource), 'logs' => $output, ]), UtopiaResponse::MODEL_LOG_LIST); } From 63c2d72b2e15595a63614d75e4a9eb89f02de88d Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 15 Dec 2025 03:58:00 +0000 Subject: [PATCH 20/23] Fix logs --- .../Modules/Databases/Http/TablesDB/Tables/Logs/XList.php | 1 + .../Modules/Databases/Http/TablesDB/Tables/Rows/Logs/XList.php | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Logs/XList.php index 0680649544..5eab050b7e 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Logs/XList.php @@ -50,6 +50,7 @@ class XList extends CollectionLogXList ->inject('dbForProject') ->inject('locale') ->inject('geodb') + ->inject('audit') ->callback($this->action(...)); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Logs/XList.php index 5f1efa2953..27bd82195d 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Logs/XList.php @@ -51,6 +51,7 @@ class XList extends DocumentLogXList ->inject('dbForProject') ->inject('locale') ->inject('geodb') + ->inject('audit') ->callback($this->action(...)); } } From 5519086c2918eb137a89ba268c3d964ac73429d2 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Wed, 24 Dec 2025 01:30:02 +0000 Subject: [PATCH 21/23] Use db 3.x audit --- app/controllers/api/projects.php | 8 +- app/worker.php | 15 ++++ composer.json | 2 +- composer.lock | 110 +++++++++++------------ src/Appwrite/Platform/Workers/Audits.php | 11 +-- 5 files changed, 80 insertions(+), 66 deletions(-) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index c8064809ce..db4e0063c5 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -21,6 +21,7 @@ use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use PHPMailer\PHPMailer\PHPMailer; use Utopia\App; +use Utopia\Audit\Adapter\Database as AdapterDatabase; use Utopia\Audit\Audit; use Utopia\Cache\Cache; use Utopia\Config\Config; @@ -247,14 +248,15 @@ App::post('/v1/projects') } if ($create || $projectTables) { - $adapter = new \Utopia\Audit\Adapter\Database($dbForProject); + $adapter = new AdapterDatabase($dbForProject); $audit = new Audit($adapter); $audit->setup(); } if (!$create && $sharedTablesV1) { - $attributes = \array_map(fn ($attribute) => new Document($attribute), Audit::ATTRIBUTES); - $indexes = \array_map(fn (array $index) => new Document($index), Audit::INDEXES); + $adapter = new AdapterDatabase($dbForProject); + $attributes = $adapter->getAttributeDocuments(); + $indexes = $adapter->getIndexDocuments(); $dbForProject->createDocument(Database::METADATA, new Document([ '$id' => ID::custom('audit'), '$permissions' => [Permission::create(Role::any())], diff --git a/app/worker.php b/app/worker.php index 76f3bb9e8a..7868861cf4 100644 --- a/app/worker.php +++ b/app/worker.php @@ -21,6 +21,8 @@ use Appwrite\Utopia\Database\Documents\User; use Executor\Executor; use Swoole\Runtime; use Utopia\Abuse\Adapters\TimeLimit\Redis as TimeLimitRedis; +use Utopia\Audit\Adapter\Database as AdapterDatabase; +use Utopia\Audit\Audit as UtopiaAudit; use Utopia\Cache\Adapter\Pool as CachePool; use Utopia\Cache\Adapter\Sharding; use Utopia\Cache\Cache; @@ -450,6 +452,19 @@ Server::setResource('logError', function (Registry $register, Document $project) Server::setResource('executor', fn () => new Executor()); +Server::setResource('getAudit', function (Database $dbForPlatform, callable $getProjectDB) { + return function (Document $project) use ($dbForPlatform, $getProjectDB) { + if ($project->isEmpty() || $project->getId() === 'console') { + $adapter = new AdapterDatabase($dbForPlatform); + return new UtopiaAudit($adapter); + } + + $dbForProject = $getProjectDB($project); + $adapter = new AdapterDatabase($dbForProject); + return new UtopiaAudit($adapter); + }; +}, ['dbForPlatform', 'getProjectDB']); + $pools = $register->get('pools'); $platform = new Appwrite(); $args = $platform->getEnv('argv'); diff --git a/composer.json b/composer.json index be88d8ae5e..1051b40d42 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,7 @@ "appwrite/php-clamav": "2.0.*", "utopia-php/abuse": "1.*", "utopia-php/analytics": "0.10.*", - "utopia-php/audit": "dev-feat-db-3.x", + "utopia-php/audit": "dev-feat-db-3x", "utopia-php/auth": "0.5.*", "utopia-php/cache": "0.13.*", "utopia-php/cli": "0.15.*", diff --git a/composer.lock b/composer.lock index ff6254b821..5dfaab9f67 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d26b9cee30ab2cc3bc5873ac911918d1", + "content-hash": "54b49eb2f01fdf10632c6be6feadb6fe", "packages": [ { "name": "adhocore/jwt", @@ -3552,16 +3552,16 @@ }, { "name": "utopia-php/audit", - "version": "dev-feat-db-3.x", + "version": "dev-feat-db-3x", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "4f77e217c86f0cb27d2b51b5e462411ae3579f80" + "reference": "7b35dab40bce66bda56eeeacd2bbcbf1e823f05f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/4f77e217c86f0cb27d2b51b5e462411ae3579f80", - "reference": "4f77e217c86f0cb27d2b51b5e462411ae3579f80", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/7b35dab40bce66bda56eeeacd2bbcbf1e823f05f", + "reference": "7b35dab40bce66bda56eeeacd2bbcbf1e823f05f", "shasum": "" }, "require": { @@ -3595,9 +3595,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/feat-db-3.x" + "source": "https://github.com/utopia-php/audit/tree/feat-db-3x" }, - "time": "2025-12-14T08:49:56+00:00" + "time": "2025-12-24T01:20:43+00:00" }, { "name": "utopia-php/auth", @@ -3656,16 +3656,16 @@ }, { "name": "utopia-php/cache", - "version": "0.13.1", + "version": "0.13.2", "source": { "type": "git", "url": "https://github.com/utopia-php/cache.git", - "reference": "97220cb3b3822b166ee016d1646e2ae2815dc540" + "reference": "5768498c9f451482f0bf3eede4d6452ddcd4a0f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/97220cb3b3822b166ee016d1646e2ae2815dc540", - "reference": "97220cb3b3822b166ee016d1646e2ae2815dc540", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/5768498c9f451482f0bf3eede4d6452ddcd4a0f6", + "reference": "5768498c9f451482f0bf3eede4d6452ddcd4a0f6", "shasum": "" }, "require": { @@ -3674,7 +3674,7 @@ "ext-redis": "*", "php": ">=8.0", "utopia-php/pools": "0.8.*", - "utopia-php/telemetry": "0.1.*" + "utopia-php/telemetry": "*" }, "require-dev": { "laravel/pint": "1.2.*", @@ -3702,9 +3702,9 @@ ], "support": { "issues": "https://github.com/utopia-php/cache/issues", - "source": "https://github.com/utopia-php/cache/tree/0.13.1" + "source": "https://github.com/utopia-php/cache/tree/0.13.2" }, - "time": "2025-05-09T14:43:52+00:00" + "time": "2025-12-17T08:55:43+00:00" }, { "name": "utopia-php/cli", @@ -3898,16 +3898,16 @@ }, { "name": "utopia-php/database", - "version": "3.6.0", + "version": "3.6.1", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "af15066255a5fd7bd2926de37bcbf3d8500fc155" + "reference": "c8c1b2f5770245dd4006e2680681e3efbe8b1fa7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/af15066255a5fd7bd2926de37bcbf3d8500fc155", - "reference": "af15066255a5fd7bd2926de37bcbf3d8500fc155", + "url": "https://api.github.com/repos/utopia-php/database/zipball/c8c1b2f5770245dd4006e2680681e3efbe8b1fa7", + "reference": "c8c1b2f5770245dd4006e2680681e3efbe8b1fa7", "shasum": "" }, "require": { @@ -3950,9 +3950,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/3.6.0" + "source": "https://github.com/utopia-php/database/tree/3.6.1" }, - "time": "2025-12-08T05:23:04+00:00" + "time": "2025-12-16T09:55:41+00:00" }, { "name": "utopia-php/detector", @@ -4001,23 +4001,23 @@ }, { "name": "utopia-php/dns", - "version": "1.4.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/utopia-php/dns.git", - "reference": "dce3453364a4524b7250db8d8eb74820b814409e" + "reference": "5daf8b683dad877491c4df84c6be24850b2f363b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/dns/zipball/dce3453364a4524b7250db8d8eb74820b814409e", - "reference": "dce3453364a4524b7250db8d8eb74820b814409e", + "url": "https://api.github.com/repos/utopia-php/dns/zipball/5daf8b683dad877491c4df84c6be24850b2f363b", + "reference": "5daf8b683dad877491c4df84c6be24850b2f363b", "shasum": "" }, "require": { "php": ">=8.3", "utopia-php/console": "0.0.*", "utopia-php/domains": "0.9.*", - "utopia-php/telemetry": "0.1.*", + "utopia-php/telemetry": "*", "utopia-php/validators": "0.*" }, "require-dev": { @@ -4052,9 +4052,9 @@ ], "support": { "issues": "https://github.com/utopia-php/dns/issues", - "source": "https://github.com/utopia-php/dns/tree/1.4.0" + "source": "https://github.com/utopia-php/dns/tree/1.4.1" }, - "time": "2025-12-05T10:09:00+00:00" + "time": "2025-12-17T09:09:08+00:00" }, { "name": "utopia-php/domains", @@ -4732,21 +4732,21 @@ }, { "name": "utopia-php/pools", - "version": "0.8.2", + "version": "0.8.3", "source": { "type": "git", "url": "https://github.com/utopia-php/pools.git", - "reference": "05c67aba42eb68ac65489cc1e7fc5db83db2dd4d" + "reference": "ad7d6ba946376e81c603204285ce9a674b6502b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/pools/zipball/05c67aba42eb68ac65489cc1e7fc5db83db2dd4d", - "reference": "05c67aba42eb68ac65489cc1e7fc5db83db2dd4d", + "url": "https://api.github.com/repos/utopia-php/pools/zipball/ad7d6ba946376e81c603204285ce9a674b6502b8", + "reference": "ad7d6ba946376e81c603204285ce9a674b6502b8", "shasum": "" }, "require": { - "php": ">=8.3", - "utopia-php/telemetry": "0.1.*" + "php": ">=8.4", + "utopia-php/telemetry": "*" }, "require-dev": { "laravel/pint": "1.*", @@ -4778,9 +4778,9 @@ ], "support": { "issues": "https://github.com/utopia-php/pools/issues", - "source": "https://github.com/utopia-php/pools/tree/0.8.2" + "source": "https://github.com/utopia-php/pools/tree/0.8.3" }, - "time": "2025-04-17T02:04:54+00:00" + "time": "2025-12-17T09:35:18+00:00" }, { "name": "utopia-php/preloader", @@ -4837,16 +4837,16 @@ }, { "name": "utopia-php/queue", - "version": "0.11.1", + "version": "0.11.2", "source": { "type": "git", "url": "https://github.com/utopia-php/queue.git", - "reference": "498bbbef418b1db71b51e1bb62f5d1d752ddd8d6" + "reference": "a854f7c4abc18e0eca55fc5608cd7088d71eb19f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/queue/zipball/498bbbef418b1db71b51e1bb62f5d1d752ddd8d6", - "reference": "498bbbef418b1db71b51e1bb62f5d1d752ddd8d6", + "url": "https://api.github.com/repos/utopia-php/queue/zipball/a854f7c4abc18e0eca55fc5608cd7088d71eb19f", + "reference": "a854f7c4abc18e0eca55fc5608cd7088d71eb19f", "shasum": "" }, "require": { @@ -4856,7 +4856,7 @@ "utopia-php/fetch": "0.4.*", "utopia-php/framework": "0.33.*", "utopia-php/pools": "0.8.*", - "utopia-php/telemetry": "0.1.*" + "utopia-php/telemetry": "*" }, "require-dev": { "ext-redis": "*", @@ -4897,9 +4897,9 @@ ], "support": { "issues": "https://github.com/utopia-php/queue/issues", - "source": "https://github.com/utopia-php/queue/tree/0.11.1" + "source": "https://github.com/utopia-php/queue/tree/0.11.2" }, - "time": "2025-05-30T11:50:34+00:00" + "time": "2025-12-17T09:32:35+00:00" }, { "name": "utopia-php/registry", @@ -4955,16 +4955,16 @@ }, { "name": "utopia-php/storage", - "version": "0.18.16", + "version": "0.18.18", "source": { "type": "git", "url": "https://github.com/utopia-php/storage.git", - "reference": "0c7b8ad68de8e1eb23ccc8af9f27a30eb832930f" + "reference": "acaea524f315f87b8811a2c34450fe2b502f49d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/0c7b8ad68de8e1eb23ccc8af9f27a30eb832930f", - "reference": "0c7b8ad68de8e1eb23ccc8af9f27a30eb832930f", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/acaea524f315f87b8811a2c34450fe2b502f49d8", + "reference": "acaea524f315f87b8811a2c34450fe2b502f49d8", "shasum": "" }, "require": { @@ -5007,9 +5007,9 @@ ], "support": { "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.18.16" + "source": "https://github.com/utopia-php/storage/tree/0.18.18" }, - "time": "2025-12-03T02:15:45+00:00" + "time": "2025-12-17T07:33:45+00:00" }, { "name": "utopia-php/swoole", @@ -5438,16 +5438,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "1.5.9", + "version": "1.7.1", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "ee434aa00a9185380b9a39bb46bf86d7104d3a93" + "reference": "14b9ebd7f5e3287cd24ef342c38dfa714808e80e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/ee434aa00a9185380b9a39bb46bf86d7104d3a93", - "reference": "ee434aa00a9185380b9a39bb46bf86d7104d3a93", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/14b9ebd7f5e3287cd24ef342c38dfa714808e80e", + "reference": "14b9ebd7f5e3287cd24ef342c38dfa714808e80e", "shasum": "" }, "require": { @@ -5483,9 +5483,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/1.5.9" + "source": "https://github.com/appwrite/sdk-generator/tree/1.7.1" }, - "time": "2025-11-25T05:22:25+00:00" + "time": "2025-12-22T11:47:51+00:00" }, { "name": "doctrine/annotations", @@ -8971,5 +8971,5 @@ "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.9.0" + "plugin-api-version": "2.6.0" } diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index 3349367adf..91dbb7cb00 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -4,8 +4,6 @@ namespace Appwrite\Platform\Workers; use Exception; use Throwable; -use Utopia\Audit\Adapter\Database as AdapterDatabase; -use Utopia\Audit\Audit; use Utopia\CLI\Console; use Utopia\Database\Document; use Utopia\Database\Exception\Authorization; @@ -43,8 +41,8 @@ class Audits extends Action $this ->desc('Audits worker') ->inject('message') - ->inject('getProjectDB') ->inject('project') + ->inject('getAudit') ->callback($this->action(...)); $this->lastTriggeredTime = time(); @@ -55,13 +53,14 @@ class Audits extends Action * @param Message $message * @param callable $getProjectDB * @param Document $project + * @param callable $getAudit * @return Commit|NoCommit * @throws Throwable * @throws \Utopia\Database\Exception * @throws Authorization * @throws Structure */ - public function action(Message $message, callable $getProjectDB, Document $project): Commit|NoCommit + public function action(Message $message, Document $project, callable $getAudit): Commit|NoCommit { $payload = $message->getPayload() ?? []; @@ -136,9 +135,7 @@ class Audits extends Action Console::log('Processing Project "' . $sequence . '" batch with ' . count($projectLogs['logs']) . ' events'); $projectDocument = $projectLogs['project']; - $dbForProject = $getProjectDB($projectDocument); - $adapter = new AdapterDatabase($dbForProject); - $audit = new Audit($adapter); + $audit = $getAudit($projectDocument); $audit->logBatch($projectLogs['logs']); Console::success('Audit logs processed successfully'); From 69430154e6c06e6c2bed001e4772cb010c9ab7ab Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Wed, 24 Dec 2025 10:24:51 +0000 Subject: [PATCH 22/23] update autit to rc version --- composer.json | 2 +- composer.lock | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/composer.json b/composer.json index 1051b40d42..844a10d7e8 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,7 @@ "appwrite/php-clamav": "2.0.*", "utopia-php/abuse": "1.*", "utopia-php/analytics": "0.10.*", - "utopia-php/audit": "dev-feat-db-3x", + "utopia-php/audit": "2.0.2-rc1", "utopia-php/auth": "0.5.*", "utopia-php/cache": "0.13.*", "utopia-php/cli": "0.15.*", diff --git a/composer.lock b/composer.lock index 5dfaab9f67..f637488a9a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "54b49eb2f01fdf10632c6be6feadb6fe", + "content-hash": "b873febd2b03c32ec61a57b690cc44a2", "packages": [ { "name": "adhocore/jwt", @@ -3552,7 +3552,7 @@ }, { "name": "utopia-php/audit", - "version": "dev-feat-db-3x", + "version": "2.0.2-rc1", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", @@ -3595,7 +3595,7 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/feat-db-3x" + "source": "https://github.com/utopia-php/audit/tree/2.0.2-rc1" }, "time": "2025-12-24T01:20:43+00:00" }, @@ -5438,16 +5438,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "1.7.1", + "version": "1.7.2", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "14b9ebd7f5e3287cd24ef342c38dfa714808e80e" + "reference": "3876d486e2c00b788fbda677ef9fcc77391b8898" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/14b9ebd7f5e3287cd24ef342c38dfa714808e80e", - "reference": "14b9ebd7f5e3287cd24ef342c38dfa714808e80e", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/3876d486e2c00b788fbda677ef9fcc77391b8898", + "reference": "3876d486e2c00b788fbda677ef9fcc77391b8898", "shasum": "" }, "require": { @@ -5483,9 +5483,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/1.7.1" + "source": "https://github.com/appwrite/sdk-generator/tree/1.7.2" }, - "time": "2025-12-22T11:47:51+00:00" + "time": "2025-12-24T07:49:12+00:00" }, { "name": "doctrine/annotations", @@ -8946,7 +8946,7 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "utopia-php/audit": 20 + "utopia-php/audit": 5 }, "prefer-stable": false, "prefer-lowest": false, @@ -8971,5 +8971,5 @@ "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } From d2cda9770b3ef4925c59e738728f8a8100c1cb9d Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 28 Dec 2025 09:01:37 +0000 Subject: [PATCH 23/23] Use get audit resource for audit cleanup. --- src/Appwrite/Platform/Workers/Deletes.php | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index db55d3963c..007f398e11 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -10,6 +10,7 @@ use Executor\Executor; use Throwable; use Utopia\Abuse\Adapters\TimeLimit\Database as AbuseDatabase; use Utopia\Audit\Adapter\SQL; +use Utopia\Audit\Audit; use Utopia\Cache\Adapter\Filesystem; use Utopia\Cache\Cache; use Utopia\CLI\Console; @@ -62,6 +63,7 @@ class Deletes extends Action ->inject('executionRetention') ->inject('auditRetention') ->inject('log') + ->inject('getAudit') ->callback($this->action(...)); } @@ -84,7 +86,8 @@ class Deletes extends Action Executor $executor, string $executionRetention, string $auditRetention, - Log $log + Log $log, + callable $getAudit, ): void { $payload = $message->getPayload() ?? []; @@ -145,7 +148,7 @@ class Deletes extends Action break; case DELETE_TYPE_AUDIT: if (!$project->isEmpty()) { - $this->deleteAuditLogs($project, $getProjectDB, $auditRetention); + $this->deleteAuditLogs($project, $auditRetention, $getAudit); } break; case DELETE_TYPE_REALTIME: @@ -777,23 +780,20 @@ class Deletes extends Action * @param Database $dbForPlatform * @param callable $getProjectDB * @param string $auditRetention + * @param callable $getAudit * @return void * @throws Exception */ - private function deleteAuditLogs(Document $project, callable $getProjectDB, string $auditRetention): void + private function deleteAuditLogs(Document $project, string $auditRetention, callable $getAudit): void { $projectId = $project->getId(); - $dbForProject = $getProjectDB($project); + /** @var Audit $audit */ + $audit = $getAudit($project); try { - $this->deleteByGroup(SQL::COLLECTION, [ - Query::select([...$this->selects, 'time']), - Query::lessThan('time', $auditRetention), - Query::orderDesc('time'), - Query::orderAsc(), - ], $dbForProject); - } catch (DatabaseException $e) { - Console::error('Failed to delete audit logs for project ' . $projectId . ': ' . $e->getMessage()); + $audit->cleanup(new \DateTime($auditRetention)); + } catch (Throwable $th) { + Console::error('Failed to delete audit logs for project ' . $projectId . ': ' . $th->getMessage()); } }