Compare commits

...
Author SHA1 Message Date
Harsh MahajanandGitHub 836c4f2607 Merge branch '1.8.x' into refactor-SER-1095-replace-usage-of-utopia-injection 2026-03-12 18:08:17 +05:30
Harsh Mahajan 3dacb1ea2e add user doc 2026-03-11 18:17:40 +05:30
Harsh MahajanandGitHub 03aa85b547 Merge branch '1.8.x' into refactor-SER-1095-replace-usage-of-utopia-injection 2026-03-11 18:06:23 +05:30
3f0a341dda Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-11 17:44:03 +05:30
Harsh MahajanandGitHub 54737dd7d2 Merge branch '1.8.x' into refactor-SER-1095-replace-usage-of-utopia-injection 2026-03-11 14:22:03 +05:30
Harsh Mahajan 8cc58d0c40 do in general.php 2026-03-11 13:45:44 +05:30
Harsh Mahajan e6b4a465e8 route-injection 2026-03-11 13:00:38 +05:30
Harsh MahajanandGitHub d49b5ee52c Merge branch '1.8.x' into refactor-SER-1095-replace-usage-of-utopia-injection 2026-03-11 12:50:48 +05:30
Harsh Mahajan 63649a7a30 revert api.php 2026-03-11 12:50:10 +05:30
Harsh Mahajan 02aa1e5018 revert 2026-03-11 12:47:26 +05:30
Harsh Mahajan fffb69a96d revert 2026-03-11 12:45:08 +05:30
Harsh Mahajan f7a6c62964 patch 2026-03-11 12:25:21 +05:30
Harsh MahajanandGitHub a11f68545b Merge branch '1.8.x' into refactor-SER-1095-replace-usage-of-utopia-injection 2026-03-11 11:07:55 +05:30
Harsh MahajanandGitHub 0e94f2a089 Merge branch '1.8.x' into refactor-SER-1095-replace-usage-of-utopia-injection 2026-03-10 14:26:22 +05:30
Harsh Mahajan 42832a6d8d revert 2026-03-10 13:38:35 +05:30
Harsh Mahajan 0d04f56d2c copilot suggestion 2026-03-10 12:28:04 +05:30
Harsh Mahajan 6e53e6a3ec Merge branch '1.8.x' into refactor-SER-1095-replace-usage-of-utopia-injection
Made-with: Cursor
2026-03-10 12:24:12 +05:30
Harsh Mahajan 62c2d41c19 added graphql fix 2026-03-03 17:56:12 +05:30
Harsh Mahajan 0e0b6c6fe7 fix 2026-03-03 14:11:46 +05:30
Harsh Mahajan ce5fe2c6bf added tests 2026-03-03 13:58:33 +05:30
Harsh Mahajan cf7b0f6679 update composer 2026-03-03 13:41:35 +05:30
6 changed files with 61 additions and 51 deletions
+23 -30
View File
@@ -50,6 +50,7 @@ use Utopia\Database\Validator\Authorization;
use Utopia\Domains\Domain;
use Utopia\DSN\DSN;
use Utopia\Http\Http;
use Utopia\Http\Route;
use Utopia\Locale\Locale;
use Utopia\Logger\Adapter\Sentry;
use Utopia\Logger\Log;
@@ -65,7 +66,7 @@ Config::setParam('domainVerification', false);
Config::setParam('cookieDomain', 'localhost');
Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE);
function router(Http $utopia, Database $dbForPlatform, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Event $queueForEvents, Bus $bus, Executor $executor, Reader $geodb, callable $isResourceBlocked, array $platform, string $previewHostname, Authorization $authorization, ?Key $apiKey, DeleteEvent $queueForDeletes, int $executionsRetentionCount)
function router(Database $dbForPlatform, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Event $queueForEvents, Bus $bus, Executor $executor, Reader $geodb, callable $isResourceBlocked, array $platform, string $previewHostname, Authorization $authorization, ?Key $apiKey, DeleteEvent $queueForDeletes, int $executionsRetentionCount)
{
$host = $request->getHostname() ?? '';
if (!empty($previewHostname)) {
@@ -822,9 +823,9 @@ Http::init()
Http::init()
->groups(['api', 'web'])
->inject('utopia')
->inject('swooleRequest')
->inject('request')
->inject('route')
->inject('response')
->inject('log')
->inject('project')
@@ -845,7 +846,7 @@ Http::init()
->inject('authorization')
->inject('queueForDeletes')
->inject('executionsRetentionCount')
->action(function (Http $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Document $project, Database $dbForPlatform, callable $getProjectDB, Locale $locale, array $localeCodes, Reader $geodb, Event $queueForEvents, Bus $bus, Executor $executor, array $platform, callable $isResourceBlocked, string $previewHostname, Document $devKey, ?Key $apiKey, Cors $cors, Authorization $authorization, DeleteEvent $queueForDeletes, int $executionsRetentionCount) {
->action(function (SwooleRequest $swooleRequest, Request $request, Route $route, Response $response, Log $log, Document $project, Database $dbForPlatform, callable $getProjectDB, Locale $locale, array $localeCodes, Reader $geodb, Event $queueForEvents, Bus $bus, Executor $executor, array $platform, callable $isResourceBlocked, string $previewHostname, Document $devKey, ?Key $apiKey, Cors $cors, Authorization $authorization, DeleteEvent $queueForDeletes, int $executionsRetentionCount) {
/*
* Appwrite Router
*/
@@ -853,15 +854,14 @@ Http::init()
$platformHostnames = $platform['hostnames'] ?? [];
// Only run Router when external domain
if (!\in_array($hostname, $platformHostnames) || !empty($previewHostname)) {
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $bus, $executor, $geodb, $isResourceBlocked, $platform, $previewHostname, $authorization, $apiKey, $queueForDeletes, $executionsRetentionCount)) {
$utopia->getRoute()?->label('router', true);
if (router($dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $bus, $executor, $geodb, $isResourceBlocked, $platform, $previewHostname, $authorization, $apiKey, $queueForDeletes, $executionsRetentionCount)) {
$route?->label('router', true);
}
}
/*
* Request format
*/
$route = $utopia->getRoute();
Request::setRoute($route);
if ($route === null) {
@@ -1127,9 +1127,9 @@ Http::init()
});
Http::options()
->inject('utopia')
->inject('swooleRequest')
->inject('request')
->inject('route')
->inject('response')
->inject('log')
->inject('dbForPlatform')
@@ -1148,15 +1148,15 @@ Http::options()
->inject('authorization')
->inject('queueForDeletes')
->inject('executionsRetentionCount')
->action(function (Http $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, Bus $bus, Executor $executor, Reader $geodb, callable $isResourceBlocked, array $platform, string $previewHostname, Document $project, Document $devKey, ?Key $apiKey, Cors $cors, Authorization $authorization, DeleteEvent $queueForDeletes, int $executionsRetentionCount) {
->action(function (SwooleRequest $swooleRequest, Request $request, Route $route, Response $response, Log $log, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, Bus $bus, Executor $executor, Reader $geodb, callable $isResourceBlocked, array $platform, string $previewHostname, Document $project, Document $devKey, ?Key $apiKey, Cors $cors, Authorization $authorization, DeleteEvent $queueForDeletes, int $executionsRetentionCount) {
/*
* Appwrite Router
*/
$platformHostnames = $platform['hostnames'] ?? [];
// Only run Router when external domain
if (!in_array($request->getHostname(), $platformHostnames) || !empty($previewHostname)) {
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $bus, $executor, $geodb, $isResourceBlocked, $platform, $previewHostname, $authorization, $apiKey, $queueForDeletes, $executionsRetentionCount)) {
$utopia->getRoute()?->label('router', true);
if (router($dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $bus, $executor, $geodb, $isResourceBlocked, $platform, $previewHostname, $authorization, $apiKey, $queueForDeletes, $executionsRetentionCount)) {
$route->label('router', true);
}
}
@@ -1180,8 +1180,8 @@ Http::options()
Http::error()
->inject('error')
->inject('utopia')
->inject('request')
->inject('route')
->inject('response')
->inject('project')
->inject('logger')
@@ -1189,9 +1189,9 @@ Http::error()
->inject('bus')
->inject('devKey')
->inject('authorization')
->action(function (Throwable $error, Http $utopia, Request $request, Response $response, Document $project, ?Logger $logger, Log $log, Bus $bus, Document $devKey, Authorization $authorization) {
->inject('user')
->action(function (Throwable $error, Request $request, Route $route, Response $response, Document $project, ?Logger $logger, Log $log, Bus $bus, Document $devKey, Authorization $authorization, Document $user) {
$version = System::getEnv('_APP_VERSION', 'UNKNOWN');
$route = $utopia->getRoute();
$class = \get_class($error);
$code = $error->getCode();
$message = $error->getMessage();
@@ -1271,14 +1271,7 @@ Http::error()
}
if ($logger && $publish) {
try {
/** @var Utopia\Database\Document $user */
$user = $utopia->getResource('user');
} catch (\Throwable) {
// All good, user is optional information for logger
}
if (isset($user) && !$user->isEmpty()) {
if (!$user->isEmpty()) {
$log->setUser(new User($user->getId()));
} else {
$log->setUser(new User('guest-' . hash('sha256', $request->getIP())));
@@ -1501,7 +1494,7 @@ Http::error()
$response->dynamic(
new Document($output),
$utopia->isDevelopment() ? Response::MODEL_ERROR_DEV : Response::MODEL_ERROR
Http::isDevelopment() ? Response::MODEL_ERROR_DEV : Response::MODEL_ERROR
);
});
@@ -1509,9 +1502,9 @@ Http::get('/robots.txt')
->desc('Robots.txt File')
->label('scope', 'public')
->label('docs', false)
->inject('utopia')
->inject('swooleRequest')
->inject('request')
->inject('route')
->inject('response')
->inject('log')
->inject('dbForPlatform')
@@ -1527,14 +1520,14 @@ Http::get('/robots.txt')
->inject('authorization')
->inject('queueForDeletes')
->inject('executionsRetentionCount')
->action(function (Http $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, Bus $bus, Executor $executor, Reader $geodb, callable $isResourceBlocked, array $platform, string $previewHostname, ?Key $apiKey, Authorization $authorization, DeleteEvent $queueForDeletes, int $executionsRetentionCount) {
->action(function (SwooleRequest $swooleRequest, Request $request, Route $route, Response $response, Log $log, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, Bus $bus, Executor $executor, Reader $geodb, callable $isResourceBlocked, array $platform, string $previewHostname, ?Key $apiKey, Authorization $authorization, DeleteEvent $queueForDeletes, int $executionsRetentionCount) {
$platformHostnames = $platform['hostnames'] ?? [];
if (in_array($request->getHostname(), $platformHostnames) || !empty($previewHostname)) {
$template = new View(__DIR__ . '/../views/general/robots.phtml');
$response->text($template->render(false));
} else {
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $bus, $executor, $geodb, $isResourceBlocked, $platform, $previewHostname, $authorization, $apiKey, $queueForDeletes, $executionsRetentionCount)) {
$utopia->getRoute()?->label('router', true);
if (router($dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $bus, $executor, $geodb, $isResourceBlocked, $platform, $previewHostname, $authorization, $apiKey, $queueForDeletes, $executionsRetentionCount)) {
$route->label('router', true);
}
}
});
@@ -1543,9 +1536,9 @@ Http::get('/humans.txt')
->desc('Humans.txt File')
->label('scope', 'public')
->label('docs', false)
->inject('utopia')
->inject('swooleRequest')
->inject('request')
->inject('route')
->inject('response')
->inject('log')
->inject('dbForPlatform')
@@ -1561,14 +1554,14 @@ Http::get('/humans.txt')
->inject('authorization')
->inject('queueForDeletes')
->inject('executionsRetentionCount')
->action(function (Http $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, Bus $bus, Executor $executor, Reader $geodb, callable $isResourceBlocked, array $platform, string $previewHostname, ?Key $apiKey, Authorization $authorization, DeleteEvent $queueForDeletes, int $executionsRetentionCount) {
->action(function (SwooleRequest $swooleRequest, Request $request, Route $route, Response $response, Log $log, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, Bus $bus, Executor $executor, Reader $geodb, callable $isResourceBlocked, array $platform, string $previewHostname, ?Key $apiKey, Authorization $authorization, DeleteEvent $queueForDeletes, int $executionsRetentionCount) {
$platformHostnames = $platform['hostnames'] ?? [];
if (in_array($request->getHostname(), $platformHostnames) || !empty($previewHostname)) {
$template = new View(__DIR__ . '/../views/general/humans.phtml');
$response->text($template->render(false));
} else {
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $bus, $executor, $geodb, $isResourceBlocked, $platform, $previewHostname, $authorization, $apiKey, $queueForDeletes, $executionsRetentionCount)) {
$utopia->getRoute()?->label('router', true);
if (router($dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $bus, $executor, $geodb, $isResourceBlocked, $platform, $previewHostname, $authorization, $apiKey, $queueForDeletes, $executionsRetentionCount)) {
$route->label('router', true);
}
}
});
+3 -3
View File
@@ -13,6 +13,7 @@ use Utopia\Database\Helpers\Permission;
use Utopia\Database\Helpers\Role;
use Utopia\Database\Validator\UID;
use Utopia\Http\Http;
use Utopia\Http\Route;
use Utopia\Locale\Locale;
use Utopia\System\System;
use Utopia\Validator\Text;
@@ -281,13 +282,12 @@ Http::get('/v1/mock/github/callback')
Http::shutdown()
->groups(['mock'])
->inject('utopia')
->inject('route')
->inject('response')
->inject('request')
->action(function (Http $utopia, Response $response, Request $request) {
->action(function (Route $route, Response $response, Request $request) {
$result = [];
$route = $utopia->getRoute();
$path = APP_STORAGE_CACHE . '/tests.json';
$tests = (\file_exists($path)) ? \json_decode(\file_get_contents($path), true) : [];
+8 -13
View File
@@ -35,6 +35,7 @@ use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Authorization\Input;
use Utopia\Database\Validator\Roles;
use Utopia\Http\Http;
use Utopia\Http\Route;
use Utopia\System\System;
use Utopia\Telemetry\Adapter as Telemetry;
use Utopia\Validator\WhiteList;
@@ -80,7 +81,7 @@ $parseLabel = function (string $label, array $responsePayload, array $requestPar
Http::init()
->groups(['api'])
->inject('utopia')
->inject('route')
->inject('request')
->inject('dbForPlatform')
->inject('dbForProject')
@@ -93,8 +94,7 @@ Http::init()
->inject('team')
->inject('apiKey')
->inject('authorization')
->action(function (Http $utopia, Request $request, Database $dbForPlatform, Database $dbForProject, Audit $queueForAudits, Document $project, Document $user, ?Document $session, array $servers, string $mode, Document $team, ?Key $apiKey, Authorization $authorization) {
$route = $utopia->getRoute();
->action(function (Route $route, Request $request, Database $dbForPlatform, Database $dbForProject, Audit $queueForAudits, Document $project, Document $user, ?Document $session, array $servers, string $mode, Document $team, ?Key $apiKey, Authorization $authorization) {
/**
* Handle user authentication and session validation.
@@ -443,7 +443,7 @@ Http::init()
Http::init()
->groups(['api'])
->inject('utopia')
->inject('route')
->inject('request')
->inject('response')
->inject('project')
@@ -467,9 +467,7 @@ Http::init()
->inject('telemetry')
->inject('platform')
->inject('authorization')
->action(function (Http $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Mail $queueForMails, Database $dbForProject, callable $timelimit, Document $resourceToken, string $mode, ?Key $apiKey, array $plan, Document $devKey, Telemetry $telemetry, array $platform, Authorization $authorization) {
$route = $utopia->getRoute();
->action(function (Route $route, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Mail $queueForMails, Database $dbForProject, callable $timelimit, Document $resourceToken, string $mode, ?Key $apiKey, array $plan, Document $devKey, Telemetry $telemetry, array $platform, Authorization $authorization) {
if (
array_key_exists('rest', $project->getAttribute('apis', []))
@@ -594,7 +592,6 @@ Http::init()
$useCache = $route->getLabel('cache', false);
$storageCacheOperationsCounter = $telemetry->createCounter('storage.cache.operations.load');
if ($useCache) {
$route = $utopia->match($request);
$isImageTransformation = $route->getPath() === '/v1/storage/buckets/:bucketId/files/:fileId/preview';
$isDisabled = isset($plan['imageTransformations']) && $plan['imageTransformations'] === -1 && !User::isPrivileged($authorization->getRoles());
@@ -704,12 +701,11 @@ Http::init()
*/
Http::shutdown()
->groups(['session'])
->inject('utopia')
->inject('request')
->inject('response')
->inject('project')
->inject('dbForProject')
->action(function (Http $utopia, Request $request, Response $response, Document $project, Database $dbForProject) {
->action(function (Request $request, Response $response, Document $project, Database $dbForProject) {
$sessionLimit = $project->getAttribute('auths', [])['maxSessions'] ?? APP_LIMIT_USER_SESSIONS_DEFAULT;
$session = $response->getPayload();
$userId = $session['userId'] ?? '';
@@ -738,7 +734,7 @@ Http::shutdown()
Http::shutdown()
->groups(['api'])
->inject('utopia')
->inject('route')
->inject('request')
->inject('response')
->inject('project')
@@ -758,7 +754,7 @@ Http::shutdown()
->inject('timelimit')
->inject('eventProcessor')
->inject('bus')
->action(function (Http $utopia, Request $request, Response $response, Document $project, User $user, Event $queueForEvents, Audit $queueForAudits, StatsUsage $queueForStatsUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Messaging $queueForMessaging, Func $queueForFunctions, Event $queueForWebhooks, Realtime $queueForRealtime, Database $dbForProject, Authorization $authorization, callable $timelimit, EventProcessor $eventProcessor, Bus $bus) use ($parseLabel) {
->action(function (Route $route, Request $request, Response $response, Document $project, User $user, Event $queueForEvents, Audit $queueForAudits, StatsUsage $queueForStatsUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Messaging $queueForMessaging, Func $queueForFunctions, Event $queueForWebhooks, Realtime $queueForRealtime, Database $dbForProject, Authorization $authorization, callable $timelimit, EventProcessor $eventProcessor, Bus $bus) use ($parseLabel) {
$responsePayload = $response->getPayload();
@@ -808,7 +804,6 @@ Http::shutdown()
}
}
$route = $utopia->getRoute();
$requestParams = $route->getParamsValues();
/**
+3 -4
View File
@@ -9,6 +9,7 @@ use Utopia\Database\DateTime;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
use Utopia\Http\Http;
use Utopia\Http\Route;
use Utopia\System\System;
Http::init()
@@ -32,12 +33,12 @@ Http::init()
Http::init()
->groups(['auth'])
->inject('utopia')
->inject('route')
->inject('request')
->inject('project')
->inject('geodb')
->inject('authorization')
->action(function (Http $utopia, Request $request, Document $project, Reader $geodb, Authorization $authorization) {
->action(function (Route $route, Request $request, Document $project, Reader $geodb, Authorization $authorization) {
$denylist = System::getEnv('_APP_CONSOLE_COUNTRIES_DENYLIST', '');
if (!empty($denylist && $project->getId() === 'console')) {
$countries = explode(',', $denylist);
@@ -48,8 +49,6 @@ Http::init()
}
}
$route = $utopia->match($request);
$isPrivilegedUser = User::isPrivileged($authorization->getRoles());
$isAppUser = User::isApp($authorization->getRoles());
+17
View File
@@ -267,8 +267,18 @@ class Resolvers
$utopia->setResource('request', static fn () => $request);
$response->setContentType(Response::CONTENT_TYPE_NULL);
$previousRoute = Request::getRoute();
$previousRouteResource = null;
try {
$previousRouteResource = $utopia->getResource('route', true);
} catch (\Throwable) {
}
try {
$route = $utopia->match($request, fresh: true);
Request::setRoute($route);
$utopia->setResource('route', static fn () => $route);
$utopia->execute($route, $request, $response);
} catch (\Throwable $e) {
@@ -277,6 +287,13 @@ class Resolvers
}
$reject($e);
return;
} finally {
Request::setRoute($previousRoute);
if ($previousRouteResource instanceof Route) {
$utopia->setResource('route', static fn () => $previousRouteResource);
} else {
$utopia->setResource('route', static fn () => null);
}
}
$payload = $response->getPayload();
+7 -1
View File
@@ -199,7 +199,13 @@ class Request extends UtopiaRequest
public function getHeader(string $key, string $default = ''): string
{
$headers = $this->getHeaders();
return $headers[$key] ?? $default;
$header = $headers[$key] ?? $default;
if (\is_array($header)) {
$header = $header[0] ?? $default;
}
return \is_string($header) ? $header : $default;
}
/**