mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Merge pull request #9627 from appwrite/feat-a-record
Feat: A/AAA record support
This commit is contained in:
@@ -23,7 +23,9 @@ _APP_OPENSSL_KEY_V1=your-secret-key
|
||||
_APP_DOMAIN=traefik
|
||||
_APP_DOMAIN_FUNCTIONS=functions.localhost
|
||||
_APP_DOMAIN_SITES=sites.localhost
|
||||
_APP_DOMAIN_TARGET=test.appwrite.io
|
||||
_APP_DOMAIN_TARGET_CNAME=test.appwrite.io
|
||||
_APP_DOMAIN_TARGET_A=127.0.0.1
|
||||
_APP_DOMAIN_TARGET_AAAA=::1
|
||||
_APP_RULES_FORMAT=md5
|
||||
_APP_REDIS_HOST=redis
|
||||
_APP_REDIS_PORT=6379
|
||||
|
||||
@@ -90,13 +90,40 @@ return [
|
||||
],
|
||||
[
|
||||
'name' => '_APP_DOMAIN_TARGET',
|
||||
'description' => 'A DNS A record hostname to serve as a CNAME target for your Appwrite custom domains. You can use the same value as used for the Appwrite \'_APP_DOMAIN\' variable. The default value is \'localhost\'.',
|
||||
'description' => 'Deprecated since 1.7.0. A DNS A record hostname to serve as a CNAME target for your Appwrite custom domains. You can use the same value as used for the Appwrite \'_APP_DOMAIN\' variable. The default value is \'localhost\'.',
|
||||
'introduction' => '',
|
||||
'default' => 'localhost',
|
||||
'required' => true,
|
||||
'question' => 'Enter a DNS A record hostname to serve as a CNAME for your custom domains.' . PHP_EOL . 'You can use the same value as used for the Appwrite hostname.',
|
||||
'filter' => 'domainTarget'
|
||||
],
|
||||
[
|
||||
'name' => '_APP_DOMAIN_TARGET_CNAME',
|
||||
'description' => 'A domain that can be used as DNS CNAME record to point to instance of Appwrite server.',
|
||||
'introduction' => '',
|
||||
'default' => 'localhost',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_DOMAIN_TARGET_AAAA',
|
||||
'description' => 'An IPv6 that can be used as DNS AAAA record to point to instance of Appwrite server.',
|
||||
'introduction' => '',
|
||||
'default' => '::1',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_DOMAIN_TARGET_A',
|
||||
'description' => 'An IPV4 that can be used as DNS A record to point to instance of Appwrite server.',
|
||||
'introduction' => '',
|
||||
'default' => '127.0.0.1',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_CONSOLE_WHITELIST_ROOT',
|
||||
'description' => 'This option allows you to disable the creation of new users on the Appwrite console. When enabled only 1 user will be able to use the registration form. New users can be added by inviting them to your project. By default this option is enabled.',
|
||||
|
||||
@@ -8,7 +8,9 @@ use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Domains\Domain;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\IP;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
App::init()
|
||||
@@ -40,10 +42,21 @@ App::get('/v1/console/variables')
|
||||
))
|
||||
->inject('response')
|
||||
->action(function (Response $response) {
|
||||
$isDomainEnabled = !empty(System::getEnv('_APP_DOMAIN', ''))
|
||||
&& !empty(System::getEnv('_APP_DOMAIN_TARGET', ''))
|
||||
&& System::getEnv('_APP_DOMAIN', '') !== 'localhost'
|
||||
&& System::getEnv('_APP_DOMAIN_TARGET', '') !== 'localhost';
|
||||
$validator = new Domain(System::getEnv('_APP_DOMAIN'));
|
||||
$isDomainValid = !empty(System::getEnv('_APP_DOMAIN', '')) && $validator->isKnown() && !$validator->isTest();
|
||||
|
||||
$validator = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME'));
|
||||
$isCNAMEValid = !empty(System::getEnv('_APP_DOMAIN_TARGET_CNAME', '')) && $validator->isKnown() && !$validator->isTest();
|
||||
|
||||
$validator = new IP(IP::V4);
|
||||
$isAValid = !empty(System::getEnv('_APP_DOMAIN_TARGET_A', '')) && ($validator->isValid(System::getEnv('_APP_DOMAIN_TARGET_A')));
|
||||
|
||||
$validator = new IP(IP::V6);
|
||||
$isAAAAValid = !empty(System::getEnv('_APP_DOMAIN_TARGET_AAAA', '')) && $validator->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA'));
|
||||
|
||||
$isDomainEnabled = $isDomainValid && (
|
||||
$isAAAAValid || $isAValid || $isCNAMEValid
|
||||
);
|
||||
|
||||
$isVcsEnabled = !empty(System::getEnv('_APP_VCS_GITHUB_APP_NAME', ''))
|
||||
&& !empty(System::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY', ''))
|
||||
@@ -54,7 +67,9 @@ App::get('/v1/console/variables')
|
||||
$isAssistantEnabled = !empty(System::getEnv('_APP_ASSISTANT_OPENAI_API_KEY', ''));
|
||||
|
||||
$variables = new Document([
|
||||
'_APP_DOMAIN_TARGET' => System::getEnv('_APP_DOMAIN_TARGET'),
|
||||
'_APP_DOMAIN_TARGET_CNAME' => System::getEnv('_APP_DOMAIN_TARGET_CNAME'),
|
||||
'_APP_DOMAIN_TARGET_AAAA' => System::getEnv('_APP_DOMAIN_TARGET_AAAA'),
|
||||
'_APP_DOMAIN_TARGET_A' => System::getEnv('_APP_DOMAIN_TARGET_A'),
|
||||
'_APP_STORAGE_LIMIT' => +System::getEnv('_APP_STORAGE_LIMIT'),
|
||||
'_APP_COMPUTE_SIZE_LIMIT' => +System::getEnv('_APP_COMPUTE_SIZE_LIMIT'),
|
||||
'_APP_USAGE_STATS' => System::getEnv('_APP_USAGE_STATS'),
|
||||
|
||||
@@ -4,7 +4,7 @@ use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Delete;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\CNAME;
|
||||
use Appwrite\Network\Validator\DNS;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Method;
|
||||
@@ -21,6 +21,8 @@ use Utopia\Database\Validator\UID;
|
||||
use Utopia\Domains\Domain;
|
||||
use Utopia\Logger\Log;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\AnyOf;
|
||||
use Utopia\Validator\IP;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
App::get('/v1/proxy/rules')
|
||||
@@ -208,17 +210,27 @@ App::patch('/v1/proxy/rules/:ruleId/verification')
|
||||
throw new Exception(Exception::RULE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$target = new Domain(System::getEnv('_APP_DOMAIN_TARGET', ''));
|
||||
$validators = [];
|
||||
$targetCNAME = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME', ''));
|
||||
if (!$targetCNAME->isKnown() || $targetCNAME->isTest()) {
|
||||
$validators[] = new DNS($targetCNAME->get(), DNS::RECORD_CNAME);
|
||||
}
|
||||
if ((new IP(IP::V4))->isValid(System::getEnv('_APP_DOMAIN_TARGET_A', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_A', ''), DNS::RECORD_A);
|
||||
}
|
||||
if ((new IP(IP::V6))->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''), DNS::RECORD_AAAA);
|
||||
}
|
||||
|
||||
if (!$target->isKnown() || $target->isTest()) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Domain target must be configured as environment variable.');
|
||||
if (empty($validators)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'At least one of domain targets environment variable must be configured.');
|
||||
}
|
||||
|
||||
if ($rule->getAttribute('verification') === true) {
|
||||
return $response->dynamic($rule, Response::MODEL_PROXY_RULE);
|
||||
}
|
||||
|
||||
$validator = new CNAME($target->get()); // Verify Domain with DNS records
|
||||
$validator = new AnyOf($validators, AnyOf::TYPE_STRING);
|
||||
$domain = new Domain($rule->getAttribute('domain', ''));
|
||||
|
||||
$validationStart = \microtime(true);
|
||||
@@ -226,7 +238,14 @@ App::patch('/v1/proxy/rules/:ruleId/verification')
|
||||
$log->addExtra('dnsTiming', \strval(\microtime(true) - $validationStart));
|
||||
$log->addTag('dnsDomain', $domain->get());
|
||||
|
||||
$error = $validator->getLogs();
|
||||
$errors = [];
|
||||
foreach ($validators as $validator) {
|
||||
if (!empty($validator->getLogs())) {
|
||||
$errors[] = $validator->getLogs();
|
||||
}
|
||||
}
|
||||
|
||||
$error = \implode("\n", $errors);
|
||||
$log->addExtra('dnsResponse', \is_array($error) ? \json_encode($error) : \strval($error));
|
||||
|
||||
throw new Exception(Exception::RULE_VERIFICATION_FAILED);
|
||||
|
||||
Generated
+24
-24
@@ -1365,16 +1365,16 @@
|
||||
},
|
||||
{
|
||||
"name": "open-telemetry/sdk",
|
||||
"version": "1.2.2",
|
||||
"version": "1.2.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/opentelemetry-php/sdk.git",
|
||||
"reference": "37eec0fe47ddd627911f318f29b6cd48196be0c0"
|
||||
"reference": "0e7804c176c4b09d95b7985400aa38ce544cb7fc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/37eec0fe47ddd627911f318f29b6cd48196be0c0",
|
||||
"reference": "37eec0fe47ddd627911f318f29b6cd48196be0c0",
|
||||
"url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/0e7804c176c4b09d95b7985400aa38ce544cb7fc",
|
||||
"reference": "0e7804c176c4b09d95b7985400aa38ce544cb7fc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1451,7 +1451,7 @@
|
||||
"issues": "https://github.com/open-telemetry/opentelemetry-php/issues",
|
||||
"source": "https://github.com/open-telemetry/opentelemetry-php"
|
||||
},
|
||||
"time": "2025-01-29T21:40:28+00:00"
|
||||
"time": "2025-04-08T09:55:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "open-telemetry/sem-conv",
|
||||
@@ -3791,16 +3791,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/image",
|
||||
"version": "0.8.1",
|
||||
"version": "0.8.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/image.git",
|
||||
"reference": "e8cc7dd14f423270a1b7570ec0dae88a66195b63"
|
||||
"reference": "6c736965177f9a9e71311e22b80cfa88511768e9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/image/zipball/e8cc7dd14f423270a1b7570ec0dae88a66195b63",
|
||||
"reference": "e8cc7dd14f423270a1b7570ec0dae88a66195b63",
|
||||
"url": "https://api.github.com/repos/utopia-php/image/zipball/6c736965177f9a9e71311e22b80cfa88511768e9",
|
||||
"reference": "6c736965177f9a9e71311e22b80cfa88511768e9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3834,9 +3834,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/image/issues",
|
||||
"source": "https://github.com/utopia-php/image/tree/0.8.1"
|
||||
"source": "https://github.com/utopia-php/image/tree/0.8.2"
|
||||
},
|
||||
"time": "2025-04-04T18:55:20+00:00"
|
||||
"time": "2025-04-08T11:31:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/locale",
|
||||
@@ -3996,16 +3996,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/migration",
|
||||
"version": "0.8.4",
|
||||
"version": "0.8.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/migration.git",
|
||||
"reference": "845fd04ccf5e0edb03c184b864e0596080a432b8"
|
||||
"reference": "0dd95b148c581579ec05d2abbbdc13c2b4702331"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/845fd04ccf5e0edb03c184b864e0596080a432b8",
|
||||
"reference": "845fd04ccf5e0edb03c184b864e0596080a432b8",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/0dd95b148c581579ec05d2abbbdc13c2b4702331",
|
||||
"reference": "0dd95b148c581579ec05d2abbbdc13c2b4702331",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4046,9 +4046,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/migration/issues",
|
||||
"source": "https://github.com/utopia-php/migration/tree/0.8.4"
|
||||
"source": "https://github.com/utopia-php/migration/tree/0.8.5"
|
||||
},
|
||||
"time": "2025-03-28T02:08:22+00:00"
|
||||
"time": "2025-04-09T05:21:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/orchestration",
|
||||
@@ -5085,16 +5085,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel/pint",
|
||||
"version": "v1.21.2",
|
||||
"version": "v1.22.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/pint.git",
|
||||
"reference": "370772e7d9e9da087678a0edf2b11b6960e40558"
|
||||
"reference": "7ddfaa6523a675fae5c4123ee38fc6bfb8ee4f36"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/pint/zipball/370772e7d9e9da087678a0edf2b11b6960e40558",
|
||||
"reference": "370772e7d9e9da087678a0edf2b11b6960e40558",
|
||||
"url": "https://api.github.com/repos/laravel/pint/zipball/7ddfaa6523a675fae5c4123ee38fc6bfb8ee4f36",
|
||||
"reference": "7ddfaa6523a675fae5c4123ee38fc6bfb8ee4f36",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5105,9 +5105,9 @@
|
||||
"php": "^8.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.72.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.75.0",
|
||||
"illuminate/view": "^11.44.2",
|
||||
"larastan/larastan": "^3.2.0",
|
||||
"larastan/larastan": "^3.3.1",
|
||||
"laravel-zero/framework": "^11.36.1",
|
||||
"mockery/mockery": "^1.6.12",
|
||||
"nunomaduro/termwind": "^2.3",
|
||||
@@ -5147,7 +5147,7 @@
|
||||
"issues": "https://github.com/laravel/pint/issues",
|
||||
"source": "https://github.com/laravel/pint"
|
||||
},
|
||||
"time": "2025-03-14T22:31:42+00:00"
|
||||
"time": "2025-04-08T22:11:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "matthiasmullie/minify",
|
||||
|
||||
+12
-4
@@ -115,7 +115,9 @@ services:
|
||||
- _APP_OPTIONS_COMPUTE_FORCE_HTTPS
|
||||
- _APP_OPENSSL_KEY_V1
|
||||
- _APP_DOMAIN
|
||||
- _APP_DOMAIN_TARGET
|
||||
- _APP_DOMAIN_TARGET_CNAME
|
||||
- _APP_DOMAIN_TARGET_AAAA
|
||||
- _APP_DOMAIN_TARGET_A
|
||||
- _APP_DOMAIN_FUNCTIONS
|
||||
- _APP_REDIS_HOST
|
||||
- _APP_REDIS_PORT
|
||||
@@ -524,7 +526,9 @@ services:
|
||||
- _APP_WORKER_PER_CORE
|
||||
- _APP_OPENSSL_KEY_V1
|
||||
- _APP_DOMAIN
|
||||
- _APP_DOMAIN_TARGET
|
||||
- _APP_DOMAIN_TARGET_CNAME
|
||||
- _APP_DOMAIN_TARGET_AAAA
|
||||
- _APP_DOMAIN_TARGET_A
|
||||
- _APP_DOMAIN_FUNCTIONS
|
||||
- _APP_EMAIL_CERTIFICATES
|
||||
- _APP_REDIS_HOST
|
||||
@@ -690,7 +694,9 @@ services:
|
||||
- _APP_WORKER_PER_CORE
|
||||
- _APP_OPENSSL_KEY_V1
|
||||
- _APP_DOMAIN
|
||||
- _APP_DOMAIN_TARGET
|
||||
- _APP_DOMAIN_TARGET_CNAME
|
||||
- _APP_DOMAIN_TARGET_AAAA
|
||||
- _APP_DOMAIN_TARGET_A
|
||||
- _APP_EMAIL_SECURITY
|
||||
- _APP_REDIS_HOST
|
||||
- _APP_REDIS_PORT
|
||||
@@ -722,7 +728,9 @@ services:
|
||||
- _APP_ENV
|
||||
- _APP_WORKER_PER_CORE
|
||||
- _APP_DOMAIN
|
||||
- _APP_DOMAIN_TARGET
|
||||
- _APP_DOMAIN_TARGET_CNAME
|
||||
- _APP_DOMAIN_TARGET_AAAA
|
||||
- _APP_DOMAIN_TARGET_A
|
||||
- _APP_DOMAIN_FUNCTIONS
|
||||
- _APP_OPENSSL_KEY_V1
|
||||
- _APP_REDIS_HOST
|
||||
|
||||
@@ -4,24 +4,22 @@ namespace Appwrite\Network\Validator;
|
||||
|
||||
use Utopia\Validator;
|
||||
|
||||
class CNAME extends Validator
|
||||
class DNS extends Validator
|
||||
{
|
||||
public const RECORD_A = 'a';
|
||||
public const RECORD_AAAA = 'aaaa';
|
||||
public const RECORD_CNAME = 'cname';
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected mixed $logs;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $target;
|
||||
|
||||
/**
|
||||
* @param string $target
|
||||
*/
|
||||
public function __construct($target)
|
||||
public function __construct(protected $target, protected string $type = self::RECORD_CNAME)
|
||||
{
|
||||
$this->target = $target;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -29,7 +27,7 @@ class CNAME extends Validator
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Invalid CNAME record';
|
||||
return 'Invalid DNS record';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,20 +39,34 @@ class CNAME extends Validator
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if CNAME record target value matches selected target
|
||||
* Check if DNS record value matches specific value
|
||||
*
|
||||
* @param mixed $domain
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($domain): bool
|
||||
public function isValid($value): bool
|
||||
{
|
||||
if (!is_string($domain)) {
|
||||
$typeNative = match ($this->type) {
|
||||
self::RECORD_A => DNS_A,
|
||||
self::RECORD_AAAA => DNS_AAAA,
|
||||
self::RECORD_CNAME => DNS_CNAME,
|
||||
default => throw new \Exception('Record type not supported.')
|
||||
};
|
||||
|
||||
$dnsKey = match ($this->type) {
|
||||
self::RECORD_A => 'ip',
|
||||
self::RECORD_AAAA => 'ipv6',
|
||||
self::RECORD_CNAME => 'target',
|
||||
default => throw new \Exception('Record type not supported.')
|
||||
};
|
||||
|
||||
if (!is_string($value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$records = \dns_get_record($domain, DNS_CNAME);
|
||||
$records = \dns_get_record($value, $typeNative);
|
||||
$this->logs = $records;
|
||||
} catch (\Throwable $th) {
|
||||
return false;
|
||||
@@ -65,7 +77,7 @@ class CNAME extends Validator
|
||||
}
|
||||
|
||||
foreach ($records as $record) {
|
||||
if (isset($record['target']) && $record['target'] === $this->target) {
|
||||
if (isset($record[$dnsKey]) && $record[$dnsKey] === $this->target) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,11 @@ namespace Appwrite\Platform\Modules\Proxy\Http\Rules\API;
|
||||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\CNAME;
|
||||
use Appwrite\Network\Validator\DNS;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Duplicate;
|
||||
@@ -19,7 +18,9 @@ use Utopia\Domains\Domain;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\AnyOf;
|
||||
use Utopia\Validator\Domain as ValidatorDomain;
|
||||
use Utopia\Validator\IP;
|
||||
|
||||
class Create extends Action
|
||||
{
|
||||
@@ -95,13 +96,6 @@ class Create extends Action
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Domain may not start with http:// or https://.');
|
||||
}
|
||||
|
||||
// Apex domain prevention due to CNAME limitations
|
||||
if (empty(App::getEnv('_APP_DOMAINS_NAMESERVERS', ''))) {
|
||||
if ($domain->get() === $domain->getRegisterable()) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'The instance does not allow root-level (apex) domains.');
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: @christyjacob remove once we migrate the rules in 1.7.x
|
||||
$ruleId = System::getEnv('_APP_RULES_FORMAT') === 'md5' ? md5($domain->get()) : ID::unique();
|
||||
|
||||
@@ -110,8 +104,23 @@ class Create extends Action
|
||||
$status = 'verified';
|
||||
}
|
||||
if ($status === 'created') {
|
||||
$target = new Domain(System::getEnv('_APP_DOMAIN_TARGET', ''));
|
||||
$validator = new CNAME($target->get());
|
||||
$validators = [];
|
||||
$targetCNAME = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME', ''));
|
||||
if (!$targetCNAME->isKnown() || $targetCNAME->isTest()) {
|
||||
$validators[] = new DNS($targetCNAME->get(), DNS::RECORD_CNAME);
|
||||
}
|
||||
if ((new IP(IP::V4))->isValid(System::getEnv('_APP_DOMAIN_TARGET_A', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_A', ''), DNS::RECORD_A);
|
||||
}
|
||||
if ((new IP(IP::V6))->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''), DNS::RECORD_AAAA);
|
||||
}
|
||||
|
||||
if (empty($validators)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'At least one of domain targets environment variable must be configured.');
|
||||
}
|
||||
|
||||
$validator = new AnyOf($validators, AnyOf::TYPE_STRING);
|
||||
if ($validator->isValid($domain->get())) {
|
||||
$status = 'verifying';
|
||||
}
|
||||
|
||||
@@ -5,12 +5,11 @@ namespace Appwrite\Platform\Modules\Proxy\Http\Rules\Function;
|
||||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\CNAME;
|
||||
use Appwrite\Network\Validator\DNS;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Duplicate;
|
||||
@@ -20,7 +19,9 @@ use Utopia\Domains\Domain;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\AnyOf;
|
||||
use Utopia\Validator\Domain as ValidatorDomain;
|
||||
use Utopia\Validator\IP;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
class Create extends Action
|
||||
@@ -96,13 +97,6 @@ class Create extends Action
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Domain may not start with http:// or https://.');
|
||||
}
|
||||
|
||||
// Apex domain prevention due to CNAME limitations
|
||||
if (empty(App::getEnv('_APP_DOMAINS_NAMESERVERS', ''))) {
|
||||
if ($domain->get() === $domain->getRegisterable()) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'The instance does not allow root-level (apex) domains.');
|
||||
}
|
||||
}
|
||||
|
||||
$function = $dbForProject->getDocument('functions', $functionId);
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception(Exception::RULE_RESOURCE_NOT_FOUND);
|
||||
@@ -118,8 +112,23 @@ class Create extends Action
|
||||
$status = 'verified';
|
||||
}
|
||||
if ($status === 'created') {
|
||||
$target = new Domain(System::getEnv('_APP_DOMAIN_TARGET', ''));
|
||||
$validator = new CNAME($target->get());
|
||||
$validators = [];
|
||||
$targetCNAME = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME', ''));
|
||||
if (!$targetCNAME->isKnown() || $targetCNAME->isTest()) {
|
||||
$validators[] = new DNS($targetCNAME->get(), DNS::RECORD_CNAME);
|
||||
}
|
||||
if ((new IP(IP::V4))->isValid(System::getEnv('_APP_DOMAIN_TARGET_A', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_A', ''), DNS::RECORD_A);
|
||||
}
|
||||
if ((new IP(IP::V6))->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''), DNS::RECORD_AAAA);
|
||||
}
|
||||
|
||||
if (empty($validators)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'At least one of domain targets environment variable must be configured.');
|
||||
}
|
||||
|
||||
$validator = new AnyOf($validators, AnyOf::TYPE_STRING);
|
||||
if ($validator->isValid($domain->get())) {
|
||||
$status = 'verifying';
|
||||
}
|
||||
|
||||
@@ -5,12 +5,11 @@ namespace Appwrite\Platform\Modules\Proxy\Http\Rules\Redirect;
|
||||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\CNAME;
|
||||
use Appwrite\Network\Validator\DNS;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Duplicate;
|
||||
@@ -19,7 +18,9 @@ use Utopia\Domains\Domain;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\AnyOf;
|
||||
use Utopia\Validator\Domain as ValidatorDomain;
|
||||
use Utopia\Validator\IP;
|
||||
use Utopia\Validator\URL;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
@@ -95,13 +96,6 @@ class Create extends Action
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Domain may not start with http:// or https://.');
|
||||
}
|
||||
|
||||
// Apex domain prevention due to CNAME limitations
|
||||
if (empty(App::getEnv('_APP_DOMAINS_NAMESERVERS', ''))) {
|
||||
if ($domain->get() === $domain->getRegisterable()) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'The instance does not allow root-level (apex) domains.');
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: @christyjacob remove once we migrate the rules in 1.7.x
|
||||
$ruleId = System::getEnv('_APP_RULES_FORMAT') === 'md5' ? md5($domain->get()) : ID::unique();
|
||||
|
||||
@@ -110,8 +104,23 @@ class Create extends Action
|
||||
$status = 'verified';
|
||||
}
|
||||
if ($status === 'created') {
|
||||
$dnsTarget = new Domain(System::getEnv('_APP_DOMAIN_TARGET', ''));
|
||||
$validator = new CNAME($dnsTarget->get());
|
||||
$validators = [];
|
||||
$targetCNAME = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME', ''));
|
||||
if (!$targetCNAME->isKnown() || $targetCNAME->isTest()) {
|
||||
$validators[] = new DNS($targetCNAME->get(), DNS::RECORD_CNAME);
|
||||
}
|
||||
if ((new IP(IP::V4))->isValid(System::getEnv('_APP_DOMAIN_TARGET_A', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_A', ''), DNS::RECORD_A);
|
||||
}
|
||||
if ((new IP(IP::V6))->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''), DNS::RECORD_AAAA);
|
||||
}
|
||||
|
||||
if (empty($validators)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'At least one of domain targets environment variable must be configured.');
|
||||
}
|
||||
|
||||
$validator = new AnyOf($validators, AnyOf::TYPE_STRING);
|
||||
if ($validator->isValid($domain->get())) {
|
||||
$status = 'verifying';
|
||||
}
|
||||
|
||||
@@ -5,12 +5,11 @@ namespace Appwrite\Platform\Modules\Proxy\Http\Rules\Site;
|
||||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\CNAME;
|
||||
use Appwrite\Network\Validator\DNS;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Duplicate;
|
||||
@@ -20,7 +19,9 @@ use Utopia\Domains\Domain;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\AnyOf;
|
||||
use Utopia\Validator\Domain as ValidatorDomain;
|
||||
use Utopia\Validator\IP;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
class Create extends Action
|
||||
@@ -96,13 +97,6 @@ class Create extends Action
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Domain may not start with http:// or https://.');
|
||||
}
|
||||
|
||||
// Apex domain prevention due to CNAME limitations
|
||||
if (empty(App::getEnv('_APP_DOMAINS_NAMESERVERS', ''))) {
|
||||
if ($domain->get() === $domain->getRegisterable()) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'The instance does not allow root-level (apex) domains.');
|
||||
}
|
||||
}
|
||||
|
||||
$site = $dbForProject->getDocument('sites', $siteId);
|
||||
if ($site->isEmpty()) {
|
||||
throw new Exception(Exception::RULE_RESOURCE_NOT_FOUND);
|
||||
@@ -118,8 +112,23 @@ class Create extends Action
|
||||
$status = 'verified';
|
||||
}
|
||||
if ($status === 'created') {
|
||||
$target = new Domain(System::getEnv('_APP_DOMAIN_TARGET', ''));
|
||||
$validator = new CNAME($target->get());
|
||||
$validators = [];
|
||||
$targetCNAME = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME', ''));
|
||||
if (!$targetCNAME->isKnown() || $targetCNAME->isTest()) {
|
||||
$validators[] = new DNS($targetCNAME->get(), DNS::RECORD_CNAME);
|
||||
}
|
||||
if ((new IP(IP::V4))->isValid(System::getEnv('_APP_DOMAIN_TARGET_A', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_A', ''), DNS::RECORD_A);
|
||||
}
|
||||
if ((new IP(IP::V6))->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''), DNS::RECORD_AAAA);
|
||||
}
|
||||
|
||||
if (empty($validators)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'At least one of domain targets environment variable must be configured.');
|
||||
}
|
||||
|
||||
$validator = new AnyOf($validators, AnyOf::TYPE_STRING);
|
||||
if ($validator->isValid($domain->get())) {
|
||||
$status = 'verifying';
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ use Utopia\Registry\Registry;
|
||||
use Utopia\Storage\Device\Local;
|
||||
use Utopia\Storage\Storage;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\IP;
|
||||
|
||||
class Doctor extends Action
|
||||
{
|
||||
@@ -43,19 +44,31 @@ class Doctor extends Action
|
||||
Console::log('[Settings]');
|
||||
|
||||
$domain = new Domain(System::getEnv('_APP_DOMAIN'));
|
||||
|
||||
if (!$domain->isKnown() || $domain->isTest()) {
|
||||
Console::log('🔴 Hostname has no public suffix (' . $domain->get() . ')');
|
||||
Console::log('🔴 Hostname is not valid (' . $domain->get() . ')');
|
||||
} else {
|
||||
Console::log('🟢 Hostname has a public suffix (' . $domain->get() . ')');
|
||||
Console::log('🟢 Hostname is valid (' . $domain->get() . ')');
|
||||
}
|
||||
|
||||
$domain = new Domain(System::getEnv('_APP_DOMAIN_TARGET'));
|
||||
|
||||
$domain = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME'));
|
||||
if (!$domain->isKnown() || $domain->isTest()) {
|
||||
Console::log('🔴 CNAME target has no public suffix (' . $domain->get() . ')');
|
||||
Console::log('🔴 CNAME record target is not valid (' . $domain->get() . ')');
|
||||
} else {
|
||||
Console::log('🟢 CNAME target has a public suffix (' . $domain->get() . ')');
|
||||
Console::log('🟢 CNAME record target is valid (' . $domain->get() . ')');
|
||||
}
|
||||
|
||||
$ipv4 = new IP(IP::V4);
|
||||
if (!$ipv4->isValid(System::getEnv('_APP_DOMAIN_TARGET_A'))) {
|
||||
Console::log('🔴 A record target is not valid (' . System::getEnv('_APP_DOMAIN_TARGET_A') . ')');
|
||||
} else {
|
||||
Console::log('🟢 A record target is valid (' . System::getEnv('_APP_DOMAIN_TARGET_A') . ')');
|
||||
}
|
||||
|
||||
$ipv6 = new IP(IP::V6);
|
||||
if (!$ipv6->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA'))) {
|
||||
Console::log('🔴 AAAA record target is not valid (' . System::getEnv('_APP_DOMAIN_TARGET_AAAA') . ')');
|
||||
} else {
|
||||
Console::log('🟢 AAAA record target is valid (' . System::getEnv('_APP_DOMAIN_TARGET_AAAA') . ')');
|
||||
}
|
||||
|
||||
if (System::getEnv('_APP_OPENSSL_KEY_V1') === 'your-secret-key' || empty(System::getEnv('_APP_OPENSSL_KEY_V1'))) {
|
||||
|
||||
@@ -8,7 +8,7 @@ use Appwrite\Event\Func;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Realtime;
|
||||
use Appwrite\Event\Webhook;
|
||||
use Appwrite\Network\Validator\CNAME;
|
||||
use Appwrite\Network\Validator\DNS;
|
||||
use Appwrite\Template\Template;
|
||||
use Appwrite\Utopia\Response\Model\Rule;
|
||||
use Exception;
|
||||
@@ -28,6 +28,8 @@ use Utopia\Logger\Log;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Queue\Message;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\AnyOf;
|
||||
use Utopia\Validator\IP;
|
||||
|
||||
class Certificates extends Action
|
||||
{
|
||||
@@ -290,22 +292,39 @@ class Certificates extends Action
|
||||
}
|
||||
|
||||
if (!$isMainDomain) {
|
||||
// TODO: Would be awesome to also support A/AAAA records here. Maybe dry run?
|
||||
// Validate if domain target is properly configured
|
||||
$target = new Domain(System::getEnv('_APP_DOMAIN_TARGET', ''));
|
||||
$validationStart = \microtime(true);
|
||||
|
||||
if (!$target->isKnown() || $target->isTest()) {
|
||||
throw new Exception('Unreachable CNAME target (' . $target->get() . '), please use a domain with a public suffix.');
|
||||
$validators = [];
|
||||
$targetCNAME = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME', ''));
|
||||
if (!$targetCNAME->isKnown() || $targetCNAME->isTest()) {
|
||||
$validators[] = new DNS($targetCNAME->get(), DNS::RECORD_CNAME);
|
||||
}
|
||||
if ((new IP(IP::V4))->isValid(System::getEnv('_APP_DOMAIN_TARGET_A', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_A', ''), DNS::RECORD_A);
|
||||
}
|
||||
if ((new IP(IP::V6))->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''), DNS::RECORD_AAAA);
|
||||
}
|
||||
|
||||
// Validate if domain target is properly configured
|
||||
if (empty($validators)) {
|
||||
throw new Exception('At least one of domain targets environment variable must be configured.');
|
||||
}
|
||||
|
||||
// Verify domain with DNS records
|
||||
$validationStart = \microtime(true);
|
||||
$validator = new CNAME($target->get());
|
||||
$validator = new AnyOf($validators, AnyOf::TYPE_STRING);
|
||||
if (!$validator->isValid($domain->get())) {
|
||||
$log->addExtra('dnsTiming', \strval(\microtime(true) - $validationStart));
|
||||
$log->addTag('dnsDomain', $domain->get());
|
||||
|
||||
$error = $validator->getLogs();
|
||||
$errors = [];
|
||||
foreach ($validators as $validator) {
|
||||
if (!empty($validator->getLogs())) {
|
||||
$errors[] = $validator->getLogs();
|
||||
}
|
||||
}
|
||||
|
||||
$error = \implode("\n", $errors);
|
||||
$log->addExtra('dnsResponse', \is_array($error) ? \json_encode($error) : \strval($error));
|
||||
|
||||
throw new Exception('Failed to verify domain DNS records.');
|
||||
|
||||
@@ -10,12 +10,24 @@ class ConsoleVariables extends Model
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->addRule('_APP_DOMAIN_TARGET', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'CNAME target for your Appwrite custom domains.',
|
||||
'default' => '',
|
||||
'example' => 'appwrite.io',
|
||||
])
|
||||
->addRule('_APP_DOMAIN_TARGET_CNAME', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'CNAME target for your Appwrite custom domains.',
|
||||
'default' => '',
|
||||
'example' => 'appwrite.io',
|
||||
])
|
||||
->addRule('_APP_DOMAIN_TARGET_A', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'A target for your Appwrite custom domains.',
|
||||
'default' => '',
|
||||
'example' => '127.0.0.1',
|
||||
])
|
||||
->addRule('_APP_DOMAIN_TARGET_AAAA', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'AAAA target for your Appwrite custom domains.',
|
||||
'default' => '',
|
||||
'example' => '::1',
|
||||
])
|
||||
->addRule('_APP_STORAGE_LIMIT', [
|
||||
'type' => self::TYPE_INTEGER,
|
||||
'description' => 'Maximum file size allowed for file upload in bytes.',
|
||||
|
||||
@@ -24,11 +24,12 @@ class ConsoleConsoleClientTest extends Scope
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(11, $response['body']);
|
||||
$this->assertIsString($response['body']['_APP_DOMAIN_TARGET']);
|
||||
$this->assertCount(13, $response['body']);
|
||||
$this->assertIsString($response['body']['_APP_DOMAIN_TARGET_CNAME']);
|
||||
$this->assertIsString($response['body']['_APP_DOMAIN_TARGET_A']);
|
||||
$this->assertIsString($response['body']['_APP_DOMAIN_TARGET_AAAA']);
|
||||
$this->assertIsInt($response['body']['_APP_STORAGE_LIMIT']);
|
||||
$this->assertIsInt($response['body']['_APP_COMPUTE_SIZE_LIMIT']);
|
||||
$this->assertIsString($response['body']['_APP_DOMAIN_TARGET']);
|
||||
$this->assertIsBool($response['body']['_APP_DOMAIN_ENABLED']);
|
||||
$this->assertIsBool($response['body']['_APP_VCS_ENABLED']);
|
||||
$this->assertIsBool($response['body']['_APP_ASSISTANT_ENABLED']);
|
||||
|
||||
@@ -53,8 +53,10 @@ class ProxyCustomServerTest extends Scope
|
||||
|
||||
public function testCreateRuleApex(): void
|
||||
{
|
||||
$rule = $this->createAPIRule('myapp.com');
|
||||
$this->assertEquals(400, $rule['headers']['status-code']);
|
||||
$domain = \uniqid() . '.com';
|
||||
$rule = $this->createAPIRule($domain);
|
||||
$this->assertEquals(201, $rule['headers']['status-code']);
|
||||
$this->assertEquals('created', $rule['body']['status']);
|
||||
}
|
||||
|
||||
public function testCreateRuleVcs(): void
|
||||
@@ -337,7 +339,7 @@ class ProxyCustomServerTest extends Scope
|
||||
$this->cleanupRule($rule['body']['$id']);
|
||||
|
||||
// Create + update
|
||||
$domain = \uniqid() . '-cname-api.custom.localhost';
|
||||
$domain = \uniqid() . '-cname-api.custom.com';
|
||||
|
||||
$rule = $this->createAPIRule($domain);
|
||||
$this->assertEquals(201, $rule['headers']['status-code']);
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Network\Validators;
|
||||
|
||||
use Appwrite\Network\Validator\CNAME;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class CNAMETest extends TestCase
|
||||
{
|
||||
protected ?CNAME $object = null;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->object = new CNAME('appwrite.io');
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
}
|
||||
|
||||
public function testValues(): void
|
||||
{
|
||||
$this->assertEquals($this->object->isValid(''), false);
|
||||
$this->assertEquals($this->object->isValid(null), false);
|
||||
$this->assertEquals($this->object->isValid(false), false);
|
||||
$this->assertEquals($this->object->isValid('cname-unit-test.appwrite.org'), true);
|
||||
$this->assertEquals($this->object->isValid('test1.appwrite.org'), false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Network\Validators;
|
||||
|
||||
use Appwrite\Network\Validator\DNS;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DNSTest extends TestCase
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
}
|
||||
|
||||
public function testCNAME(): void
|
||||
{
|
||||
$validator = new DNS('appwrite.io', DNS::RECORD_CNAME);
|
||||
$this->assertEquals($validator->isValid(''), false);
|
||||
$this->assertEquals($validator->isValid(null), false);
|
||||
$this->assertEquals($validator->isValid(false), false);
|
||||
$this->assertEquals($validator->isValid('cname-unit-test.appwrite.org'), true);
|
||||
$this->assertEquals($validator->isValid('test1.appwrite.org'), false);
|
||||
}
|
||||
|
||||
public function testA(): void
|
||||
{
|
||||
// IPv4 for documentation purposes
|
||||
$validator = new DNS('203.0.113.1', DNS::RECORD_A);
|
||||
$this->assertEquals($validator->isValid(''), false);
|
||||
$this->assertEquals($validator->isValid(null), false);
|
||||
$this->assertEquals($validator->isValid(false), false);
|
||||
$this->assertEquals($validator->isValid('a-unit-test.appwrite.org'), true);
|
||||
$this->assertEquals($validator->isValid('test1.appwrite.org'), false);
|
||||
}
|
||||
|
||||
public function testAAAA(): void
|
||||
{
|
||||
// IPv6 for documentation purposes
|
||||
$validator = new DNS('2001:db8::1', DNS::RECORD_AAAA);
|
||||
$this->assertEquals($validator->isValid(''), false);
|
||||
$this->assertEquals($validator->isValid(null), false);
|
||||
$this->assertEquals($validator->isValid(false), false);
|
||||
$this->assertEquals($validator->isValid('aaaa-unit-test.appwrite.org'), true);
|
||||
$this->assertEquals($validator->isValid('test1.appwrite.org'), false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user