diff --git a/Dockerfile b/Dockerfile index 7548ec70f4..33c368b8dd 100755 --- a/Dockerfile +++ b/Dockerfile @@ -29,7 +29,7 @@ ENV VITE_APPWRITE_GROWTH_ENDPOINT=$VITE_APPWRITE_GROWTH_ENDPOINT RUN npm ci RUN npm run build -FROM appwrite/base:0.4.3 as final +FROM appwrite/base:0.4.2 as final LABEL maintainer="team@appwrite.io" diff --git a/app/config/errors.php b/app/config/errors.php index 3638c616ce..00b177480d 100644 --- a/app/config/errors.php +++ b/app/config/errors.php @@ -631,6 +631,11 @@ return [ 'description' => 'Host is not trusted. Add a custom domain to your project first.', 'code' => 404, ], + Exception::ROUTER_DOMAIN_NOT_CONFIGURED => [ + 'name' => Exception::ROUTER_DOMAIN_NOT_CONFIGURED, + 'description' => 'Please configure domain environment variables before using Appwrite outside of localhost.', + 'code' => 500, + ], Exception::RULE_RESOURCE_NOT_FOUND => [ 'name' => Exception::RULE_RESOURCE_NOT_FOUND, 'description' => 'Resource could not be found. Check resourceId and resourceType.', diff --git a/app/config/roles.php b/app/config/roles.php index 256766d3a4..ec9cf51bf1 100644 --- a/app/config/roles.php +++ b/app/config/roles.php @@ -61,7 +61,6 @@ return [ Auth::USER_ROLE_GUESTS => [ 'label' => 'Guests', 'scopes' => [ - 'none', 'public', 'home', 'console', @@ -77,22 +76,22 @@ return [ ], Auth::USER_ROLE_USERS => [ 'label' => 'Users', - 'scopes' => \array_merge($member, [ 'none' ]), + 'scopes' => \array_merge($member), ], Auth::USER_ROLE_ADMIN => [ 'label' => 'Admin', - 'scopes' => \array_merge($admins, [ 'none' ]), + 'scopes' => \array_merge($admins), ], Auth::USER_ROLE_DEVELOPER => [ 'label' => 'Developer', - 'scopes' => \array_merge($admins, [ 'none' ]), + 'scopes' => \array_merge($admins), ], Auth::USER_ROLE_OWNER => [ 'label' => 'Owner', - 'scopes' => \array_merge($member, $admins, [ 'none' ]), + 'scopes' => \array_merge($member, $admins), ], Auth::USER_ROLE_APPS => [ 'label' => 'Applications', - 'scopes' => ['health.read', 'graphql', 'none'], + 'scopes' => ['health.read', 'graphql'], ], ]; diff --git a/app/console b/app/console index f0f0b050fc..495a9c2530 160000 --- a/app/console +++ b/app/console @@ -1 +1 @@ -Subproject commit f0f0b050fc51871206a4bb729f1c11592f7e8c2f +Subproject commit 495a9c25302bb79156773ef0668b3eef07ce3dd1 diff --git a/app/controllers/general.php b/app/controllers/general.php index 530f76584b..e8ab7f1320 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -60,7 +60,7 @@ function router(App $utopia, Database $dbForConsole, SwooleRequest $swooleReques $mainDomain = App::getEnv('_APP_DOMAIN', ''); if ($mainDomain === 'localhost') { - throw new AppwriteException(AppwriteException::GENERAL_SERVER_ERROR, 'Please configure domain environment variables before using Appwrite outside of localhost.'); + throw new AppwriteException(AppwriteException::ROUTER_DOMAIN_NOT_CONFIGURED); } else { throw new AppwriteException(AppwriteException::ROUTER_HOST_NOT_FOUND); } diff --git a/app/init.php b/app/init.php index 8edaae81fd..3d0e652b6b 100644 --- a/app/init.php +++ b/app/init.php @@ -186,7 +186,7 @@ const APP_AUTH_TYPE_ADMIN = 'Admin'; // Response related const MAX_OUTPUT_CHUNK_SIZE = 2 * 1024 * 1024; // 2MB // Function headers -const FUNCTION_ALLOWLIST_HEADERS_REQUEST = ['content-type', 'agent', 'content-length']; +const FUNCTION_ALLOWLIST_HEADERS_REQUEST = ['content-type', 'agent', 'content-length', 'host']; const FUNCTION_ALLOWLIST_HEADERS_RESPONSE = ['content-type', 'content-length']; // Usage metrics const METRIC_TEAMS = 'teams'; diff --git a/app/workers/builds.php b/app/workers/builds.php index 806e005082..f8ee40172a 100644 --- a/app/workers/builds.php +++ b/app/workers/builds.php @@ -177,7 +177,7 @@ class BuildsV1 extends Worker $gitCloneCommand = $github->generateCloneCommand($cloneOwner, $cloneRepository, $branchName, $tmpDirectory, $rootDirectory); $stdout = ''; $stderr = ''; - Console::execute('mkdir -p /tmp/builds/' . $buildId, '', $stdout, $stderr); + Console::execute('mkdir -p /tmp/builds/' . \escapeshellcmd($buildId), '', $stdout, $stderr); $exit = Console::execute($gitCloneCommand, '', $stdout, $stderr); if ($exit !== 0) { @@ -196,7 +196,7 @@ class BuildsV1 extends Worker if (!empty($templateRepositoryName) && !empty($templateOwnerName) && !empty($templateBranch)) { // Clone template repo - $tmpTemplateDirectory = '/tmp/builds/' . $buildId . '/template'; + $tmpTemplateDirectory = '/tmp/builds/' . \escapeshellcmd($buildId) . '/template'; $gitCloneCommandForTemplate = $github->generateCloneCommand($templateOwnerName, $templateRepositoryName, $templateBranch, $tmpTemplateDirectory, $templateRootDirectory); $exit = Console::execute($gitCloneCommandForTemplate, '', $stdout, $stderr); @@ -212,7 +212,7 @@ class BuildsV1 extends Worker Console::execute('cp -rfn ' . $tmpTemplateDirectory . '/' . $templateRootDirectory . '/* ' . $tmpDirectory . '/' . $rootDirectory, '', $stdout, $stderr); // Commit and push - $exit = Console::execute('git config --global user.email "security@appwrite.io" && git config --global user.name "Appwrite" && cd ' . $tmpDirectory . ' && git add . && git commit -m "Create \'' . $function->getAttribute('name', '') . '\' function" && git push origin ' . $branchName, '', $stdout, $stderr); + $exit = Console::execute('git config --global user.email "security@appwrite.io" && git config --global user.name "Appwrite" && cd ' . $tmpDirectory . ' && git add . && git commit -m "Create \'' . \escapeshellcmd($function->getAttribute('name', '')) . '\' function" && git push origin ' . \escapeshellcmd($branchName), '', $stdout, $stderr); if ($exit !== 0) { throw new \Exception('Unable to push code repository: ' . $stderr); @@ -252,7 +252,7 @@ class BuildsV1 extends Worker ); } - Console::execute('tar --exclude code.tar.gz -czf /tmp/builds/' . $buildId . '/code.tar.gz -C /tmp/builds/' . $buildId . '/code' . (empty($rootDirectory) ? '' : '/' . $rootDirectory) . ' .', '', $stdout, $stderr); + Console::execute('tar --exclude code.tar.gz -czf /tmp/builds/' . \escapeshellcmd($buildId) . '/code.tar.gz -C /tmp/builds/' . \escapeshellcmd($buildId) . '/code' . (empty($rootDirectory) ? '' : '/' . $rootDirectory) . ' .', '', $stdout, $stderr); $deviceFunctions = $this->getFunctionsDevice($project->getId()); @@ -267,7 +267,7 @@ class BuildsV1 extends Worker throw new \Exception("Unable to move file"); } - Console::execute('rm -rf /tmp/builds/' . $buildId, '', $stdout, $stderr); + Console::execute('rm -rf /tmp/builds/' . \escapeshellcmd($buildId), '', $stdout, $stderr); $source = $path; diff --git a/src/Appwrite/Extend/Exception.php b/src/Appwrite/Extend/Exception.php index aca8fd6a44..0d1b285d86 100644 --- a/src/Appwrite/Extend/Exception.php +++ b/src/Appwrite/Extend/Exception.php @@ -195,6 +195,7 @@ class Exception extends \Exception /** Router */ public const ROUTER_HOST_NOT_FOUND = 'router_host_not_found'; + public const ROUTER_DOMAIN_NOT_CONFIGURED = 'router_domain_not_configured'; /** Proxy */ public const RULE_RESOURCE_NOT_FOUND = 'rule_resource_not_found'; diff --git a/src/Appwrite/Utopia/Response/Filters/V14.php b/src/Appwrite/Utopia/Response/Filters/V14.php index ff16d1e34a..200823f37f 100644 --- a/src/Appwrite/Utopia/Response/Filters/V14.php +++ b/src/Appwrite/Utopia/Response/Filters/V14.php @@ -23,7 +23,7 @@ class V14 extends Filter break; case Response::MODEL_DOCUMENT: - // case Response::MODEL_DOMAIN: + case Response::MODEL_DOMAIN: case Response::MODEL_FUNCTION: case Response::MODEL_TEAM: case Response::MODEL_MEMBERSHIP: @@ -38,10 +38,10 @@ class V14 extends Filter $parsedResponse = $this->parseRemoveAttributesList($content, 'documents', ['$createdAt', '$updatedAt']); break; - // case Response::MODEL_DOMAIN_LIST: - // $parsedResponse = $this->parseRemoveAttributesList($content, 'domains', ['$createdAt', '$updatedAt']); + case Response::MODEL_DOMAIN_LIST: + $parsedResponse = $this->parseRemoveAttributesList($content, 'domains', ['$createdAt', '$updatedAt']); - // break; + break; case Response::MODEL_FUNCTION_LIST: $parsedResponse = $this->parseRemoveAttributesList($content, 'functions', ['$createdAt', '$updatedAt']); diff --git a/src/Appwrite/Utopia/Response/Filters/V15.php b/src/Appwrite/Utopia/Response/Filters/V15.php index 6925a16632..232feec201 100644 --- a/src/Appwrite/Utopia/Response/Filters/V15.php +++ b/src/Appwrite/Utopia/Response/Filters/V15.php @@ -50,7 +50,7 @@ class V15 extends Filter break; case Response::MODEL_DATABASE: case Response::MODEL_DEPLOYMENT: - // case Response::MODEL_DOMAIN: + case Response::MODEL_DOMAIN: case Response::MODEL_PLATFORM: case Response::MODEL_PROJECT: case Response::MODEL_TEAM: @@ -59,7 +59,7 @@ class V15 extends Filter break; case Response::MODEL_DATABASE_LIST: case Response::MODEL_DEPLOYMENT_LIST: - // case Response::MODEL_DOMAIN_LIST: + case Response::MODEL_DOMAIN_LIST: case Response::MODEL_PLATFORM_LIST: case Response::MODEL_PROJECT_LIST: case Response::MODEL_TEAM_LIST: @@ -72,9 +72,9 @@ class V15 extends Filter case Response::MODEL_DEPLOYMENT_LIST: $listKey = 'deployments'; break; - // case Response::MODEL_DOMAIN_LIST: - // $listKey = 'domains'; - // break; + case Response::MODEL_DOMAIN_LIST: + $listKey = 'domains'; + break; case Response::MODEL_PLATFORM_LIST: $listKey = 'platforms'; break; diff --git a/src/Executor/Executor.php b/src/Executor/Executor.php index 4ee1625f8a..0170031f29 100644 --- a/src/Executor/Executor.php +++ b/src/Executor/Executor.php @@ -178,7 +178,9 @@ class Executor array $headers, string $runtimeEntrypoint = null, ) { - $headers['host'] = App::getEnv('_APP_DOMAIN', ''); + if(empty($headers['host'])) { + $headers['host'] = App::getEnv('_APP_DOMAIN', ''); + } $runtimeId = "$projectId-$deploymentId"; $route = '/runtimes/' . $runtimeId . '/execution'; diff --git a/tests/e2e/Services/Console/ConsoleConsoleClientTest.php b/tests/e2e/Services/Console/ConsoleConsoleClientTest.php index 3c1e973821..bb6176cc62 100644 --- a/tests/e2e/Services/Console/ConsoleConsoleClientTest.php +++ b/tests/e2e/Services/Console/ConsoleConsoleClientTest.php @@ -24,10 +24,12 @@ class ConsoleConsoleClientTest extends Scope ], $this->getHeaders()), []); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertCount(4, $response['body']); + $this->assertCount(6, $response['body']); $this->assertIsString($response['body']['_APP_DOMAIN_TARGET']); $this->assertIsInt($response['body']['_APP_STORAGE_LIMIT']); $this->assertIsInt($response['body']['_APP_FUNCTIONS_SIZE_LIMIT']); $this->assertIsString($response['body']['_APP_DOMAIN_TARGET']); + $this->assertIsString($response['body']['_APP_VCS_ENABLED']); + $this->assertIsString($response['body']['_APP_ASSISTANT_ENABLED']); } } diff --git a/tests/e2e/Services/GraphQL/FunctionsServerTest.php b/tests/e2e/Services/GraphQL/FunctionsServerTest.php index 39a3abca05..ed7933db1a 100644 --- a/tests/e2e/Services/GraphQL/FunctionsServerTest.php +++ b/tests/e2e/Services/GraphQL/FunctionsServerTest.php @@ -25,6 +25,7 @@ class FunctionsServerTest extends Scope 'variables' => [ 'functionId' => ID::unique(), 'name' => 'Test Function', + 'entrypoint' => 'index.php', 'runtime' => 'php-8.0', 'execute' => [Role::any()->toString()], ]