Skip to content

Commit 06e3a14

Browse files
authored
Merge pull request #10939 from appwrite/fix-smtp-auth-check
Fix smtp auth check
2 parents 9fb1aaa + 36519c1 commit 06e3a14

5 files changed

Lines changed: 91 additions & 87 deletions

File tree

.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ _APP_STORAGE_ANTIVIRUS_PORT=3310
6969
_APP_SMTP_HOST=maildev
7070
_APP_SMTP_PORT=1025
7171
_APP_SMTP_SECURE=
72-
_APP_SMTP_USERNAME=
73-
_APP_SMTP_PASSWORD=
72+
_APP_SMTP_USERNAME=user
73+
_APP_SMTP_PASSWORD=password
7474
_APP_SMS_PROVIDER=sms://username:password@mock
7575
_APP_SMS_FROM=+123456789
7676
_APP_SMS_PROJECTS_DENY_LIST=

app/controllers/api/projects.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@
294294

295295
// Hook allowing instant project mirroring during migration
296296
// Outside of migration, hook is not registered and has no effect
297-
$hooks->trigger('afterProjectCreation', [ $project, $pools, $cache ]);
297+
$hooks->trigger('afterProjectCreation', [$project, $pools, $cache]);
298298

299299
$response
300300
->setStatusCode(Response::STATUS_CODE_CREATED)
@@ -2079,6 +2079,7 @@
20792079
if ($enabled) {
20802080
$mail = new PHPMailer(true);
20812081
$mail->isSMTP();
2082+
$mail->SMTPAuth = (!empty($username) && !empty($password));
20822083
$mail->Username = $username;
20832084
$mail->Password = $password;
20842085
$mail->Host = $host;
@@ -2094,7 +2095,7 @@
20942095
throw new Exception('Connection is not valid.');
20952096
}
20962097
} catch (Throwable $error) {
2097-
throw new Exception(Exception::PROJECT_SMTP_CONFIG_INVALID, 'Could not connect to SMTP server: ' . $error->getMessage());
2098+
throw new Exception(Exception::PROJECT_SMTP_CONFIG_INVALID, $error->getMessage());
20982099
}
20992100
}
21002101

@@ -2665,7 +2666,7 @@
26652666
$auths = $project->getAttribute('auths', []);
26662667
$auths['invalidateSessions'] = $enabled;
26672668
$dbForPlatform->updateDocument('projects', $project->getId(), $project
2668-
->setAttribute('auths', $auths));
2669+
->setAttribute('auths', $auths));
26692670

26702671
$response->dynamic($project, Response::MODEL_PROJECT);
26712672
});

docker-compose.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,6 +1131,9 @@ services:
11311131
- "traefik.http.routers.appwrite_maildev_https.rule=Host(`mail.localhost`)"
11321132
- "traefik.http.routers.appwrite_maildev_https.service=appwrite_maildev"
11331133
- "traefik.http.routers.appwrite_maildev_https.tls=true"
1134+
environment:
1135+
- MAILDEV_INCOMING_USER=${_APP_SMTP_USERNAME}
1136+
- MAILDEV_INCOMING_PASS=${_APP_SMTP_PASSWORD}
11341137

11351138
request-catcher-webhook: # used mainly for dev tests (mock HTTP webhook)
11361139
image: appwrite/requestcatcher:1.0.0

tests/e2e/Scopes/ProjectCustom.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,9 @@ public function getProject(bool $fresh = false): array
161161
'senderEmail' => '[email protected]',
162162
'senderName' => 'Mailer',
163163
'host' => 'maildev',
164-
'port' => 1025,
165-
'username' => '',
166-
'password' => '',
164+
'port' => intval(System::getEnv('_APP_SMTP_PORT', "1025")),
165+
'username' => System::getEnv('_APP_SMTP_USERNAME', 'user'),
166+
'password' => System::getEnv('_APP_SMTP_PASSWORD', 'password'),
167167
]);
168168

169169
$project = [

tests/e2e/Services/Projects/ProjectsConsoleClientTest.php

Lines changed: 79 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ class ProjectsConsoleClientTest extends Scope
2323
use Async;
2424

2525
/**
26-
* @group devKeys
2726
* @group smtpAndTemplates
28-
* @group projectsCRUD */
27+
* @group projectsCRUD
28+
*/
2929
public function testCreateProject(): array
3030
{
3131
/**
@@ -257,11 +257,11 @@ public function testListProject($data): array
257257
'search' => $id
258258
]));
259259

260-
$this->assertEquals($response['headers']['status-code'], 200);
261-
$this->assertEquals($response['body']['total'], 3);
260+
$this->assertEquals(200, $response['headers']['status-code']);
261+
$this->assertEquals(4, $response['body']['total']);
262262
$this->assertIsArray($response['body']['projects']);
263-
$this->assertCount(3, $response['body']['projects']);
264-
$this->assertEquals($response['body']['projects'][0]['name'], 'Project Test');
263+
$this->assertCount(4, $response['body']['projects']);
264+
$this->assertEquals('Project Test', $response['body']['projects'][0]['name']);
265265

266266
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
267267
'content-type' => 'application/json',
@@ -271,9 +271,9 @@ public function testListProject($data): array
271271
]));
272272

273273
$this->assertEquals($response['headers']['status-code'], 200);
274-
$this->assertEquals(3, $response['body']['total']);
274+
$this->assertEquals(4, $response['body']['total']);
275275
$this->assertIsArray($response['body']['projects']);
276-
$this->assertCount(3, $response['body']['projects']);
276+
$this->assertCount(4, $response['body']['projects']);
277277
$this->assertEquals($response['body']['projects'][0]['$id'], $data['projectId']);
278278

279279
/**
@@ -348,8 +348,8 @@ public function testListProject($data): array
348348

349349
$this->assertEquals(200, $response['headers']['status-code']);
350350
$this->assertNotEmpty($response['body']);
351-
$this->assertCount(1, $response['body']['projects']);
352-
$this->assertEquals('Project Test 2', $response['body']['projects'][0]['name']);
351+
$this->assertCount(2, $response['body']['projects']);
352+
$this->assertEquals('Team 1 Project', $response['body']['projects'][0]['name']);
353353

354354
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
355355
'content-type' => 'application/json',
@@ -376,7 +376,7 @@ public function testListProject($data): array
376376

377377
$this->assertEquals(200, $response['headers']['status-code']);
378378
$this->assertNotEmpty($response['body']);
379-
$this->assertCount(4, $response['body']['projects']);
379+
$this->assertCount(5, $response['body']['projects']);
380380
$this->assertEquals('Project Test 2', $response['body']['projects'][0]['name']);
381381
$this->assertEquals('Team 1 Project', $response['body']['projects'][1]['name']);
382382

@@ -387,9 +387,9 @@ public function testListProject($data): array
387387

388388
$this->assertEquals(200, $response['headers']['status-code']);
389389
$this->assertNotEmpty($response['body']);
390-
$this->assertCount(4, $response['body']['projects']);
390+
$this->assertCount(5, $response['body']['projects']);
391391
$this->assertEquals('Project Test', $response['body']['projects'][0]['name']);
392-
$this->assertEquals('Team 1 Project', $response['body']['projects'][2]['name']);
392+
$this->assertEquals('Original Project', $response['body']['projects'][2]['name']);
393393

394394
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
395395
'content-type' => 'application/json',
@@ -402,8 +402,8 @@ public function testListProject($data): array
402402

403403
$this->assertEquals(200, $response['headers']['status-code']);
404404
$this->assertNotEmpty($response['body']);
405-
$this->assertCount(3, $response['body']['projects']);
406-
$this->assertEquals('Team 1 Project', $response['body']['projects'][1]['name']);
405+
$this->assertCount(4, $response['body']['projects']);
406+
$this->assertEquals('Original Project', $response['body']['projects'][1]['name']);
407407

408408
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
409409
'content-type' => 'application/json',
@@ -618,30 +618,38 @@ public function testUpdateProject(): void
618618
public function testUpdateProjectSMTP($data): array
619619
{
620620
$id = $data['projectId'];
621+
$smtpHost = System::getEnv('_APP_SMTP_HOST', "maildev");
622+
$smtpPort = intval(System::getEnv('_APP_SMTP_PORT', "1025"));
623+
$smtpUsername = System::getEnv('_APP_SMTP_USERNAME', 'user');
624+
$smtpPassword = System::getEnv('_APP_SMTP_PASSWORD', 'password');
625+
626+
/**
627+
* Test for SUCCESS: Valid Credentials
628+
*/
621629
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/smtp', array_merge([
622630
'content-type' => 'application/json',
623631
'x-appwrite-project' => $this->getProject()['$id'],
624632
], $this->getHeaders()), [
625633
'enabled' => true,
626634
'senderEmail' => '[email protected]',
627635
'senderName' => 'Mailer',
628-
'host' => 'maildev',
629-
'port' => 1025,
630-
'username' => 'user',
631-
'password' => 'password',
636+
'host' => $smtpHost,
637+
'port' => $smtpPort,
638+
'username' => $smtpUsername,
639+
'password' => $smtpPassword,
632640
]);
633641

634642
$this->assertEquals(200, $response['headers']['status-code']);
635643
$this->assertTrue($response['body']['smtpEnabled']);
636644
$this->assertEquals('[email protected]', $response['body']['smtpSenderEmail']);
637645
$this->assertEquals('Mailer', $response['body']['smtpSenderName']);
638-
$this->assertEquals('maildev', $response['body']['smtpHost']);
639-
$this->assertEquals(1025, $response['body']['smtpPort']);
640-
$this->assertEquals('user', $response['body']['smtpUsername']);
641-
$this->assertEquals('password', $response['body']['smtpPassword']);
646+
$this->assertEquals($smtpHost, $response['body']['smtpHost']);
647+
$this->assertEquals($smtpPort, $response['body']['smtpPort']);
648+
$this->assertEquals($smtpUsername, $response['body']['smtpUsername']);
649+
$this->assertEquals($smtpPassword, $response['body']['smtpPassword']);
642650
$this->assertEquals('', $response['body']['smtpSecure']);
643651

644-
/** Test Reading Project */
652+
// Check the project
645653
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
646654
'content-type' => 'application/json',
647655
'x-appwrite-project' => $this->getProject()['$id'],
@@ -651,12 +659,32 @@ public function testUpdateProjectSMTP($data): array
651659
$this->assertTrue($response['body']['smtpEnabled']);
652660
$this->assertEquals('[email protected]', $response['body']['smtpSenderEmail']);
653661
$this->assertEquals('Mailer', $response['body']['smtpSenderName']);
654-
$this->assertEquals('maildev', $response['body']['smtpHost']);
655-
$this->assertEquals(1025, $response['body']['smtpPort']);
656-
$this->assertEquals('user', $response['body']['smtpUsername']);
657-
$this->assertEquals('password', $response['body']['smtpPassword']);
662+
$this->assertEquals($smtpHost, $response['body']['smtpHost']);
663+
$this->assertEquals($smtpPort, $response['body']['smtpPort']);
664+
$this->assertEquals($smtpUsername, $response['body']['smtpUsername']);
665+
$this->assertEquals($smtpPassword, $response['body']['smtpPassword']);
658666
$this->assertEquals('', $response['body']['smtpSecure']);
659667

668+
/**
669+
* Test for FAILURE: Invalid Credentials
670+
*/
671+
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/smtp', array_merge([
672+
'content-type' => 'application/json',
673+
'x-appwrite-project' => $this->getProject()['$id'],
674+
], $this->getHeaders()), [
675+
'enabled' => true,
676+
'senderEmail' => '[email protected]',
677+
'senderName' => 'Failing Mailer',
678+
'host' => $smtpHost,
679+
'port' => $smtpPort,
680+
'username' => 'invalid-user',
681+
'password' => 'bad-password',
682+
]);
683+
684+
$this->assertEquals(400, $response['headers']['status-code']);
685+
$this->assertEquals(Exception::PROJECT_SMTP_CONFIG_INVALID, $response['body']['type']);
686+
$this->assertStringContainsStringIgnoringCase('Could not authenticate', $response['body']['message']);
687+
660688
return $data;
661689
}
662690

@@ -665,6 +693,11 @@ public function testUpdateProjectSMTP($data): array
665693
*/
666694
public function testCreateProjectSMTPTests(): void
667695
{
696+
$smtpHost = System::getEnv('_APP_SMTP_HOST', "maildev");
697+
$smtpPort = intval(System::getEnv('_APP_SMTP_PORT', "1025"));
698+
$smtpUsername = System::getEnv('_APP_SMTP_USERNAME', 'user');
699+
$smtpPassword = System::getEnv('_APP_SMTP_PASSWORD', 'password');
700+
668701
// Create a team
669702
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
670703
'content-type' => 'application/json',
@@ -699,10 +732,10 @@ public function testCreateProjectSMTPTests(): void
699732
'senderEmail' => '[email protected]',
700733
'senderName' => 'Custom Mailer',
701734
'replyTo' => '[email protected]',
702-
'host' => 'maildev',
703-
'port' => 1025,
704-
'username' => '',
705-
'password' => '',
735+
'host' => $smtpHost,
736+
'port' => $smtpPort,
737+
'username' => $smtpUsername,
738+
'password' => $smtpPassword,
706739
]);
707740

708741
$this->assertEquals(204, $response['headers']['status-code']);
@@ -736,10 +769,10 @@ public function testCreateProjectSMTPTests(): void
736769
'senderEmail' => '[email protected]',
737770
'senderName' => 'Custom Mailer',
738771
'replyTo' => '[email protected]',
739-
'host' => 'maildev',
740-
'port' => 1025,
741-
'username' => '',
742-
'password' => '',
772+
'host' => $smtpHost,
773+
'port' => $smtpPort,
774+
'username' => $smtpUsername,
775+
'password' => $smtpPassword,
743776
]);
744777

745778
$this->assertEquals(204, $response['headers']['status-code']);
@@ -752,10 +785,10 @@ public function testCreateProjectSMTPTests(): void
752785
'senderEmail' => '[email protected]',
753786
'senderName' => 'Custom Mailer',
754787
'replyTo' => '[email protected]',
755-
'host' => 'maildev',
756-
'port' => 1025,
757-
'username' => '',
758-
'password' => '',
788+
'host' => $smtpHost,
789+
'port' => $smtpPort,
790+
'username' => $smtpUsername,
791+
'password' => $smtpPassword,
759792
]);
760793

761794
$this->assertEquals(400, $response['headers']['status-code']);
@@ -776,7 +809,7 @@ public function testUpdateTemplates($data): array
776809
], $this->getHeaders()));
777810

778811
$this->assertEquals(200, $response['headers']['status-code']);
779-
$this->assertEquals('Account Verification', $response['body']['subject']);
812+
$this->assertEquals('Account Verification for {{project}}', $response['body']['subject']);
780813
$this->assertEquals('', $response['body']['senderEmail']);
781814
$this->assertEquals('verification', $response['body']['type']);
782815
$this->assertEquals('en-us', $response['body']['locale']);
@@ -879,7 +912,7 @@ public function testUpdateProjectAuthDuration($data): array
879912

880913
$this->assertEquals(200, $response['headers']['status-code']);
881914
$this->assertNotEmpty($response['body']['$id']);
882-
$this->assertEquals('Project Test 2', $response['body']['name']);
915+
$this->assertEquals('Project Test', $response['body']['name']);
883916
$this->assertArrayHasKey('platforms', $response['body']);
884917
$this->assertArrayHasKey('webhooks', $response['body']);
885918
$this->assertArrayHasKey('keys', $response['body']);
@@ -959,39 +992,6 @@ public function testUpdateProjectAuthDuration($data): array
959992
$this->assertEquals(200, $response['headers']['status-code']);
960993
$this->assertEquals(15, $response['body']['authDuration']);
961994

962-
// Create session
963-
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([
964-
'content-type' => 'application/json',
965-
'x-appwrite-project' => $projectId,
966-
]), [
967-
'email' => $userEmail,
968-
'password' => 'password',
969-
]);
970-
971-
$this->assertEquals(201, $response['headers']['status-code']);
972-
973-
$sessionCookie = $response['headers']['set-cookie'];
974-
975-
// Wait 10 seconds, ensure valid session, extend session
976-
\sleep(10);
977-
978-
$response = $this->client->call(Client::METHOD_GET, '/account', array_merge([
979-
'content-type' => 'application/json',
980-
'x-appwrite-project' => $projectId,
981-
'Cookie' => $sessionCookie,
982-
]));
983-
984-
$this->assertEquals(200, $response['headers']['status-code']);
985-
986-
$response = $this->client->call(Client::METHOD_PATCH, '/account/sessions/current', array_merge([
987-
'origin' => 'http://localhost',
988-
'content-type' => 'application/json',
989-
'x-appwrite-project' => $projectId,
990-
'cookie' => $sessionCookie,
991-
]));
992-
993-
$this->assertEquals(200, $response['headers']['status-code']);
994-
995995
// Wait 20 seconds, ensure non-valid session
996996
\sleep(20);
997997

@@ -3132,7 +3132,7 @@ public function testUpdateProjectKey($data): array
31323132
$this->assertContains('users.write', $response['body']['scopes']);
31333133
$this->assertContains('collections.read', $response['body']['scopes']);
31343134
$this->assertContains('tables.read', $response['body']['scopes']);
3135-
$this->assertCount(3, $response['body']['scopes']);
3135+
$this->assertCount(4, $response['body']['scopes']);
31363136
$this->assertArrayHasKey('sdks', $response['body']);
31373137
$this->assertEmpty($response['body']['sdks']);
31383138
$this->assertArrayHasKey('accessedAt', $response['body']);
@@ -3151,7 +3151,7 @@ public function testUpdateProjectKey($data): array
31513151
$this->assertContains('users.write', $response['body']['scopes']);
31523152
$this->assertContains('collections.read', $response['body']['scopes']);
31533153
$this->assertContains('tables.read', $response['body']['scopes']);
3154-
$this->assertCount(3, $response['body']['scopes']);
3154+
$this->assertCount(4, $response['body']['scopes']);
31553155
$this->assertArrayHasKey('sdks', $response['body']);
31563156
$this->assertEmpty($response['body']['sdks']);
31573157
$this->assertArrayHasKey('accessedAt', $response['body']);
@@ -5086,8 +5086,8 @@ public function testDeleteProjectDevKey(): void
50865086
$this->assertEmpty($response['body']);
50875087

50885088
/**
5089-
* Get rate limit trying to use the deleted key
5090-
*/
5089+
* Get rate limit trying to use the deleted key
5090+
*/
50915091
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [
50925092
'content-type' => 'application/json',
50935093
'x-appwrite-project' => $projectId,

0 commit comments

Comments
 (0)