More backwards compatibility fixes

This commit is contained in:
Matej Bačo
2026-03-24 13:33:15 +01:00
parent c903fb87ac
commit 038f4b5992
7 changed files with 100 additions and 9 deletions
@@ -6,10 +6,12 @@ use Appwrite\Event\Event as QueueEvent;
use Appwrite\Extend\Exception;
use Appwrite\Network\Platform;
use Appwrite\Platform\Modules\Compute\Base;
use Appwrite\Platform\Modules\Project\Http\Project\Platforms\Web\Create as CreateWebPlatform;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Database\Validator\CustomId;
use Appwrite\Utopia\Request;
use Appwrite\Utopia\Response;
use Utopia\Database\Database;
use Utopia\Database\Document;
@@ -18,6 +20,7 @@ use Utopia\Database\Helpers\ID;
use Utopia\Database\Validator\Authorization;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
use Utopia\Validator\Hostname;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
@@ -52,11 +55,23 @@ class Create extends Base
];
}
/**
* @return array<string>
*/
public static function getAllSupportedTypes(): array
{
return [
...self::getSupportedTypes(),
...CreateWebPlatform::getSupportedTypes(),
];
}
public function __construct()
{
$this
->setHttpMethod(Action::HTTP_REQUEST_METHOD_POST)
->setHttpPath('/v1/project/platforms/app')
->httpAlias('/v1/projects/:projectId/platforms')
->desc('Create project app platform')
->groups(['api', 'project'])
->label('scope', 'project.write')
@@ -83,10 +98,11 @@ class Create extends Base
->param(
'type',
null,
new WhiteList($this->getSupportedTypes(), true),
new WhiteList($this->getAllSupportedTypes(), true), // We only support all here for backwards compatibility
'Platform type. Possible values are: ' . implode(', ', $this->getSupportedTypes())
)
->param('identifier', '', new Text(256), 'Package name for Android or bundle ID for iOS or macOS. Max length: 256 chars.')
->param('identifier', '', new Text(256), 'Package name for Android or bundle ID for iOS or macOS. Max length: 256 chars.', true) // We only mark optional=true for backwards compatibility
->inject('request')
->inject('response')
->inject('queueForEvents')
->inject('project')
@@ -99,13 +115,31 @@ class Create extends Base
string $platformId,
string $name,
string $type,
string $identifier,
?string $identifier, // Only nullable for backwards compatibility
Request $request,
Response $response,
QueueEvent $queueForEvents,
Document $project,
Database $dbForPlatform,
Authorization $authorization,
) {
$hostname = null;
// Backwards compatibility
$isDeprecatedRequest = false;
if (!\in_array($type, self::getSupportedTypes())) {
$isDeprecatedRequest = true;
$hostname = $request->getParam('hostname', '');
$hostnameValidator = new Hostname();
if (!$hostnameValidator->isValid($hostname)) {
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Param "hostname" is invalid: ' . $hostnameValidator->getDescription());
}
} else {
if (empty($identifier)) {
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Param "identifier" is not optional.');
}
}
$platformId = ($platformId == 'unique()') ? ID::unique() : $platformId;
$platform = new Document([
@@ -116,8 +150,8 @@ class Create extends Base
'type' => $type,
'name' => $name,
'key' => $identifier,
'store' => null, // Unused at the moment
'hostname' => null // Web platform attribute
'hostname' => $hostname, // Web platform attribute; We fill only during backwards compatibility, otherwise null
'store' => null, // Unused attribute
]);
try {
@@ -130,6 +164,10 @@ class Create extends Base
$queueForEvents->setParam('platformId', $platform->getId());
if (!$isDeprecatedRequest) {
$platform->setAttribute('hostname', '');
}
$response
->setStatusCode(Response::STATUS_CODE_CREATED)
->dynamic($platform, Response::MODEL_PLATFORM_APP);
@@ -6,9 +6,11 @@ use Appwrite\Event\Event as QueueEvent;
use Appwrite\Extend\Exception;
use Appwrite\Platform\Modules\Compute\Base;
use Appwrite\Platform\Modules\Project\Http\Project\Platforms\App\Create as AppPlatformCreate;
use Appwrite\Platform\Modules\Project\Http\Project\Platforms\Web\Create as WebPlatformCreate;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Request;
use Appwrite\Utopia\Response;
use Utopia\Database\Database;
use Utopia\Database\Document;
@@ -17,6 +19,7 @@ use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\UID;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
use Utopia\Validator\Hostname;
use Utopia\Validator\Text;
class Update extends Base
@@ -32,6 +35,7 @@ class Update extends Base
{
$this->setHttpMethod(Action::HTTP_REQUEST_METHOD_PUT)
->setHttpPath('/v1/project/platforms/app/:platformId')
->httpAlias('/v1/projects/:projectId/platforms/:platformId')
->desc('Update project app platform')
->groups(['api', 'project'])
->label('scope', 'project.write')
@@ -55,7 +59,8 @@ class Update extends Base
))
->param('platformId', '', fn (Database $dbForPlatform) => new UID($dbForPlatform->getAdapter()->getMaxUIDLength()), 'Platform ID.', false, ['dbForPlatform'])
->param('name', null, new Text(128), 'Platform name. Max length: 128 chars.')
->param('identifier', '', new Text(256), 'Package name for Android or bundle ID for iOS or macOS. Max length: 256 chars.')
->param('identifier', '', new Text(256), 'Package name for Android or bundle ID for iOS or macOS. Max length: 256 chars.', true) // Only optional=true for backwards compatibility
->inject('request')
->inject('response')
->inject('queueForEvents')
->inject('dbForPlatform')
@@ -67,13 +72,29 @@ class Update extends Base
public function action(
string $platformId,
string $name,
string $identifier,
?string $identifier, // Only nullable for backwards compatibility
Request $request,
Response $response,
QueueEvent $queueForEvents,
Database $dbForPlatform,
Authorization $authorization,
Document $project,
) {
// Backwards compatibility
$isDeprecatedRequest = false;
$hostname = $request->getParam('hostname', '');
if (!empty($hostname)) {
$isDeprecatedRequest = true;
$hostnameValidator = new Hostname();
if (!$hostnameValidator->isValid($hostname)) {
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Param "hostname" is invalid: ' . $hostnameValidator->getDescription());
}
} else {
if (empty($identifier)) {
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Param "identifier" is not optional.');
}
}
$platform = $authorization->skip(fn () => $dbForPlatform->getDocument('platforms', $platformId));
if ($platform->isEmpty() || $platform->getAttribute('projectInternalId', '') !== $project->getSequence()) {
@@ -82,12 +103,22 @@ class Update extends Base
$appPlatforms = AppPlatformCreate::getSupportedTypes();
if (!\in_array($platform->getAttribute('type', ''), $appPlatforms)) {
throw new Exception(Exception::PLATFORM_METHOD_UNSUPPORTED);
if ($isDeprecatedRequest) {
// Bacwkards compatible check
$webPlatforms = WebPlatformCreate::getSupportedTypes();
if (!\in_array($platform->getAttribute('type', ''), $webPlatforms)) {
throw new Exception(Exception::PLATFORM_METHOD_UNSUPPORTED);
}
} else {
throw new Exception(Exception::PLATFORM_METHOD_UNSUPPORTED);
}
}
$updates = new Document([
'name' => $name,
'key' => $identifier,
'hostname' => $hostname ?? $platform['hostname'] ?? '', // Backwards compatibility
]);
try {
@@ -100,6 +131,10 @@ class Update extends Base
$queueForEvents->setParam('platformId', $platform->getId());
if (!$isDeprecatedRequest) {
$platform->setAttribute('hostname', '');
}
$response->dynamic($platform, Response::MODEL_PLATFORM_APP);
}
}
@@ -107,7 +107,7 @@ class Create extends Base
'type' => $type,
'name' => $name,
'key' => null, // App platform attribute
'store' => null, // App platform attribute
'store' => null, // Unused attribute
'hostname' => $hostname
]);
@@ -753,6 +753,9 @@ abstract class Format
protected function getNestedModels(Model $model, array &$usedModels): void
{
foreach ($model->getRules() as $rule) {
if (($rule['hidden'] ?? false) === true) {
continue;
}
if (!in_array($model->getType(), $usedModels)) {
continue;
}
@@ -829,6 +829,10 @@ class OpenAPI3 extends Format
}
foreach ($model->getRules() as $name => $rule) {
if (($rule['hidden'] ?? false) === true) {
continue;
}
$type = '';
$format = null;
$items = null;
@@ -810,6 +810,10 @@ class Swagger2 extends Format
}
foreach ($model->getRules() as $name => $rule) {
if (($rule['hidden'] ?? false) === true) {
continue;
}
$type = '';
$format = null;
$items = null;
@@ -52,6 +52,13 @@ class PlatformApp extends PlatformBase
'default' => '',
'example' => 'com.company.appname',
])
->addRule('hostname', [ // Backwards compatibility
'type' => self::TYPE_STRING,
'description' => 'Web app hostname. Empty string for other platforms.',
'default' => '',
'example' => 'app.example.com',
'hidden' => true,
])
;
}