From be1753a198b09aa7d596ae732535bfba76ec361a Mon Sep 17 00:00:00 2001 From: Binyamin Yawitz <316103+byawitz@users.noreply.github.com> Date: Thu, 1 Aug 2024 14:36:21 -0400 Subject: [PATCH 1/5] refactor: no session alerts for otp and magic-url logins --- app/controllers/api/account.php | 8 ++- .../Account/AccountCustomClientTest.php | 56 ++++++++++++++++++- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 37627d79fc..082ea8ab79 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -177,6 +177,12 @@ $createSession = function (string $userId, string $secret, Request $request, Res default => throw new Exception(Exception::USER_INVALID_TOKEN) }); + $sendingAlerts = (match ($verifiedToken->getAttribute('type')) { + Auth::TOKEN_TYPE_MAGIC_URL, + Auth::TOKEN_TYPE_EMAIL => false, + default => true + }); + $session = new Document(array_merge( [ '$id' => ID::unique(), @@ -223,7 +229,7 @@ $createSession = function (string $userId, string $secret, Request $request, Res throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed saving user to DB'); } - if ($project->getAttribute('auths', [])['sessionAlerts'] ?? false) { + if (($project->getAttribute('auths', [])['sessionAlerts'] ?? false) && $sendingAlerts) { sendSessionAlert($locale, $user, $project, $session, $queueForMails); } diff --git a/tests/e2e/Services/Account/AccountCustomClientTest.php b/tests/e2e/Services/Account/AccountCustomClientTest.php index 321b1110fd..00d37bd426 100644 --- a/tests/e2e/Services/Account/AccountCustomClientTest.php +++ b/tests/e2e/Services/Account/AccountCustomClientTest.php @@ -620,9 +620,9 @@ class AccountCustomClientTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'], ]), [ 'userId' => ID::unique(), - 'email' => $data['email'], - 'password' => $data['password'], - 'name' => $data['name'], + 'email' => $data['email'], + 'password' => $data['password'], + 'name' => $data['name'], ]); $this->assertEquals(201, $response['headers']['status-code']); @@ -1246,6 +1246,56 @@ class AccountCustomClientTest extends Scope $this->assertStringContainsString($response['body']['ip'], $lastEmail['text']); // IP Address $this->assertStringContainsString('Unknown', $lastEmail['text']); // Country $this->assertStringContainsString($response['body']['clientName'], $lastEmail['text']); // Client name + + // Verify no alert sent in OTP login + $response = $this->client->call(Client::METHOD_POST, '/account/tokens/email', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]), [ + 'userId' => ID::unique(), + 'email' => 'otpuser2@appwrite.io' + ]); + + $this->assertEquals($response['headers']['status-code'], 201); + $this->assertNotEmpty($response['body']['$id']); + $this->assertNotEmpty($response['body']['$createdAt']); + $this->assertNotEmpty($response['body']['userId']); + $this->assertNotEmpty($response['body']['expire']); + $this->assertEmpty($response['body']['secret']); + $this->assertEmpty($response['body']['phrase']); + + $userId = $response['body']['userId']; + + $lastEmail = $this->getLastEmail(); + + $this->assertEquals('otpuser2@appwrite.io', $lastEmail['to'][0]['address']); + $this->assertEquals('OTP for ' . $this->getProject()['name'] . ' Login', $lastEmail['subject']); + + // FInd 6 concurrent digits in email text - OTP + preg_match_all("/\b\d{6}\b/", $lastEmail['text'], $matches); + $code = ($matches[0] ?? [])[0] ?? ''; + + $this->assertNotEmpty($code); + + $response = $this->client->call(Client::METHOD_POST, '/account/sessions/token', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]), [ + 'userId' => $userId, + 'secret' => $code + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals($userId, $response['body']['userId']); + $this->assertNotEmpty($response['body']['$id']); + $this->assertNotEmpty($response['body']['expire']); + $this->assertEmpty($response['body']['secret']); + + $lastEmailId = $lastEmail['id']; + $lastEmail = $this->getLastEmail(); + $this->assertEquals($lastEmailId, $lastEmail['id']); } /** From 47d1bc44e5197a98891b551e779c46bbb7cb22b8 Mon Sep 17 00:00:00 2001 From: Binyamin Yawitz <316103+byawitz@users.noreply.github.com> Date: Mon, 5 Aug 2024 16:16:59 -0400 Subject: [PATCH 2/5] refactor: Variables names --- app/controllers/api/account.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 082ea8ab79..8d15d903ae 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -177,7 +177,7 @@ $createSession = function (string $userId, string $secret, Request $request, Res default => throw new Exception(Exception::USER_INVALID_TOKEN) }); - $sendingAlerts = (match ($verifiedToken->getAttribute('type')) { + $sendAlert = (match ($verifiedToken->getAttribute('type')) { Auth::TOKEN_TYPE_MAGIC_URL, Auth::TOKEN_TYPE_EMAIL => false, default => true @@ -229,7 +229,7 @@ $createSession = function (string $userId, string $secret, Request $request, Res throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed saving user to DB'); } - if (($project->getAttribute('auths', [])['sessionAlerts'] ?? false) && $sendingAlerts) { + if (($project->getAttribute('auths', [])['sessionAlerts'] ?? false) && $sendAlert) { sendSessionAlert($locale, $user, $project, $session, $queueForMails); } From 834fad78e1af3a3ac76f4f0f9cb53824fc00cdef Mon Sep 17 00:00:00 2001 From: Binyamin Yawitz <316103+byawitz@users.noreply.github.com> Date: Mon, 5 Aug 2024 16:20:52 -0400 Subject: [PATCH 3/5] refactor: Variables names --- app/controllers/api/account.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index af4e60364e..e2d6788f96 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -177,6 +177,12 @@ $createSession = function (string $userId, string $secret, Request $request, Res default => throw new Exception(Exception::USER_INVALID_TOKEN) }); + $sendAlert = (match ($verifiedToken->getAttribute('type')) { + Auth::TOKEN_TYPE_MAGIC_URL, + Auth::TOKEN_TYPE_EMAIL => false, + default => true + }); + $session = new Document(array_merge( [ '$id' => ID::unique(), @@ -223,7 +229,7 @@ $createSession = function (string $userId, string $secret, Request $request, Res throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed saving user to DB'); } - if ($project->getAttribute('auths', [])['sessionAlerts'] ?? false) { + if (($project->getAttribute('auths', [])['sessionAlerts'] ?? false) && $sendAlert) { if ($dbForProject->count('sessions', [ Query::equal('userId', [$user->getId()]), ]) !== 1) { From caa234f14058d21a8551b6986db20ce0fa264349 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Thu, 8 Aug 2024 19:15:00 +0530 Subject: [PATCH 4/5] Add scopes to function template --- src/Appwrite/Utopia/Response/Model/TemplateFunction.php | 7 +++++++ tests/e2e/Services/Functions/FunctionsCustomClientTest.php | 1 + 2 files changed, 8 insertions(+) diff --git a/src/Appwrite/Utopia/Response/Model/TemplateFunction.php b/src/Appwrite/Utopia/Response/Model/TemplateFunction.php index f5df10986f..c630880a95 100644 --- a/src/Appwrite/Utopia/Response/Model/TemplateFunction.php +++ b/src/Appwrite/Utopia/Response/Model/TemplateFunction.php @@ -110,6 +110,13 @@ class TemplateFunction extends Model 'default' => [], 'example' => [], 'array' => true + ]) + ->addRule('scopes', [ + 'type' => self::TYPE_STRING, + 'description' => 'Function scopes.', + 'default' => [], + 'example' => 'users.read', + 'array' => true, ]); } diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 3aaa18594e..2bd6880239 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -881,6 +881,7 @@ class FunctionsCustomClientTest extends Scope $this->assertEquals($expectedTemplates[$i]['vcsProvider'], $templates['body']['templates'][$i]['vcsProvider']); $this->assertEquals($expectedTemplates[$i]['runtimes'], $templates['body']['templates'][$i]['runtimes']); $this->assertEquals($expectedTemplates[$i]['variables'], $templates['body']['templates'][$i]['variables']); + $this->assertEquals($expectedTemplates[$i]['scopes'], $templates['body']['templates'][$i]['scopes']); } $templates_offset = $this->client->call(Client::METHOD_GET, '/functions/templates', array_merge([ From 7cfdf40b4784ba807229f713fa646686f0bfac41 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Thu, 8 Aug 2024 19:38:59 +0530 Subject: [PATCH 5/5] Fix tests --- tests/e2e/Services/Functions/FunctionsCustomClientTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 2bd6880239..79e7a83dda 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -881,7 +881,9 @@ class FunctionsCustomClientTest extends Scope $this->assertEquals($expectedTemplates[$i]['vcsProvider'], $templates['body']['templates'][$i]['vcsProvider']); $this->assertEquals($expectedTemplates[$i]['runtimes'], $templates['body']['templates'][$i]['runtimes']); $this->assertEquals($expectedTemplates[$i]['variables'], $templates['body']['templates'][$i]['variables']); - $this->assertEquals($expectedTemplates[$i]['scopes'], $templates['body']['templates'][$i]['scopes']); + if (array_key_exists('scopes', $expectedTemplates[$i])) { + $this->assertEquals($expectedTemplates[$i]['scopes'], $templates['body']['templates'][$i]['scopes']); + } } $templates_offset = $this->client->call(Client::METHOD_GET, '/functions/templates', array_merge([