Merge branch '1.8.x' into chore-upgrade-cache

This commit is contained in:
premtsd-code 2026-02-02 18:22:02 +00:00 committed by GitHub
commit 47e406baa0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 237 additions and 113 deletions

2
.env
View file

@ -26,7 +26,7 @@ _APP_DNS=172.16.238.100 # CoreDNS
_APP_DOMAIN=appwrite.test
_APP_CONSOLE_DOMAIN=localhost
_APP_DOMAIN_FUNCTIONS=functions.localhost
_APP_DOMAIN_SITES=sites.localhost
_APP_DOMAIN_SITES=sites.localhost,rebranded.localhost
_APP_DOMAIN_TARGET_CNAME=cname.localhost
_APP_DOMAIN_TARGET_A=203.0.0.1
_APP_DOMAIN_TARGET_AAAA=::1

View file

@ -2,6 +2,17 @@
use Utopia\System\System;
// For now, take first domain as primary (for previews)
// Later-on this can become platform-specific with new env var (appwrite=this,imagine=that)
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
if (\str_contains($sitesDomain, ',')) {
$sitesDomain = explode(',', $sitesDomain)[0];
}
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
if (\str_contains($functionsDomain, ',')) {
$functionsDomain = explode(',', $functionsDomain)[0];
}
/**
* Platform configuration
*/
@ -23,5 +34,6 @@ return [
'privacyUrl' => APP_EMAIL_PRIVACY_URL,
'websiteUrl' => 'https://' . APP_DOMAIN,
'emailSenderName' => APP_EMAIL_PLATFORM_NAME,
'sitePreviewDomain' => System::getEnv('_APP_DOMAIN_SITES', ''),
'sitesDomain' => $sitesDomain,
'functionsDomain' => $functionsDomain,
];

View file

@ -341,7 +341,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
$projectId = $project->getId();
// Deployment preview
$sitesDomain = $platform['sitePreviewDomain'];
$sitesDomain = $platform['sitesDomain'];
$domain = ID::unique() . "." . $sitesDomain;
$ruleId = md5($domain);
$previewRuleId = $ruleId;

View file

@ -85,22 +85,32 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
$platformHostnames = $platform['hostnames'] ?? [];
if ($rule->isEmpty()) {
$appDomainFunctionsFallback = System::getEnv('_APP_DOMAIN_FUNCTIONS_FALLBACK', '');
$appDomainFunctions = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
$appDomainSites = System::getEnv('_APP_DOMAIN_SITES', '');
if (!empty($appDomainFunctionsFallback) && \str_ends_with($host, $appDomainFunctionsFallback)) {
$appDomainFunctions = $appDomainFunctionsFallback;
$denyDomains = [];
$denyEnvVars = [
System::getEnv('_APP_DOMAIN_FUNCTIONS_FALLBACK', ''),
System::getEnv('_APP_DOMAIN_FUNCTIONS', ''),
System::getEnv('_APP_DOMAIN_SITES', ''),
];
foreach ($denyEnvVars as $denyEnvVar) {
foreach (\explode(',', $denyEnvVar) as $denyDomain) {
if (empty($denyDomain)) {
continue;
}
$denyDomains[] = $denyDomain;
}
}
if ($host === $appDomainFunctions || $host === $appDomainSites) {
throw new AppwriteException(AppwriteException::GENERAL_ACCESS_FORBIDDEN, 'This domain cannot be used for security reasons. Please use any subdomain instead.', view: $errorView);
}
foreach ($denyDomains as $denyDomain) {
if ($host === $denyDomain) {
throw new AppwriteException(AppwriteException::GENERAL_ACCESS_FORBIDDEN, 'This domain cannot be used for security reasons. Please use any subdomain instead.', view: $errorView);
}
if (\str_ends_with($host, $appDomainFunctions) || \str_ends_with($host, $appDomainSites)) {
$exception = new AppwriteException(AppwriteException::RULE_NOT_FOUND, 'This domain is not connected to any Appwrite resources. Visit domains tab under function/site settings to configure it.', view: $errorView);
if (\str_ends_with($host, $denyDomain)) {
$exception = new AppwriteException(AppwriteException::RULE_NOT_FOUND, 'This domain is not connected to any Appwrite resources. Visit domains tab under function/site settings to configure it.', view: $errorView);
$exception->addCTA('Start with this domain', $url . '/console');
throw $exception;
$exception->addCTA('Start with this domain', $url . '/console');
throw $exception;
}
}
if (!in_array($host, $platformHostnames)) {
@ -1094,19 +1104,28 @@ App::init()
// 5. Create new rule
$owner = '';
$fallback = System::getEnv('_APP_DOMAIN_FUNCTIONS_FALLBACK', '');
$funcDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
$siteDomain = System::getEnv('_APP_DOMAIN_SITES', '');
if (!empty($fallback) && \str_ends_with($domain->get(), $fallback)) {
$funcDomain = $fallback;
// Mark owner as Appwrite if its appwrite-owned domain
$appwriteDomains = [];
$appwriteDomainEnvs = [
System::getEnv('_APP_DOMAIN_FUNCTIONS_FALLBACK', ''),
System::getEnv('_APP_DOMAIN_FUNCTIONS', ''),
System::getEnv('_APP_DOMAIN_SITES', ''),
];
foreach ($appwriteDomainEnvs as $appwriteDomainEnv) {
foreach (\explode(',', $appwriteDomainEnv) as $appwriteDomain) {
if (empty($appwriteDomain)) {
continue;
}
$appwriteDomains[] = $appwriteDomain;
}
}
if (
(!empty($funcDomain) && \str_ends_with($domain->get(), $funcDomain)) ||
(!empty($siteDomain) && \str_ends_with($domain->get(), $siteDomain))
) {
$owner = 'Appwrite';
foreach ($appwriteDomains as $appwriteDomain) {
if (\str_ends_with($domain->get(), $appwriteDomain)) {
$owner = 'Appwrite';
break;
}
}
$ruleId = $isMd5 ? md5($domain->get()) : ID::unique();

View file

@ -100,11 +100,19 @@ function dispatch(Server $server, int $fd, int $type, $data = null): int
$risky = false;
if (str_starts_with($request, 'POST') && str_contains($request, '/executions')) {
$risky = true;
} elseif (str_ends_with($domain, System::getEnv('_APP_DOMAIN_FUNCTIONS'))) {
$risky = true;
} elseif ($domains->get(md5($domain), 'value') === 1) {
// executions request coming from custom domain
$risky = true;
} else {
foreach (\explode(',', System::getEnv('_APP_DOMAIN_FUNCTIONS')) as $riskyDomain) {
if (empty($riskyDomain)) {
continue;
}
if (str_ends_with($domain, $riskyDomain)) {
$risky = true;
break;
}
}
}
if ($risky) {
@ -591,9 +599,33 @@ $http->on(Constant::EVENT_TASK, function () use ($register, $domains) {
$sum = count($results);
foreach ($results as $document) {
$domain = $document->getAttribute('domain');
if (str_ends_with($domain, System::getEnv('_APP_DOMAIN_FUNCTIONS')) || str_ends_with($domain, System::getEnv('_APP_DOMAIN_SITES'))) {
$denyDomains = [];
$denyEnvVars = [
System::getEnv('_APP_DOMAIN_FUNCTIONS_FALLBACK', ''),
System::getEnv('_APP_DOMAIN_FUNCTIONS', ''),
System::getEnv('_APP_DOMAIN_SITES', ''),
];
foreach ($denyEnvVars as $denyEnvVar) {
foreach (\explode(',', $denyEnvVar) as $denyDomain) {
if (empty($denyDomain)) {
continue;
}
$denyDomains[] = $denyDomain;
}
}
$isDenyDomain = false;
foreach ($denyDomains as $denyDomain) {
if (str_ends_with($domain, $denyDomain)) {
$isDenyDomain = true;
}
}
if ($isDenyDomain) {
continue;
}
$domains->set(md5($domain), ['value' => 1]);
}
$latestDocument = !empty(array_key_last($results)) ? $results[array_key_last($results)] : null;

View file

@ -235,7 +235,7 @@ class Base extends Action
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument('sites', $site->getId(), $site);
$sitesDomain = $platform['sitePreviewDomain'];
$sitesDomain = $platform['sitesDomain'];
$domain = ID::unique() . "." . $sitesDomain;
// TODO: (@Meldiron) Remove after 1.7.x migration

View file

@ -74,36 +74,41 @@ class Get extends Action
) {
$domains = $platform['hostnames'] ?? [];
if ($type === 'rules') {
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
$deniedDomains = [...$domains];
$restrictions = [];
if (!empty($sitesDomain)) {
$sitesDomains = System::getEnv('_APP_DOMAIN_SITES', '');
foreach (\explode(',', $sitesDomains) as $sitesDomain) {
if (empty($sitesDomain)) {
continue;
}
$deniedDomains[] = $sitesDomain;
// Ensure site domains are exactly 1 subdomain, and dont start with reserved prefix
$domainLevel = \count(\explode('.', $sitesDomain));
$restrictions[] = DomainValidator::createRestriction($sitesDomain, $domainLevel + 1, ['commit-', 'branch-']);
}
if (!empty($functionsDomain)) {
$functionsDomains = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
foreach (\explode(',', $functionsDomains) as $functionsDomain) {
if (empty($functionsDomain)) {
continue;
}
$deniedDomains[] = $functionsDomain;
// Ensure function domains are exactly 1 subdomain
$domainLevel = \count(\explode('.', $functionsDomain));
$restrictions[] = DomainValidator::createRestriction($functionsDomain, $domainLevel + 1);
}
$validator = new DomainValidator($restrictions);
if (!$validator->isValid($value)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
}
$deniedDomains = [...$domains];
if (!empty($sitesDomain)) {
$deniedDomains[] = $sitesDomain;
}
if (!empty($functionsDomain)) {
$deniedDomains[] = $functionsDomain;
}
$denyListDomains = System::getEnv('_APP_CUSTOM_DOMAIN_DENY_LIST', '');
$denyListDomains = \array_map('trim', explode(',', $denyListDomains));
foreach ($denyListDomains as $denyListDomain) {

View file

@ -46,10 +46,11 @@ class Get extends Action
contentType: ContentType::JSON
))
->inject('response')
->inject('platform')
->callback($this->action(...));
}
public function action(Response $response)
public function action(Response $response, array $platform)
{
$validator = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME'));
$isCNAMEValid = !empty(System::getEnv('_APP_DOMAIN_TARGET_CNAME', '')) && $validator->isKnown() && !$validator->isTest();
@ -82,8 +83,8 @@ class Get extends Action
'_APP_VCS_ENABLED' => $isVcsEnabled,
'_APP_DOMAIN_ENABLED' => $isDomainEnabled,
'_APP_ASSISTANT_ENABLED' => $isAssistantEnabled,
'_APP_DOMAIN_SITES' => System::getEnv('_APP_DOMAIN_SITES'),
'_APP_DOMAIN_FUNCTIONS' => System::getEnv('_APP_DOMAIN_FUNCTIONS'),
'_APP_DOMAIN_SITES' => $platform['sitesDomain'],
'_APP_DOMAIN_FUNCTIONS' => $platform['functionsDomain'],
'_APP_OPTIONS_FORCE_HTTPS' => System::getEnv('_APP_OPTIONS_FORCE_HTTPS'),
'_APP_DOMAINS_NAMESERVERS' => System::getEnv('_APP_DOMAINS_NAMESERVERS'),
]);

View file

@ -116,6 +116,7 @@ class Create extends Base
->inject('request')
->inject('gitHub')
->inject('authorization')
->inject('platform')
->callback($this->action(...));
}
@ -154,7 +155,8 @@ class Create extends Base
Database $dbForPlatform,
Request $request,
GitHub $github,
Authorization $authorization
Authorization $authorization,
array $platform
) {
// Temporary abuse check
@ -321,7 +323,6 @@ class Create extends Base
template: $template,
github: $github,
activate: true,
authorization: $authorization,
reference: $providerBranch,
referenceType: 'branch'
);
@ -366,7 +367,7 @@ class Create extends Base
->setTemplate($template);
}
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
$functionsDomain = $platform['functionsDomain'];
if (!empty($functionsDomain)) {
$routeSubdomain = ID::unique();
$domain = "{$routeSubdomain}.{$functionsDomain}";

View file

@ -1037,7 +1037,7 @@ class Builds extends Action
// VCS branch
$branchName = $deployment->getAttribute('providerBranch');
if (!empty($branchName)) {
$sitesDomain = $platform['sitePreviewDomain'];
$sitesDomain = $platform['sitesDomain'];
$branchPrefix = substr($branchName, 0, 16);
if (strlen($branchName) > 16) {
$remainingChars = substr($branchName, 16);

View file

@ -31,34 +31,42 @@ class Action extends PlatformAction
protected function validateDomainRestrictions(string $domain, array $platform): void
{
$domains = $platform['hostnames'] ?? [];
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
$deniedDomains = [...$domains];
$restrictions = [];
if (!empty($sitesDomain)) {
$sitesDomains = System::getEnv('_APP_DOMAIN_SITES', '');
foreach (\explode(',', $sitesDomains) as $sitesDomain) {
if (empty($sitesDomain)) {
continue;
}
$deniedDomains[] = $sitesDomain;
// Ensure site domains are exactly 1 subdomain, and dont start with reserved prefix
$domainLevel = \count(\explode('.', $sitesDomain));
$restrictions[] = ValidatorDomain::createRestriction($sitesDomain, $domainLevel + 1, ['commit-', 'branch-']);
}
if (!empty($functionsDomain)) {
$functionsDomains = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
foreach (\explode(',', $functionsDomains) as $functionsDomain) {
if (empty($functionsDomains)) {
continue;
}
$deniedDomains[] = $functionsDomain;
// Ensure function domains are exactly 1 subdomain
$domainLevel = \count(\explode('.', $functionsDomain));
$restrictions[] = ValidatorDomain::createRestriction($functionsDomain, $domainLevel + 1);
}
$validator = new ValidatorDomain($restrictions);
if (!$validator->isValid($domain)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
}
$deniedDomains = [...$domains];
if (!empty($sitesDomain)) {
$deniedDomains[] = $sitesDomain;
}
if (!empty($functionsDomain)) {
$deniedDomains[] = $functionsDomain;
}
$denyListDomains = System::getEnv('_APP_CUSTOM_DOMAIN_DENY_LIST', '');
$denyListDomains = \array_map('trim', explode(',', $denyListDomains));
foreach ($denyListDomains as $denyListDomain) {
@ -117,31 +125,51 @@ class Action extends PlatformAction
}
}
$targetCNAME = null;
$targetCNAMEs = [];
$ruleType = $rule->getAttribute('type', '');
$resourceType = $rule->getAttribute('deploymentResourceType', '');
// Ensures different target based on rule's type, as configured by env variables
if ($resourceType === 'function') {
// For example: fra.appwrite.run
$targetCNAME = new Domain(System::getEnv('_APP_DOMAIN_FUNCTIONS', ''));
foreach (\explode(',', System::getEnv('_APP_DOMAIN_FUNCTIONS', '')) as $targetCNAME) {
if (empty($targetCNAME)) {
continue;
}
$targetCNAMEs[] = new Domain($targetCNAME);
}
} elseif ($resourceType === 'site') {
// For example: appwrite.network
$targetCNAME = new Domain(System::getEnv('_APP_DOMAIN_SITES', ''));
foreach (\explode(',', System::getEnv('_APP_DOMAIN_SITES', '')) as $targetCNAME) {
if (empty($targetCNAME)) {
continue;
}
$targetCNAMEs[] = new Domain($targetCNAME);
}
} elseif ($ruleType === 'api') {
// For example: fra.cloud.appwrite.io
$targetCNAME = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME', ''));
$targetCNAMEs[] = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME', ''));
} elseif ($ruleType === 'redirect') {
// Shouldn't be needed, because redirect should always have resourceTyp too, but just in case we default to sites
// For example: appwrite.network
$targetCNAME = new Domain(System::getEnv('_APP_DOMAIN_SITES', ''));
foreach (\explode(',', System::getEnv('_APP_DOMAIN_SITES', '')) as $targetCNAME) {
if (empty($targetCNAME)) {
continue;
}
$targetCNAMEs[] = new Domain($targetCNAME);
}
}
$validators = [];
$mainValidator = null; // Validator to use for error description
if (!is_null($targetCNAME)) {
$validator = new $dnsValidatorClass($targetCNAME->get(), Record::TYPE_CNAME, $dnsServers);
if (\count($targetCNAMEs) > 0) {
$cnameValidators = [];
foreach ($targetCNAMEs as $targetCNAME) {
$cnameValidators[] = new $dnsValidatorClass($targetCNAME->get(), Record::TYPE_CNAME, $dnsServers);
}
$validator = new AnyOf($cnameValidators);
$validators[] = $validator;
if (\is_null($mainValidator)) {
@ -185,4 +213,30 @@ class Action extends PlatformAction
throw new Exception(Exception::RULE_VERIFICATION_FAILED, $mainValidator->getDescription());
}
}
protected function isAppwriteOwned(string $domain): bool
{
$appwriteDomains = [];
$appwriteDomainEnvs = [
System::getEnv('_APP_DOMAIN_FUNCTIONS_FALLBACK', ''),
System::getEnv('_APP_DOMAIN_FUNCTIONS', ''),
System::getEnv('_APP_DOMAIN_SITES', ''),
];
foreach ($appwriteDomainEnvs as $appwriteDomainEnv) {
foreach (\explode(',', $appwriteDomainEnv) as $appwriteDomain) {
if (empty($appwriteDomain)) {
continue;
}
$appwriteDomains[] = $appwriteDomain;
}
}
foreach ($appwriteDomains as $appwriteDomain) {
if (\str_ends_with($domain, $appwriteDomain)) {
return true;
}
}
return false;
}
}

View file

@ -74,18 +74,12 @@ class Create extends Action
{
$this->validateDomainRestrictions($domain, $platform);
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
// TODO: (@Meldiron) Remove after 1.7.x migration
$ruleId = System::getEnv('_APP_RULES_FORMAT') === 'md5' ? md5($domain) : ID::unique();
$status = RULE_STATUS_CREATED;
$owner = '';
if (
($functionsDomain != '' && \str_ends_with($domain, $functionsDomain)) ||
($sitesDomain != '' && \str_ends_with($domain, $sitesDomain))
) {
if ($this->isAppwriteOwned($domain)) {
$status = RULE_STATUS_VERIFIED;
$owner = 'Appwrite';
}

View file

@ -79,9 +79,6 @@ class Create extends Action
{
$this->validateDomainRestrictions($domain, $platform);
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception(Exception::RULE_RESOURCE_NOT_FOUND);
@ -94,10 +91,7 @@ class Create extends Action
$status = RULE_STATUS_CREATED;
$owner = '';
if (
($functionsDomain != '' && \str_ends_with($domain, $functionsDomain)) ||
($sitesDomain != '' && \str_ends_with($domain, $sitesDomain))
) {
if ($this->isAppwriteOwned($domain)) {
$status = RULE_STATUS_VERIFIED;
$owner = 'Appwrite';
}

View file

@ -82,9 +82,6 @@ class Create extends Action
{
$this->validateDomainRestrictions($domain, $platform);
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
$collection = match ($resourceType) {
'site' => 'sites',
'function' => 'functions'
@ -99,10 +96,7 @@ class Create extends Action
$status = RULE_STATUS_CREATED;
$owner = '';
if (
($functionsDomain != '' && \str_ends_with($domain, $functionsDomain)) ||
($sitesDomain != '' && \str_ends_with($domain, $sitesDomain))
) {
if ($this->isAppwriteOwned($domain)) {
$status = RULE_STATUS_VERIFIED;
$owner = 'Appwrite';
}

View file

@ -79,9 +79,6 @@ class Create extends Action
{
$this->validateDomainRestrictions($domain, $platform);
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
$site = $dbForProject->getDocument('sites', $siteId);
if ($site->isEmpty()) {
throw new Exception(Exception::RULE_RESOURCE_NOT_FOUND);
@ -94,10 +91,7 @@ class Create extends Action
$status = RULE_STATUS_CREATED;
$owner = '';
if (
($functionsDomain != '' && \str_ends_with($domain, $functionsDomain)) ||
($sitesDomain != '' && \str_ends_with($domain, $sitesDomain))
) {
if ($this->isAppwriteOwned($domain)) {
$status = RULE_STATUS_VERIFIED;
$owner = 'Appwrite';
}

View file

@ -274,7 +274,7 @@ class Create extends Action
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument('sites', $site->getId(), $site);
$sitesDomain = $platform['sitePreviewDomain'];
$sitesDomain = $platform['sitesDomain'];
$domain = ID::unique() . "." . $sitesDomain;
// TODO: (@Meldiron) Remove after 1.7.x migration
@ -344,7 +344,7 @@ class Create extends Action
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument('sites', $site->getId(), $site);
$sitesDomain = $platform['sitePreviewDomain'];
$sitesDomain = $platform['sitesDomain'];
$domain = ID::unique() . "." . $sitesDomain;
$ruleId = md5($domain);
$authorization->skip(

View file

@ -145,7 +145,7 @@ class Create extends Action
$dbForProject->updateDocument('sites', $site->getId(), $site);
// Preview deployments for sites
$sitesDomain = $platform['sitePreviewDomain'];
$sitesDomain = $platform['sitesDomain'];
$domain = ID::unique() . "." . $sitesDomain;
// TODO: (@Meldiron) Remove after 1.7.x migration

View file

@ -189,7 +189,7 @@ class Create extends Base
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument('sites', $site->getId(), $site);
$sitesDomain = $platform['sitePreviewDomain'];
$sitesDomain = $platform['sitesDomain'];
$domain = ID::unique() . "." . $sitesDomain;
// TODO: (@Meldiron) Remove after 1.7.x migration

View file

@ -1283,6 +1283,7 @@ class UsageTest extends Scope
$this->assertEquals(200, $response['headers']['status-code']);
$functionsDomain = \explode(',', System::getEnv('_APP_DOMAIN_FUNCTIONS', ''))[0];
$rule = $this->client->call(
Client::METHOD_POST,
'/proxy/rules/function',
@ -1291,7 +1292,7 @@ class UsageTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()),
[
'domain' => 'test-' . ID::unique() . '.' . System::getEnv('_APP_DOMAIN_FUNCTIONS'),
'domain' => 'test-' . ID::unique() . '.' . $functionsDomain,
'functionId' => $functionId,
],
);

View file

@ -316,12 +316,13 @@ trait FunctionsBase
protected function setupFunctionDomain(string $functionId, string $subdomain = ''): string
{
$functionsDomain = \explode(',', System::getEnv('_APP_DOMAIN_FUNCTIONS', ''))[0];
$subdomain = $subdomain ? $subdomain : ID::unique();
$rule = $this->client->call(Client::METHOD_POST, '/proxy/rules/function', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'domain' => $subdomain . '.' . System::getEnv('_APP_DOMAIN_FUNCTIONS', ''),
'domain' => $subdomain . '.' . $functionsDomain,
'functionId' => $functionId,
]);

View file

@ -50,7 +50,7 @@ class ProjectsCustomServerTest extends Scope
$this->assertEquals(204, $response['headers']['status-code']);
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
$functionsDomain = \explode(',', System::getEnv('_APP_DOMAIN_FUNCTIONS', ''))[0];
$response = $this->client->call(Client::METHOD_POST, '/proxy/rules/api', $headers, [
'domain' => $functionsDomain,
@ -59,7 +59,7 @@ class ProjectsCustomServerTest extends Scope
$this->assertEquals(400, $response['headers']['status-code']);
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$sitesDomain = \explode(',', System::getEnv('_APP_DOMAIN_SITES', ''))[0];
$response = $this->client->call(Client::METHOD_POST, '/proxy/rules/api', $headers, [
'domain' => $sitesDomain,

View file

@ -112,7 +112,8 @@ class ProxyCustomServerTest extends Scope
$this->assertEquals(201, $rule['headers']['status-code']);
$this->cleanupRule($rule['body']['$id']);
$domain = \uniqid() . '-vcs.' . System::getEnv('_APP_DOMAIN_SITES', '');
$sitesDomain = \explode(',', System::getEnv('_APP_DOMAIN_SITES', ''))[0];
$domain = \uniqid() . '-vcs.' . $sitesDomain;
$rule = $this->createSiteRule('commit-' . $domain, $siteId);
$this->assertEquals(400, $rule['headers']['status-code']);
@ -292,11 +293,28 @@ class ProxyCustomServerTest extends Scope
$ruleId = $this->setupSiteRule($domain, $siteId);
$this->assertNotEmpty($ruleId);
$rule = $this->getRule($ruleId);
$this->assertSame(200, $rule['headers']['status-code']);
$this->assertSame('created', $rule['body']['status']);
$response = $proxyClient->call(Client::METHOD_GET, '/contact');
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertStringContainsString('Contact page', $response['body']);
// Wildcard domains automatically get verified status
$domains = [
\uniqid() . '.sites.localhost',
\uniqid() . '.rebranded.localhost',
];
foreach ($domains as $domain) {
$wildcardRuleId = $this->setupSiteRule($domain, $siteId);
$this->assertNotEmpty($wildcardRuleId);
$rule = $this->getRule($wildcardRuleId);
$this->assertSame(200, $rule['headers']['status-code']);
$this->assertSame('verified', $rule['body']['status']);
$this->cleanupRule($wildcardRuleId);
}
$rules = $this->listRules([
'queries' => [
Query::limit(1)->toString(),
@ -384,7 +402,8 @@ class ProxyCustomServerTest extends Scope
public function testUpdateRule(): void
{
// Create function appwrite-network domain
$domain = \uniqid() . '-cname-api.' . System::getEnv('_APP_DOMAIN_FUNCTIONS');
$functionsDomain = \explode(',', System::getEnv('_APP_DOMAIN_FUNCTIONS', ''))[0];
$domain = \uniqid() . '-cname-api.' . $functionsDomain;
$rule = $this->createAPIRule($domain);
$this->assertEquals(201, $rule['headers']['status-code']);
@ -393,7 +412,8 @@ class ProxyCustomServerTest extends Scope
$this->cleanupRule($rule['body']['$id']);
// Create site appwrite-network domain
$domain = \uniqid() . '-cname-api.' . System::getEnv('_APP_DOMAIN_SITES');
$sitesDomain = \explode(',', System::getEnv('_APP_DOMAIN_SITES', ''))[0];
$domain = \uniqid() . '-cname-api.' . $sitesDomain;
$rule = $this->createAPIRule($domain);
$this->assertEquals(201, $rule['headers']['status-code']);

View file

@ -368,12 +368,13 @@ trait SitesBase
protected function setupSiteDomain(string $siteId, string $subdomain = ''): string
{
$sitesDomain = \explode(',', System::getEnv('_APP_DOMAIN_SITES', ''))[0];
$subdomain = $subdomain ? $subdomain : ID::unique();
$rule = $this->client->call(Client::METHOD_POST, '/proxy/rules/site', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'domain' => $subdomain . '.' . System::getEnv('_APP_DOMAIN_SITES', ''),
'domain' => $subdomain . '.' . $sitesDomain,
'siteId' => $siteId,
]);

View file

@ -1810,11 +1810,12 @@ class SitesCustomServerTest extends Scope
$siteId2 = $site2['body']['$id'];
$sitesDomain = \explode(',', System::getEnv('_APP_DOMAIN_SITES', ''))[0];
$rule = $this->client->call(Client::METHOD_POST, '/proxy/rules/site', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'domain' => $subdomain . '.' . System::getEnv('_APP_DOMAIN_SITES', ''),
'domain' => $subdomain . '.' . $sitesDomain,
'siteId' => $siteId2,
]);