From a14d5c584ebefbd3e9181c1df3965071b4226001 Mon Sep 17 00:00:00 2001 From: VijaykumarPujar-tech Date: Mon, 8 Dec 2025 20:22:18 +0530 Subject: [PATCH 1/4] Fix: robust SMTP validation and added regression test --- .../Projects/ProjectsConsoleClientTest.php | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index e297757225..99f7205d28 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -564,6 +564,10 @@ class ProjectsConsoleClientTest extends Scope public function testUpdateProjectSMTP($data): array { $id = $data['projectId']; + + /** + * Test for SUCCESS: Valid Credentials + */ $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/smtp', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -603,6 +607,35 @@ class ProjectsConsoleClientTest extends Scope $this->assertEquals('password', $response['body']['smtpPassword']); $this->assertEquals('', $response['body']['smtpSecure']); + /** * Test for FAILURE: Missing or Invalid Credentials + */ + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/smtp', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'enabled' => true, + 'senderEmail' => 'fail@appwrite.io', + 'senderName' => 'Failing Mailer', + 'host' => 'maildev', + 'port' => 1025, + 'username' => 'invalid-user', + 'password' => 'bad-password', + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + $this->assertEquals(Exception::PROJECT_SMTP_CONFIG_INVALID, $response['body']['type']); + $this->assertStringContainsStringIgnoringCase('SMTP authentication failed.', $response['body']['message']); + + /** * Test Reading Project to ensure settings were NOT saved after failure + */ + $response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('mailer@appwrite.io', $response['body']['smtpSenderEmail']); + return $data; } From 2fa95b52a047377445cb0ea8c28ef3cacb168e27 Mon Sep 17 00:00:00 2001 From: VijaykumarPujar-tech Date: Tue, 9 Dec 2025 22:40:51 +0530 Subject: [PATCH 2/4] Reverted some added changes --- .../Projects/ProjectsConsoleClientTest.php | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 99f7205d28..7e81ca9db0 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -565,9 +565,7 @@ class ProjectsConsoleClientTest extends Scope { $id = $data['projectId']; - /** - * Test for SUCCESS: Valid Credentials - */ + /**Test for SUCCESS: Valid Credentials*/ $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/smtp', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -607,8 +605,7 @@ class ProjectsConsoleClientTest extends Scope $this->assertEquals('password', $response['body']['smtpPassword']); $this->assertEquals('', $response['body']['smtpSecure']); - /** * Test for FAILURE: Missing or Invalid Credentials - */ + /** Test for Missing or Invalid Credentials*/ $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/smtp', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -626,16 +623,6 @@ class ProjectsConsoleClientTest extends Scope $this->assertEquals(Exception::PROJECT_SMTP_CONFIG_INVALID, $response['body']['type']); $this->assertStringContainsStringIgnoringCase('SMTP authentication failed.', $response['body']['message']); - /** * Test Reading Project to ensure settings were NOT saved after failure - */ - $response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); - - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals('mailer@appwrite.io', $response['body']['smtpSenderEmail']); - return $data; } From 8951a8465c5d7a485604ef65a974da8dda1ed68c Mon Sep 17 00:00:00 2001 From: VijaykumarPujar-tech Date: Tue, 9 Dec 2025 23:30:34 +0530 Subject: [PATCH 3/4] Added the projects.php changes back --- app/controllers/api/projects.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 80d407322e..b8011828ce 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -2073,8 +2073,11 @@ App::patch('/v1/projects/:projectId/smtp') if ($enabled) { $mail = new PHPMailer(true); $mail->isSMTP(); - $mail->Username = $username; - $mail->Password = $password; + if (!empty($username) && !empty($password)) { + $mail->SMTPAuth = true; + $mail->Username = $username; + $mail->Password = $password; + } $mail->Host = $host; $mail->Port = $port; $mail->SMTPSecure = $secure; From e0a937912c6a9a2cc7c11636f843891e3496ecc3 Mon Sep 17 00:00:00 2001 From: VijaykumarPujar-tech Date: Tue, 9 Dec 2025 23:46:44 +0530 Subject: [PATCH 4/4] Added Validation check for username and password --- app/controllers/api/projects.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index b8011828ce..e0f8013467 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -2071,13 +2071,16 @@ App::patch('/v1/projects/:projectId/smtp') // validate SMTP settings if ($enabled) { + if (empty($username)) { + throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'SMTP Username is required when enabling SMTP.'); + } elseif (empty($password)) { + throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'SMTP Password is required when enabling SMTP.'); + } $mail = new PHPMailer(true); $mail->isSMTP(); - if (!empty($username) && !empty($password)) { - $mail->SMTPAuth = true; - $mail->Username = $username; - $mail->Password = $password; - } + $mail->SMTPAuth = true; + $mail->Username = $username; + $mail->Password = $password; $mail->Host = $host; $mail->Port = $port; $mail->SMTPSecure = $secure;