From 8ea69e03212ecbdc53f8c23accfcf01f4e103815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 20 Apr 2026 16:57:23 +0200 Subject: [PATCH] Fix password visibility test --- src/Appwrite/Utopia/Response/Model/Project.php | 9 +++------ tests/e2e/Services/Project/SMTPBase.php | 14 ++++++++++++-- .../Projects/ProjectsConsoleClientTest.php | 6 ++++-- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/Appwrite/Utopia/Response/Model/Project.php b/src/Appwrite/Utopia/Response/Model/Project.php index aef4927ad7..11e23b02d8 100644 --- a/src/Appwrite/Utopia/Response/Model/Project.php +++ b/src/Appwrite/Utopia/Response/Model/Project.php @@ -277,15 +277,12 @@ class Project extends Model 'default' => '', 'example' => 'emailuser', ]) - /* - We intentionally do not expose SMTP password - it's write-only property. ->addRule('smtpPassword', [ 'type' => self::TYPE_STRING, - 'description' => 'SMTP server password', + 'description' => 'SMTP server password. This property is write-only and always returned empty.', 'default' => '', - 'example' => 'securepassword', + 'example' => '', ]) - */ ->addRule('smtpSecure', [ 'type' => self::TYPE_STRING, 'description' => 'SMTP server secure protocol', @@ -423,7 +420,7 @@ class Project extends Model $document->setAttribute('smtpHost', $smtp['host'] ?? ''); $document->setAttribute('smtpPort', $smtp['port'] ?? ''); $document->setAttribute('smtpUsername', $smtp['username'] ?? ''); - $document->setAttribute('smtpPassword', $smtp['password'] ?? ''); + $document->setAttribute('smtpPassword', ''); // Write-only: never expose the stored value $document->setAttribute('smtpSecure', $smtp['secure'] ?? ''); } diff --git a/tests/e2e/Services/Project/SMTPBase.php b/tests/e2e/Services/Project/SMTPBase.php index c8cb06ac4e..fa58891b08 100644 --- a/tests/e2e/Services/Project/SMTPBase.php +++ b/tests/e2e/Services/Project/SMTPBase.php @@ -88,6 +88,8 @@ trait SMTPBase senderEmail: 'sender@example.com', host: 'maildev', port: 1025, + username: 'user', + password: 'password', enabled: true, ); @@ -103,6 +105,8 @@ trait SMTPBase $this->assertArrayHasKey('smtpPort', $response['body']); $this->assertArrayHasKey('smtpUsername', $response['body']); $this->assertArrayHasKey('smtpPassword', $response['body']); + // smtpPassword is write-only: the stored password must never leak in responses + $this->assertSame('', $response['body']['smtpPassword']); $this->assertArrayHasKey('smtpSecure', $response['body']); // Cleanup @@ -219,6 +223,8 @@ trait SMTPBase senderEmail: 'sender@example.com', host: 'maildev', port: 1025, + username: 'user', + password: 'password', ); $this->assertSame(200, $response['headers']['status-code']); @@ -233,6 +239,8 @@ trait SMTPBase $this->assertArrayHasKey('smtpPort', $response['body']); $this->assertArrayHasKey('smtpUsername', $response['body']); $this->assertArrayHasKey('smtpPassword', $response['body']); + // smtpPassword is write-only: the stored password must never leak in responses + $this->assertSame('', $response['body']['smtpPassword']); $this->assertArrayHasKey('smtpSecure', $response['body']); // Cleanup @@ -455,7 +463,8 @@ trait SMTPBase ); $this->assertSame(200, $response['headers']['status-code']); - $this->assertSame('p', $response['body']['smtpPassword']); + // smtpPassword is write-only: the accepted password must not be echoed back + $this->assertSame('', $response['body']['smtpPassword']); // Cleanup $this->updateSMTP(enabled: false); @@ -473,7 +482,8 @@ trait SMTPBase ); $this->assertSame(200, $response['headers']['status-code']); - $this->assertSame($password, $response['body']['smtpPassword']); + // smtpPassword is write-only: the accepted password must not be echoed back + $this->assertSame('', $response['body']['smtpPassword']); // Cleanup $this->updateSMTP(enabled: false); diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 4400c337ac..9506c1a963 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -971,7 +971,8 @@ class ProjectsConsoleClientTest extends Scope $this->assertEquals($smtpHost, $response['body']['smtpHost']); $this->assertEquals($smtpPort, $response['body']['smtpPort']); $this->assertEquals($smtpUsername, $response['body']['smtpUsername']); - $this->assertEquals($smtpPassword, $response['body']['smtpPassword']); + // smtpPassword is write-only: the stored password must never leak in responses + $this->assertEquals('', $response['body']['smtpPassword']); $this->assertEquals('', $response['body']['smtpSecure']); // Check the project @@ -987,7 +988,8 @@ class ProjectsConsoleClientTest extends Scope $this->assertEquals($smtpHost, $response['body']['smtpHost']); $this->assertEquals($smtpPort, $response['body']['smtpPort']); $this->assertEquals($smtpUsername, $response['body']['smtpUsername']); - $this->assertEquals($smtpPassword, $response['body']['smtpPassword']); + // smtpPassword is write-only: the stored password must never leak in responses + $this->assertEquals('', $response['body']['smtpPassword']); $this->assertEquals('', $response['body']['smtpSecure']); /**