-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Fix readonly attr stripping on write #10405
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
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -100,6 +100,7 @@ public function action(string $databaseId, string $collectionId, array $document | |||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| foreach ($documents as $key => $document) { | ||||||||||||||||||||||||||||
| $document = $this->removeReadonlyAttributes($document); | ||||||||||||||||||||||||||||
| $documents[$key] = new Document($document); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
Comment on lines
102
to
105
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove noisy debug output in removeReadonlyAttributes (can corrupt HTTP responses). Calls here rely on a helper that currently var_dumps per attribute. This can leak into JSON responses and break clients. Replace the var_dump with a silent unset (or proper logger) in Action.php. Apply in Action.php: protected function removeReadonlyAttributes(Document|array $document): Document|array
{
foreach ($this->removableAttributes as $attribute) {
- \var_dump('Removing attribute: ' . $attribute);
- unset($document[$attribute]);
+ if (isset($document[$attribute])) {
+ unset($document[$attribute]);
+ }
}
return $document;
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -159,17 +159,14 @@ public function action(string $databaseId, string $collectionId, string $documen | |||
| $permissions = $document->getPermissions() ?? []; | ||||
| } | ||||
|
|
||||
| // Remove sequence if set | ||||
| unset($document['$sequence']); | ||||
|
|
||||
| $data['$id'] = $documentId; | ||||
| $data['$permissions'] = $permissions; | ||||
| $data = $this->removeReadonlyAttributes($data); | ||||
| $newDocument = new Document($data); | ||||
|
|
||||
| $operations = 0; | ||||
|
|
||||
| $setCollection = (function (Document $collection, Document $document) use (&$setCollection, $dbForProject, $database, &$operations) { | ||||
|
|
||||
| $operations++; | ||||
|
|
||||
| $relationships = \array_filter( | ||||
|
|
@@ -208,11 +205,13 @@ public function action(string $databaseId, string $collectionId, string $documen | |||
| $relation = new Document($relation); | ||||
| } | ||||
| if ($relation instanceof Document) { | ||||
| $relation = $this->removeReadonlyAttributes($relation); | ||||
|
|
||||
| $oldDocument = Authorization::skip(fn () => $dbForProject->getDocument( | ||||
| 'database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence(), | ||||
| $relation->getId() | ||||
| )); | ||||
| $this->removeReadonlyAttributes($relation); | ||||
|
|
||||
| // Attribute $collection is required for Utopia. | ||||
| $relation->setAttribute( | ||||
| '$collection', | ||||
|
|
@@ -242,6 +241,8 @@ public function action(string $databaseId, string $collectionId, string $documen | |||
| ->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, max($operations, 1)) | ||||
| ->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), $operations); | ||||
|
|
||||
| \var_dump($newDocument); | ||||
|
|
||||
|
Comment on lines
+234
to
+235
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove debug output; var_dump corrupts HTTP responses and leaks data var_dump will pollute JSON bodies and can expose sensitive info under load. Remove it. Apply: - \var_dump($newDocument);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||
| try { | ||||
| $document = $dbForProject->withRequestTimestamp( | ||||
| $requestTimestamp, | ||||
|
|
||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -170,6 +170,7 @@ public function action(string $databaseId, string $collectionId, string $documen | |
|
|
||
| $data['$id'] = $documentId; | ||
| $data['$permissions'] = $permissions ?? []; | ||
| $data = $this->removeReadonlyAttributes($data); | ||
| $newDocument = new Document($data); | ||
| $operations = 0; | ||
|
||
|
|
||
|
|
@@ -213,11 +214,13 @@ public function action(string $databaseId, string $collectionId, string $documen | |
| $relation = new Document($relation); | ||
| } | ||
| if ($relation instanceof Document) { | ||
| $relation = $this->removeReadonlyAttributes($relation); | ||
|
|
||
| $oldDocument = Authorization::skip(fn () => $dbForProject->getDocument( | ||
| 'database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence(), | ||
| $relation->getId() | ||
| )); | ||
| $this->removeReadonlyAttributes($relation); | ||
|
|
||
| // Attribute $collection is required for Utopia. | ||
| $relation->setAttribute( | ||
| '$collection', | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1697,6 +1697,7 @@ public function testCreateDocument(array $data): array | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return $data; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @depends testCreateIndexes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -2211,6 +2212,49 @@ public function testUpsertDocument(array $data): void | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertArrayHasKey('$permissions', $library3['body']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertCount(3, $library3['body']['$permissions']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertNotEmpty($library3['body']['$permissions']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Readonly attributes are ignored | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $personNoPerm = $this->client->call(Client::METHOD_PUT, '/databases/' . $databaseId . '/collections/' . $person['body']['$id'] . '/documents/' . $newPersonId, array_merge([ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'content-type' => 'application/json', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'x-appwrite-project' => $this->getProject()['$id'], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ], $this->getHeaders()), [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'data' => [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '$id' => 'some-other-id', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '$collectionId' => 'some-other-collection', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '$databaseId' => 'some-other-database', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '$createdAt' => '2024-01-01T00:00:00Z', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '$updatedAt' => '2024-01-01T00:00:00Z', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'library' => [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '$id' => 'library3', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'libraryName' => 'Library 3', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '$createdAt' => '2024-01-01T00:00:00Z', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '$updatedAt' => '2024-01-01T00:00:00Z', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $update = $personNoPerm; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $update['body']['$id'] = 'random'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $update['body']['$sequence'] = 123; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $update['body']['$databaseId'] = 'random'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $update['body']['$collectionId'] = 'random'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $update['body']['$createdAt'] = '2024-01-01T00:00:00Z'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $update['body']['$updatedAt'] = '2024-01-01T00:00:00Z'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $upserted = $this->client->call(Client::METHOD_PUT, '/databases/' . $databaseId . '/collections/' . $person['body']['$id'] . '/documents/' . $newPersonId, array_merge([ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'content-type' => 'application/json', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'x-appwrite-project' => $this->getProject()['$id'], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ], $this->getHeaders()), [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'data' => $update['body'] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertEquals(200, $upserted['headers']['status-code']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertEquals($personNoPerm['body']['$id'], $upserted['body']['$id']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertEquals($personNoPerm['body']['$collectionId'], $upserted['body']['$collectionId']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertEquals($personNoPerm['body']['$databaseId'], $upserted['body']['$databaseId']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertEquals($personNoPerm['body']['$sequence'], $upserted['body']['$sequence']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertEquals($personNoPerm['body']['$createdAt'], $upserted['body']['$createdAt']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertNotEquals('2024-01-01T00:00:00Z', $upserted['body']['$updatedAt']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+2215
to
2264
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Strengthen assertions; avoid brittle “echo body back” payload
Apply this diff to extend assertions (keeping your current flow): $this->assertEquals(200, $upserted['headers']['status-code']);
$this->assertEquals($personNoPerm['body']['$id'], $upserted['body']['$id']);
$this->assertEquals($personNoPerm['body']['$collectionId'], $upserted['body']['$collectionId']);
$this->assertEquals($personNoPerm['body']['$databaseId'], $upserted['body']['$databaseId']);
$this->assertEquals($personNoPerm['body']['$sequence'], $upserted['body']['$sequence']);
$this->assertEquals($personNoPerm['body']['$createdAt'], $upserted['body']['$createdAt']);
$this->assertNotEquals('2024-01-01T00:00:00Z', $upserted['body']['$updatedAt']);
+ // Nested relation readonly attributes should also be ignored
+ $this->assertEquals('Library 3', $upserted['body']['library']['libraryName']);
+ $this->assertArrayHasKey('$createdAt', $upserted['body']['library']);
+ $this->assertNotEquals('2024-01-01T00:00:00Z', $upserted['body']['library']['$createdAt']);
+ $this->assertNotEquals('2024-01-01T00:00:00Z', $upserted['body']['library']['$updatedAt']);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -3000,6 +3044,31 @@ public function testUpdateDocument(array $data): array | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertEquals(200, $response['headers']['status-code']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Test readonly attributes are ignored | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $response = $this->client->call(Client::METHOD_PATCH, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents/' . $id, array_merge([ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'content-type' => 'application/json', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'x-appwrite-project' => $this->getProject()['$id'], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'x-appwrite-timestamp' => DateTime::formatTz(DateTime::now()), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ], $this->getHeaders()), [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'data' => [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '$id' => 'newId', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '$sequence' => 9999, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '$collectionId' => 'newCollectionId', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '$databaseId' => 'newDatabaseId', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '$createdAt' => '2024-01-01T00:00:00+00:00', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '$updatedAt' => '2024-01-01T00:00:00+00:00', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'title' => 'Thor: Ragnarok', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertEquals(200, $response['headers']['status-code']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertEquals($id, $response['body']['$id']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertEquals($data['moviesId'], $response['body']['$collectionId']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertEquals($databaseId, $response['body']['$databaseId']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertNotEquals('2024-01-01T00:00:00+00:00', $response['body']['$createdAt']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertNotEquals('2024-01-01T00:00:00+00:00', $response['body']['$updatedAt']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $this->assertNotEquals(9999, $response['body']['$sequence']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Fix helper: support Document|array, no var_dump, no fatal on Document
Apply:
Run to spot any remaining debug prints and audit call sites:
🏁 Script executed:
Length of output: 785
🏁 Script executed:
Length of output: 6268
Remove debug dumps and update removeReadonlyAttributes to handle Document safely
src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Action.php(line 205) and.../Update.php(line 244), remove the\var_dump(...)calls leaking internals.removeReadonlyAttributesbody with:protected function removeReadonlyAttributes(Document|array $document): Document|array { - foreach ($this->removableAttributes as $attribute) { - \var_dump('Removing attribute: ' . $attribute); - unset($document[$attribute]); - } + foreach ($this->removableAttributes as $attribute) { + if ($document instanceof Document) { + $document->removeAttribute($attribute); + } elseif (is_array($document)) { + unset($document[$attribute]); + } + } return $document; }rg --type=php '\bvar_dump\s*\(' srcto ensure no stray debug prints remain.removeReadonlyAttributes(...)call sites to confirm array returns are captured and Document instances aren’t inadvertently re-wrapped.📝 Committable suggestion
🤖 Prompt for AI Agents