Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Wildcard hostname #3124

Merged
merged 5 commits into from May 12, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 13 additions & 1 deletion app/controllers/api/projects.php
Expand Up @@ -21,7 +21,7 @@
use Appwrite\Extend\Exception;
use Utopia\Validator\ArrayList;
use Utopia\Validator\Boolean;
use Utopia\Validator\Integer;
use Utopia\Validator\Hostname;
use Utopia\Validator\Range;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
Expand Down Expand Up @@ -1016,6 +1016,12 @@
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForConsole */

// Ensure hostname has proper structure (no port, protocol..)
TorstenDittmann marked this conversation as resolved.
Show resolved Hide resolved
$validator = new Hostname();
if (!is_null($hostname) && !$validator->isValid($hostname)) {
throw new Exception($validator->getDescription(), 400, Exception::ATTRIBUTE_VALUE_INVALID);
}

$project = $dbForConsole->getDocument('projects', $projectId);

if ($project->isEmpty()) {
Expand Down Expand Up @@ -1135,6 +1141,12 @@
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForConsole */

// Ensure hostname has proper structure (no port, protocol..)
$validator = new Hostname();
if (!is_null($hostname) && !$validator->isValid($hostname)) {
throw new Exception($validator->getDescription(), 400, Exception::ATTRIBUTE_VALUE_INVALID);
}

$project = $dbForConsole->getDocument('projects', $projectId);

if ($project->isEmpty()) {
Expand Down
10 changes: 8 additions & 2 deletions app/controllers/general.php
Expand Up @@ -19,6 +19,7 @@
use Utopia\Database\Document;
use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization;
use Utopia\Validator\Hostname;
use Appwrite\Utopia\Request\Filters\V12 as RequestV12;
use Appwrite\Utopia\Request\Filters\V13 as RequestV13;
use Utopia\Validator\Text;
Expand Down Expand Up @@ -123,8 +124,13 @@
$protocol = \parse_url($request->getOrigin($referrer), PHP_URL_SCHEME);
$port = \parse_url($request->getOrigin($referrer), PHP_URL_PORT);

$refDomain = (!empty($protocol) ? $protocol : $request->getProtocol()).'://'.((\in_array($origin, $clients))
? $origin : 'localhost').(!empty($port) ? ':'.$port : '');
$refDomainOrigin = 'localhost';
$validator = new Hostname($clients);
if ($validator->isValid($origin)) {
$refDomainOrigin = $origin;
}

$refDomain = (!empty($protocol) ? $protocol : $request->getProtocol()) . '://' . $refDomainOrigin . (!empty($port) ? ':' . $port : '');

$refDomain = (!$route->getLabel('origin', false)) // This route is publicly accessible
? $refDomain
Expand Down
29 changes: 19 additions & 10 deletions app/views/console/home/index.phtml
Expand Up @@ -299,8 +299,9 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<label for="name">Name <span class="tooltip large" data-tooltip="Choose any name that will help you distinguish between your different apps."><i class="icon-question"></i></span></label>
<input type="text" class="full-width" name="name" required autocomplete="off" placeholder="My Web App" maxlength="128" />

<label for="hostname">Hostname <span class="tooltip large" data-tooltip="The hostname that your website will use to interact with the <?php echo APP_NAME; ?> APIs in production or development environments. No port number required."><i class="icon-question"></i></span></label>
<input name="hostname" type="text" class="margin-bottom" autocomplete="off" placeholder="localhost" required>
<label for="hostname">Hostname <span class="tooltip large" data-tooltip="The hostname that your website will use to interact with the <?php echo APP_NAME; ?> APIs in production or development environments. No protocol or port number required."><i class="icon-question"></i></span></label>
<input name="hostname" type="text" class="margin-bottom" autocomplete="off" placeholder="yourapp.com" required>
<div class="text-fade text-size-xs margin-top-negative-small margin-bottom">You can use * to allow wildcard hostnames or subdomains.</div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future, it might be cool to add small buttons to allow to quickly add *.vercel.app or *.netlify.app

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aaand *.*.gitpod.io probably


<div class="info margin-top margin-bottom">
<div class="text-bold margin-bottom-small">Next Steps</div>
Expand Down Expand Up @@ -329,7 +330,8 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
data-success="alert,trigger"
data-success-param-alert-text="Updated platform successfully"
data-success-param-trigger-events="projects.updatePlatform"
data-failure="alert"
data-failure="alert,trigger"
data-failure-param-trigger-events="projects.updatePlatform"
data-failure-param-alert-text="Failed to update platform"
data-failure-param-alert-classname="error">

Expand All @@ -340,7 +342,8 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<input type="text" class="full-width" data-ls-attrs="id=name-{{platform.$id}}" name="name" required autocomplete="off" data-ls-bind="{{platform.name}}" placeholder="My Web App" maxlength="128" />

<label for="hostname">Hostname <span class="tooltip large" data-tooltip="The hostname that your website will use to interact with the <?php echo APP_NAME; ?> APIs in production or development environments. No port number required."><i class="icon-question"></i></span></label>
<input name="hostname" type="text" class="margin-bottom" autocomplete="off" placeholder="localhost" data-ls-bind="{{platform.hostname}}" required />
<input name="hostname" type="text" class="margin-bottom" autocomplete="off" placeholder="yourapp.com" data-ls-bind="{{platform.hostname}}" required />
<div class="text-fade text-size-xs margin-top-negative-small margin-bottom">You can use * to allow wildcard hostnames or subdomains.</div>

<hr />

Expand Down Expand Up @@ -714,7 +717,8 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
data-success="alert,trigger"
data-success-param-alert-text="Updated platform successfully"
data-success-param-trigger-events="projects.updatePlatform"
data-failure="alert"
data-failure="alert,trigger"
data-failure-param-trigger-events="projects.updatePlatform"
data-failure-param-alert-text="Failed to update platform"
data-failure-param-alert-classname="error">

Expand Down Expand Up @@ -746,7 +750,8 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
data-success="alert,trigger"
data-success-param-alert-text="Updated platform successfully"
data-success-param-trigger-events="projects.updatePlatform"
data-failure="alert"
data-failure="alert,trigger"
data-failure-param-trigger-events="projects.updatePlatform"
data-failure-param-alert-text="Failed to update platform"
data-failure-param-alert-classname="error">

Expand Down Expand Up @@ -777,7 +782,8 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
data-success="alert,trigger"
data-success-param-alert-text="Updated platform successfully"
data-success-param-trigger-events="projects.updatePlatform"
data-failure="alert"
data-failure="alert,trigger"
data-failure-param-trigger-events="projects.updatePlatform"
data-failure-param-alert-text="Failed to update platform"
data-failure-param-alert-classname="error">

Expand Down Expand Up @@ -808,7 +814,8 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
data-success="alert,trigger"
data-success-param-alert-text="Updated platform successfully"
data-success-param-trigger-events="projects.updatePlatform"
data-failure="alert"
data-failure="alert,trigger"
data-failure-param-trigger-events="projects.updatePlatform"
data-failure-param-alert-text="Failed to update platform"
data-failure-param-alert-classname="error">

Expand Down Expand Up @@ -841,7 +848,8 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
data-success="alert,trigger"
data-success-param-alert-text="Updated platform successfully"
data-success-param-trigger-events="projects.updatePlatform"
data-failure="alert"
data-failure="alert,trigger"
data-failure-param-trigger-events="projects.updatePlatform"
data-failure-param-alert-text="Failed to update platform"
data-failure-param-alert-classname="error">

Expand Down Expand Up @@ -873,7 +881,8 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
data-success="alert,trigger"
data-success-param-alert-text="Updated platform successfully"
data-success-param-trigger-events="projects.updatePlatform"
data-failure="alert"
data-failure="alert,trigger"
data-failure-param-trigger-events="projects.updatePlatform"
data-failure-param-alert-text="Failed to update platform"
data-failure-param-alert-classname="error">

Expand Down
34 changes: 13 additions & 21 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions src/Appwrite/Network/Validator/Host.php
@@ -1,6 +1,7 @@
<?php

namespace Appwrite\Network\Validator;
use Utopia\Validator\Hostname;
Meldiron marked this conversation as resolved.
Show resolved Hide resolved

use Utopia\Validator;

Expand Down Expand Up @@ -45,17 +46,16 @@ public function getDescription(): string
*/
public function isValid($value): bool
{
// Check if value is valid URL
$urlValidator = new URL();

if (!$urlValidator->isValid($value)) {
return false;
}

if (\in_array(\parse_url($value, PHP_URL_HOST), $this->whitelist)) {
return true;
}

return false;
$hostname = \parse_url($value, PHP_URL_HOST);
$hostnameValudator = new Hostname($this->whitelist);
Meldiron marked this conversation as resolved.
Show resolved Hide resolved
return $hostnameValudator->isValid($hostname);
Meldiron marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
8 changes: 3 additions & 5 deletions src/Appwrite/Network/Validator/Origin.php
@@ -1,6 +1,7 @@
<?php

namespace Appwrite\Network\Validator;
use Utopia\Validator\Hostname;
Meldiron marked this conversation as resolved.
Show resolved Hide resolved

use Utopia\Validator;

Expand Down Expand Up @@ -122,11 +123,8 @@ public function isValid($origin): bool
return true;
}

if (\in_array($host, $this->clients)) {
return true;
}

return false;
$validator = new Hostname($this->clients);
return $validator->isValid($host);
Meldiron marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down