diff --git a/app/config/specs/open-api3-1.7.x-client.json b/app/config/specs/open-api3-1.7.x-client.json index 6813c71f74..dc16932fd4 100644 --- a/app/config/specs/open-api3-1.7.x-client.json +++ b/app/config/specs/open-api3-1.7.x-client.json @@ -8479,17 +8479,20 @@ "type": "integer", "description": "Document automatically incrementing ID.", "x-example": 1, - "format": "int32" + "format": "int32", + "readOnly": true }, "$collectionId": { "type": "string", "description": "Collection ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$databaseId": { "type": "string", "description": "Database ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$createdAt": { "type": "string", diff --git a/app/config/specs/open-api3-1.7.x-console.json b/app/config/specs/open-api3-1.7.x-console.json index 358b282600..0063b8b557 100644 --- a/app/config/specs/open-api3-1.7.x-console.json +++ b/app/config/specs/open-api3-1.7.x-console.json @@ -37978,17 +37978,20 @@ "type": "integer", "description": "Document automatically incrementing ID.", "x-example": 1, - "format": "int32" + "format": "int32", + "readOnly": true }, "$collectionId": { "type": "string", "description": "Collection ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$databaseId": { "type": "string", "description": "Database ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$createdAt": { "type": "string", @@ -44635,6 +44638,11 @@ "description": "AAAA target for your Appwrite custom domains.", "x-example": "::1" }, + "_APP_DOMAIN_TARGET_CAA": { + "type": "string", + "description": "CAA target for your Appwrite custom domains.", + "x-example": "digicert.com" + }, "_APP_STORAGE_LIMIT": { "type": "integer", "description": "Maximum file size allowed for file upload in bytes.", @@ -44692,6 +44700,7 @@ "_APP_DOMAIN_TARGET_CNAME", "_APP_DOMAIN_TARGET_A", "_APP_DOMAIN_TARGET_AAAA", + "_APP_DOMAIN_TARGET_CAA", "_APP_STORAGE_LIMIT", "_APP_COMPUTE_SIZE_LIMIT", "_APP_USAGE_STATS", @@ -44707,6 +44716,7 @@ "_APP_DOMAIN_TARGET_CNAME": "appwrite.io", "_APP_DOMAIN_TARGET_A": "127.0.0.1", "_APP_DOMAIN_TARGET_AAAA": "::1", + "_APP_DOMAIN_TARGET_CAA": "digicert.com", "_APP_STORAGE_LIMIT": "30000000", "_APP_COMPUTE_SIZE_LIMIT": "30000000", "_APP_USAGE_STATS": "enabled", diff --git a/app/config/specs/open-api3-1.7.x-server.json b/app/config/specs/open-api3-1.7.x-server.json index 35a1066924..b3917036f0 100644 --- a/app/config/specs/open-api3-1.7.x-server.json +++ b/app/config/specs/open-api3-1.7.x-server.json @@ -27864,17 +27864,20 @@ "type": "integer", "description": "Document automatically incrementing ID.", "x-example": 1, - "format": "int32" + "format": "int32", + "readOnly": true }, "$collectionId": { "type": "string", "description": "Collection ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$databaseId": { "type": "string", "description": "Database ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$createdAt": { "type": "string", diff --git a/app/config/specs/open-api3-latest-client.json b/app/config/specs/open-api3-latest-client.json index 6813c71f74..dc16932fd4 100644 --- a/app/config/specs/open-api3-latest-client.json +++ b/app/config/specs/open-api3-latest-client.json @@ -8479,17 +8479,20 @@ "type": "integer", "description": "Document automatically incrementing ID.", "x-example": 1, - "format": "int32" + "format": "int32", + "readOnly": true }, "$collectionId": { "type": "string", "description": "Collection ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$databaseId": { "type": "string", "description": "Database ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$createdAt": { "type": "string", diff --git a/app/config/specs/open-api3-latest-console.json b/app/config/specs/open-api3-latest-console.json index 358b282600..0063b8b557 100644 --- a/app/config/specs/open-api3-latest-console.json +++ b/app/config/specs/open-api3-latest-console.json @@ -37978,17 +37978,20 @@ "type": "integer", "description": "Document automatically incrementing ID.", "x-example": 1, - "format": "int32" + "format": "int32", + "readOnly": true }, "$collectionId": { "type": "string", "description": "Collection ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$databaseId": { "type": "string", "description": "Database ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$createdAt": { "type": "string", @@ -44635,6 +44638,11 @@ "description": "AAAA target for your Appwrite custom domains.", "x-example": "::1" }, + "_APP_DOMAIN_TARGET_CAA": { + "type": "string", + "description": "CAA target for your Appwrite custom domains.", + "x-example": "digicert.com" + }, "_APP_STORAGE_LIMIT": { "type": "integer", "description": "Maximum file size allowed for file upload in bytes.", @@ -44692,6 +44700,7 @@ "_APP_DOMAIN_TARGET_CNAME", "_APP_DOMAIN_TARGET_A", "_APP_DOMAIN_TARGET_AAAA", + "_APP_DOMAIN_TARGET_CAA", "_APP_STORAGE_LIMIT", "_APP_COMPUTE_SIZE_LIMIT", "_APP_USAGE_STATS", @@ -44707,6 +44716,7 @@ "_APP_DOMAIN_TARGET_CNAME": "appwrite.io", "_APP_DOMAIN_TARGET_A": "127.0.0.1", "_APP_DOMAIN_TARGET_AAAA": "::1", + "_APP_DOMAIN_TARGET_CAA": "digicert.com", "_APP_STORAGE_LIMIT": "30000000", "_APP_COMPUTE_SIZE_LIMIT": "30000000", "_APP_USAGE_STATS": "enabled", diff --git a/app/config/specs/open-api3-latest-server.json b/app/config/specs/open-api3-latest-server.json index 35a1066924..b3917036f0 100644 --- a/app/config/specs/open-api3-latest-server.json +++ b/app/config/specs/open-api3-latest-server.json @@ -27864,17 +27864,20 @@ "type": "integer", "description": "Document automatically incrementing ID.", "x-example": 1, - "format": "int32" + "format": "int32", + "readOnly": true }, "$collectionId": { "type": "string", "description": "Collection ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$databaseId": { "type": "string", "description": "Database ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$createdAt": { "type": "string", diff --git a/app/config/specs/swagger2-1.7.x-client.json b/app/config/specs/swagger2-1.7.x-client.json index 07a12f0dbb..9941e3db2c 100644 --- a/app/config/specs/swagger2-1.7.x-client.json +++ b/app/config/specs/swagger2-1.7.x-client.json @@ -8516,17 +8516,20 @@ "type": "integer", "description": "Document automatically incrementing ID.", "x-example": 1, - "format": "int32" + "format": "int32", + "readOnly": true }, "$collectionId": { "type": "string", "description": "Collection ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$databaseId": { "type": "string", "description": "Database ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$createdAt": { "type": "string", diff --git a/app/config/specs/swagger2-1.7.x-console.json b/app/config/specs/swagger2-1.7.x-console.json index 32afa9e180..4b458c3a95 100644 --- a/app/config/specs/swagger2-1.7.x-console.json +++ b/app/config/specs/swagger2-1.7.x-console.json @@ -38139,17 +38139,20 @@ "type": "integer", "description": "Document automatically incrementing ID.", "x-example": 1, - "format": "int32" + "format": "int32", + "readOnly": true }, "$collectionId": { "type": "string", "description": "Collection ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$databaseId": { "type": "string", "description": "Database ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$createdAt": { "type": "string", @@ -44900,6 +44903,11 @@ "description": "AAAA target for your Appwrite custom domains.", "x-example": "::1" }, + "_APP_DOMAIN_TARGET_CAA": { + "type": "string", + "description": "CAA target for your Appwrite custom domains.", + "x-example": "digicert.com" + }, "_APP_STORAGE_LIMIT": { "type": "integer", "description": "Maximum file size allowed for file upload in bytes.", @@ -44957,6 +44965,7 @@ "_APP_DOMAIN_TARGET_CNAME", "_APP_DOMAIN_TARGET_A", "_APP_DOMAIN_TARGET_AAAA", + "_APP_DOMAIN_TARGET_CAA", "_APP_STORAGE_LIMIT", "_APP_COMPUTE_SIZE_LIMIT", "_APP_USAGE_STATS", @@ -44972,6 +44981,7 @@ "_APP_DOMAIN_TARGET_CNAME": "appwrite.io", "_APP_DOMAIN_TARGET_A": "127.0.0.1", "_APP_DOMAIN_TARGET_AAAA": "::1", + "_APP_DOMAIN_TARGET_CAA": "digicert.com", "_APP_STORAGE_LIMIT": "30000000", "_APP_COMPUTE_SIZE_LIMIT": "30000000", "_APP_USAGE_STATS": "enabled", diff --git a/app/config/specs/swagger2-1.7.x-server.json b/app/config/specs/swagger2-1.7.x-server.json index 391adc2dfc..20cf716590 100644 --- a/app/config/specs/swagger2-1.7.x-server.json +++ b/app/config/specs/swagger2-1.7.x-server.json @@ -28092,17 +28092,20 @@ "type": "integer", "description": "Document automatically incrementing ID.", "x-example": 1, - "format": "int32" + "format": "int32", + "readOnly": true }, "$collectionId": { "type": "string", "description": "Collection ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$databaseId": { "type": "string", "description": "Database ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$createdAt": { "type": "string", diff --git a/app/config/specs/swagger2-latest-client.json b/app/config/specs/swagger2-latest-client.json index 07a12f0dbb..9941e3db2c 100644 --- a/app/config/specs/swagger2-latest-client.json +++ b/app/config/specs/swagger2-latest-client.json @@ -8516,17 +8516,20 @@ "type": "integer", "description": "Document automatically incrementing ID.", "x-example": 1, - "format": "int32" + "format": "int32", + "readOnly": true }, "$collectionId": { "type": "string", "description": "Collection ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$databaseId": { "type": "string", "description": "Database ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$createdAt": { "type": "string", diff --git a/app/config/specs/swagger2-latest-console.json b/app/config/specs/swagger2-latest-console.json index 32afa9e180..4b458c3a95 100644 --- a/app/config/specs/swagger2-latest-console.json +++ b/app/config/specs/swagger2-latest-console.json @@ -38139,17 +38139,20 @@ "type": "integer", "description": "Document automatically incrementing ID.", "x-example": 1, - "format": "int32" + "format": "int32", + "readOnly": true }, "$collectionId": { "type": "string", "description": "Collection ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$databaseId": { "type": "string", "description": "Database ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$createdAt": { "type": "string", @@ -44900,6 +44903,11 @@ "description": "AAAA target for your Appwrite custom domains.", "x-example": "::1" }, + "_APP_DOMAIN_TARGET_CAA": { + "type": "string", + "description": "CAA target for your Appwrite custom domains.", + "x-example": "digicert.com" + }, "_APP_STORAGE_LIMIT": { "type": "integer", "description": "Maximum file size allowed for file upload in bytes.", @@ -44957,6 +44965,7 @@ "_APP_DOMAIN_TARGET_CNAME", "_APP_DOMAIN_TARGET_A", "_APP_DOMAIN_TARGET_AAAA", + "_APP_DOMAIN_TARGET_CAA", "_APP_STORAGE_LIMIT", "_APP_COMPUTE_SIZE_LIMIT", "_APP_USAGE_STATS", @@ -44972,6 +44981,7 @@ "_APP_DOMAIN_TARGET_CNAME": "appwrite.io", "_APP_DOMAIN_TARGET_A": "127.0.0.1", "_APP_DOMAIN_TARGET_AAAA": "::1", + "_APP_DOMAIN_TARGET_CAA": "digicert.com", "_APP_STORAGE_LIMIT": "30000000", "_APP_COMPUTE_SIZE_LIMIT": "30000000", "_APP_USAGE_STATS": "enabled", diff --git a/app/config/specs/swagger2-latest-server.json b/app/config/specs/swagger2-latest-server.json index 391adc2dfc..20cf716590 100644 --- a/app/config/specs/swagger2-latest-server.json +++ b/app/config/specs/swagger2-latest-server.json @@ -28092,17 +28092,20 @@ "type": "integer", "description": "Document automatically incrementing ID.", "x-example": 1, - "format": "int32" + "format": "int32", + "readOnly": true }, "$collectionId": { "type": "string", "description": "Collection ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$databaseId": { "type": "string", "description": "Database ID.", - "x-example": "5e5ea5c15117e" + "x-example": "5e5ea5c15117e", + "readOnly": true }, "$createdAt": { "type": "string", diff --git a/src/Appwrite/SDK/Specification/Format/OpenAPI3.php b/src/Appwrite/SDK/Specification/Format/OpenAPI3.php index c4a39b707b..55c71569cb 100644 --- a/src/Appwrite/SDK/Specification/Format/OpenAPI3.php +++ b/src/Appwrite/SDK/Specification/Format/OpenAPI3.php @@ -686,6 +686,7 @@ class OpenAPI3 extends Format break; } + $readOnly = $rule['readOnly'] ?? false; if ($rule['array']) { $output['components']['schemas'][$model->getType()]['properties'][$name] = [ 'type' => 'array', @@ -699,6 +700,9 @@ class OpenAPI3 extends Format if ($format) { $output['components']['schemas'][$model->getType()]['properties'][$name]['items']['format'] = $format; } + if ($readOnly) { + $output['components']['schemas'][$model->getType()]['properties'][$name]['readOnly'] = true; + } } else { $output['components']['schemas'][$model->getType()]['properties'][$name] = [ 'type' => $type, @@ -709,6 +713,9 @@ class OpenAPI3 extends Format if ($format) { $output['components']['schemas'][$model->getType()]['properties'][$name]['format'] = $format; } + if ($readOnly) { + $output['components']['schemas'][$model->getType()]['properties'][$name]['readOnly'] = true; + } } if ($items) { $output['components']['schemas'][$model->getType()]['properties'][$name]['items'] = $items; diff --git a/src/Appwrite/SDK/Specification/Format/Swagger2.php b/src/Appwrite/SDK/Specification/Format/Swagger2.php index 45fdc63bc8..654284fa0a 100644 --- a/src/Appwrite/SDK/Specification/Format/Swagger2.php +++ b/src/Appwrite/SDK/Specification/Format/Swagger2.php @@ -692,6 +692,7 @@ class Swagger2 extends Format break; } + $readOnly = $rule['readOnly'] ?? false; if ($rule['type'] == 'json') { $output['definitions'][$model->getType()]['properties'][$name] = [ 'type' => $type, @@ -699,6 +700,10 @@ class Swagger2 extends Format 'description' => $rule['description'] ?? '', 'x-example' => $rule['example'] ?? null, ]; + + if ($readOnly) { + $output['definitions'][$model->getType()]['properties'][$name]['readOnly'] = true; + } continue; } @@ -715,6 +720,9 @@ class Swagger2 extends Format if ($format) { $output['definitions'][$model->getType()]['properties'][$name]['items']['format'] = $format; } + if ($readOnly) { + $output['definitions'][$model->getType()]['properties'][$name]['readOnly'] = true; + } } else { $output['definitions'][$model->getType()]['properties'][$name] = [ 'type' => $type, @@ -725,6 +733,9 @@ class Swagger2 extends Format if ($format) { $output['definitions'][$model->getType()]['properties'][$name]['format'] = $format; } + if ($readOnly) { + $output['definitions'][$model->getType()]['properties'][$name]['readOnly'] = true; + } } if ($items) { $output['definitions'][$model->getType()]['properties'][$name]['items'] = $items; diff --git a/src/Appwrite/Utopia/Response/Model.php b/src/Appwrite/Utopia/Response/Model.php index 32de9fa035..962da4834c 100644 --- a/src/Appwrite/Utopia/Response/Model.php +++ b/src/Appwrite/Utopia/Response/Model.php @@ -91,7 +91,8 @@ abstract class Model 'array' => false, 'description' => '', 'example' => '', - 'sensitive' => false + 'sensitive' => false, + 'readOnly' => false ], $options); return $this; @@ -129,6 +130,27 @@ abstract class Model return $list; } + /** + * Get Readonly Fields + * + * Returns list of field names that are marked as readOnly + * and should not be allowed in create/update payloads + * + * @return array + */ + public function getReadonlyFields(): array + { + $list = []; + + foreach ($this->rules as $key => $rule) { + if ($rule['readOnly'] ?? false) { + $list[] = $key; + } + } + + return $list; + } + /** * Is None * diff --git a/src/Appwrite/Utopia/Response/Model/Document.php b/src/Appwrite/Utopia/Response/Model/Document.php index dc9faf6a8e..5bad504a63 100644 --- a/src/Appwrite/Utopia/Response/Model/Document.php +++ b/src/Appwrite/Utopia/Response/Model/Document.php @@ -41,18 +41,21 @@ class Document extends Any 'description' => 'Document automatically incrementing ID.', 'default' => 0, 'example' => 1, + 'readOnly' => true, ]) ->addRule('$collectionId', [ 'type' => self::TYPE_STRING, 'description' => 'Collection ID.', 'default' => '', 'example' => '5e5ea5c15117e', + 'readOnly' => true, ]) ->addRule('$databaseId', [ 'type' => self::TYPE_STRING, 'description' => 'Database ID.', 'default' => '', 'example' => '5e5ea5c15117e', + 'readOnly' => true, ]) ->addRule('$createdAt', [ 'type' => self::TYPE_DATETIME,