From 7ae614fe138c85ba85a6447b09a2619d5e1371fc Mon Sep 17 00:00:00 2001 From: prateek banga Date: Tue, 14 Nov 2023 18:14:07 +0530 Subject: [PATCH 1/5] adds provider type in target --- app/config/collections.php | 15 ++- app/config/errors.php | 5 + app/controllers/api/account.php | 7 +- app/controllers/api/messaging.php | 103 ++++++++++++------ app/controllers/api/teams.php | 3 +- app/controllers/api/users.php | 53 ++++++--- src/Appwrite/Extend/Exception.php | 1 + src/Appwrite/Platform/Workers/Messaging.php | 30 ++++- src/Appwrite/Utopia/Response/Model/Target.php | 6 + tests/e2e/Services/GraphQL/Base.php | 12 +- tests/e2e/Services/GraphQL/MessagingTest.php | 7 ++ tests/e2e/Services/GraphQL/UsersTest.php | 3 +- .../e2e/Services/Messaging/MessagingBase.php | 19 ++++ tests/e2e/Services/Users/UsersBase.php | 8 +- 14 files changed, 202 insertions(+), 70 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index aa6afffb17..bfa8192b74 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -1845,7 +1845,7 @@ $commonCollections = [ 'filters' => [], ], [ - '$id' => ID::custom('providerId'), + '$id' => ID::custom('providerType'), 'type' => Database::VAR_STRING, 'format' => '', 'size' => Database::LENGTH_KEY, @@ -1855,13 +1855,24 @@ $commonCollections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => ID::custom('providerId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], [ '$id' => ID::custom('providerInternalId'), 'type' => Database::VAR_STRING, 'format' => '', 'size' => Database::LENGTH_KEY, 'signed' => true, - 'required' => true, + 'required' => false, 'default' => null, 'array' => false, 'filters' => [], diff --git a/app/config/errors.php b/app/config/errors.php index 1117f20e48..e915091940 100644 --- a/app/config/errors.php +++ b/app/config/errors.php @@ -781,6 +781,11 @@ return [ 'description' => 'Provider with the requested ID is of incorrect type: ', 'code' => 400, ], + Exception::PROVIDER_INTERNAL_UPDATE_DISABLED => [ + 'name' => Exception::PROVIDER_INTERNAL_UPDATE_DISABLED, + 'description' => 'Provider with the requested ID cannot be disabled.', + 'code' => 400, + ], /** Topic Errors */ Exception::TOPIC_NOT_FOUND => [ diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 96c0483cca..77ff2a27e4 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1240,6 +1240,7 @@ App::post('/v1/account/sessions/phone') Query::equal('internal', [true]), Query::equal('type', ['sms']) ])); + if ($provider === false || $provider->isEmpty()) { throw new Exception(Exception::GENERAL_PHONE_DISABLED, 'Phone provider not configured'); } @@ -1335,8 +1336,7 @@ App::post('/v1/account/sessions/phone') $target = $dbForProject->createDocument('targets', new Document([ 'userId' => $user->getId(), 'userInternalId' => $user->getInternalId(), - 'providerId' => $provider->getId(), - 'providerInternalId' => $provider->getInternalId(), + 'providerType' => 'sms', 'identifier' => $phone, ])); } @@ -2959,8 +2959,7 @@ App::post('/v1/account/verification/phone') $target = $dbForProject->createDocument('targets', new Document([ 'userId' => $user->getId(), 'userInternalId' => $user->getInternalId(), - 'providerId' => $provider->getId(), - 'providerInternalId' => $provider->getInternalId(), + 'providerType' => 'sms', 'identifier' => $user->getAttribute('phone'), ])); } diff --git a/app/controllers/api/messaging.php b/app/controllers/api/messaging.php index 2cc9639fbd..f8d0ae16ec 100644 --- a/app/controllers/api/messaging.php +++ b/app/controllers/api/messaging.php @@ -806,14 +806,21 @@ App::patch('/v1/messaging/providers/mailgun/:providerId') ]); } - if ($enabled === true || $enabled === false) { - $provider->setAttribute('enabled', $enabled); - } - if ($internal === true) { $provider->setAttribute('internal', $internal); } + if ($enabled === true || $enabled === false) { + if ($provider->getAttribute('internal') === true && $enabled === false) { + throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + } + if ($provider->getAttribute('internal') === true && $enabled === false) { + throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + } + + $provider->setAttribute('enabled', $enabled); + } + $credentials = $provider->getAttribute('credentials'); if ($isEuRegion === true || $isEuRegion === false) { @@ -893,14 +900,17 @@ App::patch('/v1/messaging/providers/sendgrid/:providerId') ]); } - if ($enabled === true || $enabled === false) { - $provider->setAttribute('enabled', $enabled); - } - if ($internal === true) { $provider->setAttribute('internal', $internal); } + if ($enabled === true || $enabled === false) { + if ($provider->getAttribute('internal') === true && $enabled === false) { + throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + } + $provider->setAttribute('enabled', $enabled); + } + if (!empty($apiKey)) { $provider->setAttribute('credentials', [ 'apiKey' => $apiKey, @@ -971,14 +981,17 @@ App::patch('/v1/messaging/providers/msg91/:providerId') ]); } - if ($enabled === true || $enabled === false) { - $provider->setAttribute('enabled', $enabled); - } - if ($internal === true) { $provider->setAttribute('internal', $internal); } + if ($enabled === true || $enabled === false) { + if ($provider->getAttribute('internal') === true && $enabled === false) { + throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + } + $provider->setAttribute('enabled', $enabled); + } + $credentials = $provider->getAttribute('credentials'); if (!empty($senderId)) { @@ -1055,14 +1068,17 @@ App::patch('/v1/messaging/providers/telesign/:providerId') ]); } - if ($enabled === true || $enabled === false) { - $provider->setAttribute('enabled', $enabled); - } - if ($internal === true) { $provider->setAttribute('internal', $internal); } + if ($enabled === true || $enabled === false) { + if ($provider->getAttribute('internal') === true && $enabled === false) { + throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + } + $provider->setAttribute('enabled', $enabled); + } + $credentials = $provider->getAttribute('credentials'); if (!empty($username)) { @@ -1139,14 +1155,17 @@ App::patch('/v1/messaging/providers/textmagic/:providerId') ]); } - if ($enabled === true || $enabled === false) { - $provider->setAttribute('enabled', $enabled); - } - if ($internal === true) { $provider->setAttribute('internal', $internal); } + if ($enabled === true || $enabled === false) { + if ($provider->getAttribute('internal') === true && $enabled === false) { + throw new Exception(Exception::PROVIDER_INTERNAL_UPDATE_DISABLED); + } + $provider->setAttribute('enabled', $enabled); + } + $credentials = $provider->getAttribute('credentials'); if (!empty($username)) { @@ -1223,14 +1242,17 @@ App::patch('/v1/messaging/providers/twilio/:providerId') ]); } - if ($enabled === true || $enabled === false) { - $provider->setAttribute('enabled', $enabled); - } - if ($internal === true) { $provider->setAttribute('internal', $internal); } + if ($enabled === true || $enabled === false) { + if ($provider->getAttribute('internal') === true && $enabled === false) { + throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + } + $provider->setAttribute('enabled', $enabled); + } + $credentials = $provider->getAttribute('credentials'); if (!empty($accountSid)) { @@ -1307,14 +1329,17 @@ App::patch('/v1/messaging/providers/vonage/:providerId') ]); } - if ($enabled === true || $enabled === false) { - $provider->setAttribute('enabled', $enabled); - } - if ($internal === true) { $provider->setAttribute('internal', $internal); } + if ($enabled === true || $enabled === false) { + if ($provider->getAttribute('internal') === true && $enabled === false) { + throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + } + $provider->setAttribute('enabled', $enabled); + } + $credentials = $provider->getAttribute('credentials'); if (!empty($apiKey)) { @@ -1383,14 +1408,17 @@ App::patch('/v1/messaging/providers/fcm/:providerId') $provider->setAttribute('name', $name); } - if ($enabled === true || $enabled === false) { - $provider->setAttribute('enabled', $enabled); - } - if ($internal === true) { $provider->setAttribute('internal', $internal); } + if ($enabled === true || $enabled === false) { + if ($provider->getAttribute('internal') === true && $enabled === false) { + throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + } + $provider->setAttribute('enabled', $enabled); + } + if (!empty($serverKey)) { $provider->setAttribute('credentials', ['serverKey' => $serverKey]); } @@ -1456,14 +1484,17 @@ App::patch('/v1/messaging/providers/apns/:providerId') $provider->setAttribute('name', $name); } - if ($enabled === true || $enabled === false) { - $provider->setAttribute('enabled', $enabled); - } - if ($internal === true) { $provider->setAttribute('internal', $internal); } + if ($enabled === true || $enabled === false) { + if ($provider->getAttribute('internal') === true && $enabled === false) { + throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + } + $provider->setAttribute('enabled', $enabled); + } + $credentials = $provider->getAttribute('credentials'); if (!empty($authKey)) { diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index a4ad61733f..b19080e894 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -650,8 +650,7 @@ App::post('/v1/teams/:teamId/memberships') $target = $dbForProject->createDocument('targets', new Document([ 'userId' => $invitee->getId(), 'userInternalId' => $invitee->getInternalId(), - 'providerId' => $provider->getId(), - 'providerInternalId' => $provider->getInternalId(), + 'providerType' => 'sms', 'identifier' => $phone, ])); diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 71deded08f..d9968c83a7 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -394,18 +394,25 @@ App::post('/v1/users/:userId/targets') ->label('sdk.response.code', Response::STATUS_CODE_CREATED) ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_TARGET) + ->param('targetId', '', new CustomId(), 'Target ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.') ->param('userId', '', new UID(), 'User ID.') - ->param('targetId', '', new UID(), 'Target ID.') - ->param('providerId', '', new UID(), 'Provider ID.') + ->param('providerType', '', new WhiteList(['email', 'sms', 'push']), 'The target provider type. Can be one of the following: `email`, `sms` or `push`.') ->param('identifier', '', new Text(Database::LENGTH_KEY), 'The target identifier (token, email, phone etc.)') + ->param('providerId', '', new UID(), 'Provider ID. Message will be sent to this target from the specified provider ID. If no provider ID is set the first setup provider will be used.', true) ->inject('queueForEvents') ->inject('response') ->inject('dbForProject') - ->action(function (string $userId, string $targetId, string $providerId, string $identifier, Event $queueForEvents, Response $response, Database $dbForProject) { - $provider = $dbForProject->getDocument('providers', $providerId); + ->action(function (string $targetId, string $userId, string $providerType, string $identifier, string $providerId, Event $queueForEvents, Response $response, Database $dbForProject) { + $targetId = $targetId == 'unique()' ? ID::unique() : $targetId; - if ($provider->isEmpty()) { - throw new Exception(Exception::PROVIDER_NOT_FOUND); + $provider = new Document(); + + if ($providerType === 'push') { + $provider = $dbForProject->getDocument('providers', $providerId); + + if ($provider->isEmpty()) { + throw new Exception(Exception::PROVIDER_NOT_FOUND); + } } $user = $dbForProject->getDocument('users', $userId); @@ -423,8 +430,9 @@ App::post('/v1/users/:userId/targets') try { $target = $dbForProject->createDocument('targets', new Document([ '$id' => $targetId, - 'providerId' => $providerId, - 'providerInternalId' => $provider->getInternalId(), + 'providerId' => $providerId ?? null, + 'providerInternalId' => $provider->getInternalId() ?? null, + 'providerType' => $providerType, 'userId' => $userId, 'userInternalId' => $user->getInternalId(), 'identifier' => $identifier, @@ -1223,8 +1231,8 @@ App::patch('/v1/users/:userId/prefs') $response->dynamic(new Document($prefs), Response::MODEL_PREFERENCES); }); -App::patch('/v1/users/:userId/targets/:targetId/identifier') - ->desc('Update user target\'s identifier') +App::patch('/v1/users/:userId/targets/:targetId') + ->desc('Update User target') ->groups(['api', 'users']) ->label('audits.event', 'target.update') ->label('audits.resource', 'target/{response.$id}') @@ -1232,19 +1240,19 @@ App::patch('/v1/users/:userId/targets/:targetId/identifier') ->label('scope', 'targets.write') ->label('sdk.auth', [APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_ADMIN]) ->label('sdk.namespace', 'users') - ->label('sdk.method', 'updateTargetIdentifier') - ->label('sdk.description', '/docs/references/users/update-target-identifier.md') + ->label('sdk.method', 'updateTarget') + ->label('sdk.description', '/docs/references/users/update-target.md') ->label('sdk.response.code', Response::STATUS_CODE_OK) ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_TARGET) ->param('userId', '', new UID(), 'User ID.') ->param('targetId', '', new UID(), 'Target ID.') - ->param('identifier', '', new Text(Database::LENGTH_KEY), 'The target identifier (token, email, phone etc.)') + ->param('providerId', '', new UID(), 'Provider ID. Message will be sent to this target from the specified provider ID. If no provider ID is set the first setup provider will be used.', true) + ->param('identifier', '', new Text(Database::LENGTH_KEY), 'The target identifier (token, email, phone etc.)', true) ->inject('queueForEvents') ->inject('response') ->inject('dbForProject') - ->action(function (string $userId, string $targetId, string $identifier, Event $queueForEvents, Response $response, Database $dbForProject) { - + ->action(function (string $userId, string $targetId, string $providerId, string $identifier, Event $queueForEvents, Response $response, Database $dbForProject) { $user = $dbForProject->getDocument('users', $userId); if ($user->isEmpty()) { @@ -1261,7 +1269,20 @@ App::patch('/v1/users/:userId/targets/:targetId/identifier') throw new Exception(Exception::USER_TARGET_NOT_FOUND); } - $target->setAttribute('identifier', $identifier); + if ($identifier) { + $target->setAttribute('identifier', $identifier); + } + + if ($providerId) { + $provider = $dbForProject->getDocument('providers', $providerId); + + if ($provider->isEmpty()) { + throw new Exception(Exception::PROVIDER_NOT_FOUND); + } + + $target->setAttribute('providerId', $provider->getId()); + $target->setAttribute('providerInternalId', $provider->getInternalId()); + } $target = $dbForProject->updateDocument('targets', $target->getId(), $target); $dbForProject->deleteCachedDocument('users', $user->getId()); diff --git a/src/Appwrite/Extend/Exception.php b/src/Appwrite/Extend/Exception.php index d887a5a520..b7043a9738 100644 --- a/src/Appwrite/Extend/Exception.php +++ b/src/Appwrite/Extend/Exception.php @@ -236,6 +236,7 @@ class Exception extends \Exception public const PROVIDER_NOT_FOUND = 'provider_not_found'; public const PROVIDER_ALREADY_EXISTS = 'provider_already_exists'; public const PROVIDER_INCORRECT_TYPE = 'provider_incorrect_type'; + public const PROVIDER_INTERNAL_UPDATE_DISABLED = 'provider_internal_update_disabled'; /** Topic */ public const TOPIC_NOT_FOUND = 'topic_not_found'; diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index dcef84c2df..68bae1b4d0 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -98,6 +98,11 @@ class Messaging extends Action $recipients = \array_merge($recipients, $targets); } + $internalProvider = $dbForProject->findOne('providers', [ + Query::equal('internal', [true]), + Query::equal('type', [$recipients[0]->getAttribute('providerType')]), + ]); + /** * @var array> $identifiersByProviderId */ @@ -109,6 +114,11 @@ class Messaging extends Action $providers = []; foreach ($recipients as $recipient) { $providerId = $recipient->getAttribute('providerId'); + + if (!$providerId) { + $providerId = $internalProvider->getId(); + } + if (!isset($identifiersByProviderId[$providerId])) { $identifiersByProviderId[$providerId] = []; } @@ -118,17 +128,26 @@ class Messaging extends Action /** * @var array[] $results */ - $results = batch(\array_map(function ($providerId) use ($identifiersByProviderId, $providers, $message, $dbForProject) { - return function () use ($providerId, $identifiersByProviderId, $providers, $message, $dbForProject) { - $provider = $dbForProject->getDocument('providers', $providerId); + $results = batch(\array_map(function ($providerId) use ($identifiersByProviderId, $providers, $internalProvider, $message, $dbForProject) { + return function () use ($providerId, $identifiersByProviderId, $providers, $internalProvider, $message, $dbForProject) { + $provider = new Document(); + + if ($internalProvider->getId() === $providerId) { + $provider = $internalProvider; + } else { + $provider = $dbForProject->getDocument('providers', $providerId); + } + $providers[] = $provider; $identifiers = $identifiersByProviderId[$providerId]; + $adapter = match ($provider->getAttribute('type')) { 'sms' => $this->sms($provider), 'push' => $this->push($provider), 'email' => $this->email($provider), default => throw new Exception(Exception::PROVIDER_INCORRECT_TYPE) }; + $maxBatchSize = $adapter->getMaxMessagesPerRequest(); $batches = \array_chunk($identifiers, $maxBatchSize); $batchIndex = 0; @@ -139,12 +158,14 @@ class Messaging extends Action $deliveryErrors = []; $messageData = clone $message; $messageData->setAttribute('to', $batch); + $data = match ($provider->getAttribute('type')) { 'sms' => $this->buildSMSMessage($messageData, $provider), 'push' => $this->buildPushMessage($messageData), 'email' => $this->buildEmailMessage($messageData, $provider), default => throw new Exception(Exception::PROVIDER_INCORRECT_TYPE) }; + try { $adapter->send($data); $deliveredTotal += \count($batch); @@ -168,10 +189,12 @@ class Messaging extends Action $deliveredTotal = 0; $deliveryErrors = []; + foreach ($results as $result) { $deliveredTotal += $result['deliveredTotal']; $deliveryErrors = \array_merge($deliveryErrors, $result['deliveryErrors']); } + $message->setAttribute('deliveryErrors', $deliveryErrors); if (\count($message->getAttribute('deliveryErrors')) > 0) { @@ -179,6 +202,7 @@ class Messaging extends Action } else { $message->setAttribute('status', 'sent'); } + $message->removeAttribute('to'); foreach ($providers as $provider) { diff --git a/src/Appwrite/Utopia/Response/Model/Target.php b/src/Appwrite/Utopia/Response/Model/Target.php index c6c5929ee3..f6346f409a 100644 --- a/src/Appwrite/Utopia/Response/Model/Target.php +++ b/src/Appwrite/Utopia/Response/Model/Target.php @@ -41,6 +41,12 @@ class Target extends Model 'default' => '', 'example' => '259125845563242502', ]) + ->addRule('providerType', [ + 'type' => self::TYPE_STRING, + 'description' => 'The target provider type. Can be one of the following: `email`, `sms` or `push`.', + 'default' => '', + 'example' => 'email', + ]) ->addRule('identifier', [ 'type' => self::TYPE_STRING, 'description' => 'The target identifier.', diff --git a/tests/e2e/Services/GraphQL/Base.php b/tests/e2e/Services/GraphQL/Base.php index 93fd6cdc74..b57b680674 100644 --- a/tests/e2e/Services/GraphQL/Base.php +++ b/tests/e2e/Services/GraphQL/Base.php @@ -934,10 +934,11 @@ trait Base } }'; case self::$CREATE_USER_TARGET: - return 'mutation createUserTarget($userId: String!, $targetId: String!, $providerId: String!, $identifier: String!){ - usersCreateTarget(userId: $userId, targetId: $targetId, providerId: $providerId, identifier: $identifier) { + return 'mutation createUserTarget($userId: String!, $targetId: String!, $providerType: String!, $identifier: String! $providerId: String){ + usersCreateTarget(userId: $userId, targetId: $targetId, providerType: $providerType, identifier: $identifier, providerId: $providerId) { _id userId + providerType providerId identifier } @@ -949,6 +950,7 @@ trait Base targets { _id userId + providerType providerId identifier } @@ -959,15 +961,17 @@ trait Base usersGetTarget(userId: $userId, targetId: $targetId) { _id userId + providerType providerId identifier } }'; case self::$UPDATE_USER_TARGET: - return 'mutation updateUserTarget($userId: String!, $targetId: String!, $identifier: String!){ - usersUpdateTargetIdentifier(userId: $userId, targetId: $targetId, identifier: $identifier) { + return 'mutation updateUserTarget($userId: String!, $targetId: String!, $providerId: String, $identifier: String){ + usersUpdateTarget(userId: $userId, targetId: $targetId, providerId: $providerId, identifier: $identifier) { _id userId + providerType providerId identifier } diff --git a/tests/e2e/Services/GraphQL/MessagingTest.php b/tests/e2e/Services/GraphQL/MessagingTest.php index c0322372ba..57ed825a5c 100644 --- a/tests/e2e/Services/GraphQL/MessagingTest.php +++ b/tests/e2e/Services/GraphQL/MessagingTest.php @@ -395,6 +395,7 @@ class MessagingTest extends Scope 'query' => $query, 'variables' => [ 'targetId' => ID::unique(), + 'providerType' => 'email', 'userId' => $userId, 'providerId' => $providerId, 'identifier' => 'token', @@ -604,6 +605,7 @@ class MessagingTest extends Scope 'query' => $query, 'variables' => [ 'targetId' => ID::unique(), + 'providerType' => 'email', 'userId' => $user['body']['data']['usersCreate']['_id'], 'providerId' => $providerId, 'identifier' => $to, @@ -755,6 +757,7 @@ class MessagingTest extends Scope 'query' => $query, 'variables' => [ 'targetId' => ID::unique(), + 'providerType' => 'email', 'userId' => $user['body']['data']['usersCreate']['_id'], 'providerId' => $providerId, 'identifier' => $to, @@ -916,6 +919,7 @@ class MessagingTest extends Scope 'query' => $query, 'variables' => [ 'targetId' => ID::unique(), + 'providerType' => 'sms', 'userId' => $user['body']['data']['usersCreate']['_id'], 'providerId' => $providerId, 'identifier' => $to, @@ -1063,6 +1067,7 @@ class MessagingTest extends Scope 'query' => $query, 'variables' => [ 'targetId' => ID::unique(), + 'providerType' => 'sms', 'userId' => $user['body']['data']['usersCreate']['_id'], 'providerId' => $providerId, 'identifier' => $to, @@ -1219,6 +1224,7 @@ class MessagingTest extends Scope 'query' => $query, 'variables' => [ 'targetId' => ID::unique(), + 'providerType' => 'push', 'userId' => $user['body']['data']['usersCreate']['_id'], 'providerId' => $providerId, 'identifier' => $to, @@ -1363,6 +1369,7 @@ class MessagingTest extends Scope 'query' => $query, 'variables' => [ 'targetId' => ID::unique(), + 'providerType' => 'push', 'userId' => $user['body']['data']['usersCreate']['_id'], 'providerId' => $providerId, 'identifier' => $to, diff --git a/tests/e2e/Services/GraphQL/UsersTest.php b/tests/e2e/Services/GraphQL/UsersTest.php index d750de5834..59c0c4a805 100644 --- a/tests/e2e/Services/GraphQL/UsersTest.php +++ b/tests/e2e/Services/GraphQL/UsersTest.php @@ -78,6 +78,7 @@ class UsersTest extends Scope 'variables' => [ 'targetId' => ID::unique(), 'userId' => $user['_id'], + 'providerType' => 'email', 'providerId' => $providerId, 'identifier' => 'identifier', ] @@ -479,7 +480,7 @@ class UsersTest extends Scope ], $this->getHeaders()), $graphQLPayload); $this->assertEquals(200, $target['headers']['status-code']); - $this->assertEquals('newidentifier', $target['body']['data']['usersUpdateTargetIdentifier']['identifier']); + $this->assertEquals('newidentifier', $target['body']['data']['usersUpdateTarget']['identifier']); } public function testDeleteUserSessions() diff --git a/tests/e2e/Services/Messaging/MessagingBase.php b/tests/e2e/Services/Messaging/MessagingBase.php index 21d22827f0..707ba2f7b5 100644 --- a/tests/e2e/Services/Messaging/MessagingBase.php +++ b/tests/e2e/Services/Messaging/MessagingBase.php @@ -317,6 +317,7 @@ trait MessagingBase 'x-appwrite-key' => $this->getProject()['apiKey'], ]), [ 'targetId' => ID::unique(), + 'providerType' => 'email', 'providerId' => $provider['body']['$id'], 'identifier' => 'my-token', ]); @@ -558,6 +559,7 @@ trait MessagingBase 'isEuRegion' => filter_var($isEuRegion, FILTER_VALIDATE_BOOLEAN), 'from' => $from ]); + $this->assertEquals(201, $provider['headers']['status-code']); // Create Topic @@ -570,6 +572,7 @@ trait MessagingBase 'name' => 'topic1', 'description' => 'Test Topic' ]); + $this->assertEquals(201, $topic['headers']['status-code']); // Create User @@ -593,6 +596,7 @@ trait MessagingBase 'x-appwrite-key' => $this->getProject()['apiKey'], ], [ 'targetId' => ID::unique(), + 'providerType' => 'email', 'providerId' => $provider['body']['$id'], 'identifier' => $to, ]); @@ -682,6 +686,7 @@ trait MessagingBase 'isEuRegion' => filter_var($isEuRegion, FILTER_VALIDATE_BOOLEAN), 'from' => $from ]); + $this->assertEquals(201, $provider['headers']['status-code']); // Create Topic @@ -694,6 +699,7 @@ trait MessagingBase 'name' => 'topic1', 'description' => 'Test Topic' ]); + $this->assertEquals(201, $topic['headers']['status-code']); // Create User @@ -717,6 +723,7 @@ trait MessagingBase 'x-appwrite-key' => $this->getProject()['apiKey'], ], [ 'targetId' => ID::unique(), + 'providerType' => 'email', 'providerId' => $provider['body']['$id'], 'identifier' => $to, ]); @@ -801,6 +808,7 @@ trait MessagingBase 'authKey' => $authKey, 'from' => $from ]); + $this->assertEquals(201, $provider['headers']['status-code']); // Create Topic @@ -813,6 +821,7 @@ trait MessagingBase 'name' => 'topic1', 'description' => 'Test Topic' ]); + $this->assertEquals(201, $topic['headers']['status-code']); // Create User @@ -836,6 +845,7 @@ trait MessagingBase 'x-appwrite-key' => $this->getProject()['apiKey'], ], [ 'targetId' => ID::unique(), + 'providerType' => 'sms', 'providerId' => $provider['body']['$id'], 'identifier' => $to, ]); @@ -922,6 +932,7 @@ trait MessagingBase 'authKey' => $authKey, 'from' => $from ]); + $this->assertEquals(201, $provider['headers']['status-code']); // Create Topic @@ -934,6 +945,7 @@ trait MessagingBase 'name' => 'topic1', 'description' => 'Test Topic' ]); + $this->assertEquals(201, $topic['headers']['status-code']); // Create User @@ -957,6 +969,7 @@ trait MessagingBase 'x-appwrite-key' => $this->getProject()['apiKey'], ], [ 'targetId' => ID::unique(), + 'providerType' => 'sms', 'providerId' => $provider['body']['$id'], 'identifier' => $to, ]); @@ -1036,6 +1049,7 @@ trait MessagingBase 'name' => 'FCM-1', 'serverKey' => $serverKey, ]); + $this->assertEquals(201, $provider['headers']['status-code']); // Create Topic @@ -1048,6 +1062,7 @@ trait MessagingBase 'name' => 'topic1', 'description' => 'Test Topic' ]); + $this->assertEquals(201, $topic['headers']['status-code']); // Create User @@ -1071,6 +1086,7 @@ trait MessagingBase 'x-appwrite-key' => $this->getProject()['apiKey'], ], [ 'targetId' => ID::unique(), + 'providerType' => 'push', 'providerId' => $provider['body']['$id'], 'identifier' => $to, ]); @@ -1154,6 +1170,7 @@ trait MessagingBase 'name' => 'FCM-2', 'serverKey' => $serverKey, ]); + $this->assertEquals(201, $provider['headers']['status-code']); // Create Topic @@ -1166,6 +1183,7 @@ trait MessagingBase 'name' => 'topic1', 'description' => 'Test Topic' ]); + $this->assertEquals(201, $topic['headers']['status-code']); // Create User @@ -1189,6 +1207,7 @@ trait MessagingBase 'x-appwrite-key' => $this->getProject()['apiKey'], ], [ 'targetId' => ID::unique(), + 'providerType' => 'push', 'providerId' => $provider['body']['$id'], 'identifier' => $to, ]); diff --git a/tests/e2e/Services/Users/UsersBase.php b/tests/e2e/Services/Users/UsersBase.php index 9ca00aa5df..c9cb17d7b5 100644 --- a/tests/e2e/Services/Users/UsersBase.php +++ b/tests/e2e/Services/Users/UsersBase.php @@ -1232,7 +1232,7 @@ trait UsersBase 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'providerId' => 'unique()', + 'providerId' => ID::unique(), 'name' => 'Sengrid1', 'apiKey' => 'my-apikey', 'from' => 'from@domain.com', @@ -1244,6 +1244,7 @@ trait UsersBase ], $this->getHeaders()), [ 'targetId' => ID::unique(), 'providerId' => $provider['body']['$id'], + 'providerType' => 'email', 'identifier' => 'my-token', ]); $this->assertEquals(201, $response['headers']['status-code']); @@ -1257,7 +1258,7 @@ trait UsersBase */ public function testUpdateUserTarget(array $data): array { - $response = $this->client->call(Client::METHOD_PATCH, '/users/' . $data['userId'] . '/targets/' . $data['$id'] . '/identifier', array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, '/users/' . $data['userId'] . '/targets/' . $data['$id'], array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -1303,11 +1304,14 @@ trait UsersBase 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); + $this->assertEquals(204, $response['headers']['status-code']); + $response = $this->client->call(Client::METHOD_GET, '/users/' . $data['userId'] . '/targets', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); + $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(0, $response['body']['total']); } From 1870524be5748709bf2b2d2a80f7f224fc2f1069 Mon Sep 17 00:00:00 2001 From: prateek banga Date: Tue, 14 Nov 2023 21:34:17 +0530 Subject: [PATCH 2/5] fixes error name --- app/controllers/api/messaging.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/controllers/api/messaging.php b/app/controllers/api/messaging.php index f8d0ae16ec..dd5ab2bd1a 100644 --- a/app/controllers/api/messaging.php +++ b/app/controllers/api/messaging.php @@ -812,10 +812,10 @@ App::patch('/v1/messaging/providers/mailgun/:providerId') if ($enabled === true || $enabled === false) { if ($provider->getAttribute('internal') === true && $enabled === false) { - throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + throw new Exception(Exception::PROVIDER_INTERNAL_UPDATE_DISABLED); } if ($provider->getAttribute('internal') === true && $enabled === false) { - throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + throw new Exception(Exception::PROVIDER_INTERNAL_UPDATE_DISABLED); } $provider->setAttribute('enabled', $enabled); @@ -906,7 +906,7 @@ App::patch('/v1/messaging/providers/sendgrid/:providerId') if ($enabled === true || $enabled === false) { if ($provider->getAttribute('internal') === true && $enabled === false) { - throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + throw new Exception(Exception::PROVIDER_INTERNAL_UPDATE_DISABLED); } $provider->setAttribute('enabled', $enabled); } @@ -987,7 +987,7 @@ App::patch('/v1/messaging/providers/msg91/:providerId') if ($enabled === true || $enabled === false) { if ($provider->getAttribute('internal') === true && $enabled === false) { - throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + throw new Exception(Exception::PROVIDER_INTERNAL_UPDATE_DISABLED); } $provider->setAttribute('enabled', $enabled); } @@ -1074,7 +1074,7 @@ App::patch('/v1/messaging/providers/telesign/:providerId') if ($enabled === true || $enabled === false) { if ($provider->getAttribute('internal') === true && $enabled === false) { - throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + throw new Exception(Exception::PROVIDER_INTERNAL_UPDATE_DISABLED); } $provider->setAttribute('enabled', $enabled); } @@ -1248,7 +1248,7 @@ App::patch('/v1/messaging/providers/twilio/:providerId') if ($enabled === true || $enabled === false) { if ($provider->getAttribute('internal') === true && $enabled === false) { - throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + throw new Exception(Exception::PROVIDER_INTERNAL_UPDATE_DISABLED); } $provider->setAttribute('enabled', $enabled); } @@ -1335,7 +1335,7 @@ App::patch('/v1/messaging/providers/vonage/:providerId') if ($enabled === true || $enabled === false) { if ($provider->getAttribute('internal') === true && $enabled === false) { - throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + throw new Exception(Exception::PROVIDER_INTERNAL_UPDATE_DISABLED); } $provider->setAttribute('enabled', $enabled); } @@ -1414,7 +1414,7 @@ App::patch('/v1/messaging/providers/fcm/:providerId') if ($enabled === true || $enabled === false) { if ($provider->getAttribute('internal') === true && $enabled === false) { - throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + throw new Exception(Exception::PROVIDER_INTERNAL_UPDATE_DISABLED); } $provider->setAttribute('enabled', $enabled); } @@ -1490,7 +1490,7 @@ App::patch('/v1/messaging/providers/apns/:providerId') if ($enabled === true || $enabled === false) { if ($provider->getAttribute('internal') === true && $enabled === false) { - throw new Exception(Exception::PROVIDER_INTERNAL_DISABLED); + throw new Exception(Exception::PROVIDER_INTERNAL_UPDATE_DISABLED); } $provider->setAttribute('enabled', $enabled); } From adc76c5797c2b456743edffc909feb3ac9405b26 Mon Sep 17 00:00:00 2001 From: prateek banga Date: Tue, 14 Nov 2023 22:46:20 +0530 Subject: [PATCH 3/5] adds target when account is created or email or phone is updated --- app/config/collections.php | 4 +-- app/controllers/api/account.php | 54 +++++++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index bfa8192b74..5571fd57d6 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -1926,9 +1926,9 @@ $commonCollections = [ 'orders' => [], ], [ - '$id' => ID::custom('_key_identifier_providerId'), + '$id' => ID::custom('_key_identifier_userInternalId'), 'type' => Database::INDEX_UNIQUE, - 'attributes' => ['providerId', 'identifier'], + 'attributes' => ['identifier', 'userInternalId'], 'lengths' => [], 'orders' => [], ] diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 77ff2a27e4..8a15432a25 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -147,8 +147,15 @@ App::post('/v1/account') 'search' => implode(' ', [$userId, $email, $name]), 'accessedAt' => DateTime::now(), ]); + $userInternalId = $user->getInternalId(); $user->removeAttribute('$internalId'); Authorization::skip(fn() => $dbForProject->createDocument('users', $user)); + Authorization::skip(fn() => $dbForProject->createDocument('targets', new Document([ + 'userId' => $user->getId(), + 'userInternalId' => $userInternalId, + 'providerType' => 'email', + 'identifier' => $email, + ]))); } catch (Duplicate) { throw new Exception(Exception::USER_ALREADY_EXISTS); } @@ -1329,10 +1336,10 @@ App::post('/v1/account/sessions/phone') $target = $dbForProject->findOne('targets', [ Query::equal('identifier', [$phone]), - Query::equal('providerInternalId', [$provider->getInternalId()]) + Query::equal('userInternalId', [$user->getInternalId()]) ]); - if (!$target) { + if (!$target || $target->isEmpty()) { $target = $dbForProject->createDocument('targets', new Document([ 'userId' => $user->getId(), 'userInternalId' => $user->getInternalId(), @@ -1995,6 +2002,7 @@ App::patch('/v1/account/email') throw new Exception(Exception::USER_INVALID_CREDENTIALS); } + $oldEmail = $user->getAttribute('email'); $email = \strtolower($email); // Makes sure this email is not already used in another identity @@ -2019,8 +2027,23 @@ App::patch('/v1/account/email') ->setAttribute('passwordUpdate', DateTime::now()); } + $target = $dbForProject->findOne('targets', [ + Query::equal('identifier', [$email]), + Query::equal('userInternalId', [$user->getInternalId()]) + ]); + + if ($target && !$target->isEmpty()) { + throw new Exception(Exception::USER_TARGET_ALREADY_EXISTS); + } + + /** + * @var Document $oldTarget + */ + $oldTarget = $user->find('identifier', $oldEmail, 'targets'); + try { $user = $dbForProject->withRequestTimestamp($requestTimestamp, fn () => $dbForProject->updateDocument('users', $user->getId(), $user)); + $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $email)); } catch (Duplicate) { throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS); } @@ -2065,6 +2088,20 @@ App::patch('/v1/account/phone') throw new Exception(Exception::USER_INVALID_CREDENTIALS); } + $target = $dbForProject->findOne('targets', [ + Query::equal('identifier', [$phone]), + Query::equal('userInternalId', [$user->getInternalId()]) + ]); + + if ($target && !$target->isEmpty()) { + throw new Exception(Exception::USER_TARGET_ALREADY_EXISTS); + } + + /** + * @var Document $oldTarget + */ + $oldTarget = $user->find('identifier', $user->getAttribute('phone'), 'targets'); + $user ->setAttribute('phone', $phone) ->setAttribute('phoneVerification', false) // After this user needs to confirm phone number again @@ -2080,6 +2117,7 @@ App::patch('/v1/account/phone') try { $user = $dbForProject->withRequestTimestamp($requestTimestamp, fn () => $dbForProject->updateDocument('users', $user->getId(), $user)); + $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $phone)); } catch (Duplicate $th) { throw new Exception(Exception::USER_PHONE_ALREADY_EXISTS); } @@ -2904,6 +2942,7 @@ App::post('/v1/account/verification/phone') Query::equal('internal', [true]), Query::equal('type', ['sms']) ])); + if ($provider === false || $provider->isEmpty()) { throw new Exception(Exception::GENERAL_PHONE_DISABLED, 'Phone provider not configured'); } @@ -2952,18 +2991,9 @@ App::post('/v1/account/verification/phone') $target = $dbForProject->findOne('targets', [ Query::equal('identifier', [$user->getAttribute('phone')]), - Query::equal('providerInternalId', [$provider->getInternalId()]) + Query::equal('userInternalId', [$user->getInternalId()]) ]); - if (!$target) { - $target = $dbForProject->createDocument('targets', new Document([ - 'userId' => $user->getId(), - 'userInternalId' => $user->getInternalId(), - 'providerType' => 'sms', - 'identifier' => $user->getAttribute('phone'), - ])); - } - $messageDoc = $dbForProject->createDocument('messages', new Document([ '$id' => $verification->getId(), 'targets' => [$target->getId()], From fdca55b0de9d61f72dc8822ce1d9148de464d851 Mon Sep 17 00:00:00 2001 From: prateek banga Date: Wed, 15 Nov 2023 01:24:55 +0530 Subject: [PATCH 4/5] fix test cases --- app/config/collections.php | 9 +- app/controllers/api/account.php | 70 +++- tests/e2e/Services/GraphQL/MessagingTest.php | 318 +----------------- .../e2e/Services/Messaging/MessagingBase.php | 247 +------------- 4 files changed, 66 insertions(+), 578 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index 5571fd57d6..f2ee405c92 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -1920,18 +1920,11 @@ $commonCollections = [ ], [ '$id' => ID::custom('_key_identifier'), - 'type' => Database::INDEX_KEY, + 'type' => Database::INDEX_UNIQUE, 'attributes' => ['identifier'], 'lengths' => [], 'orders' => [], ], - [ - '$id' => ID::custom('_key_identifier_userInternalId'), - 'type' => Database::INDEX_UNIQUE, - 'attributes' => ['identifier', 'userInternalId'], - 'lengths' => [], - 'orders' => [], - ] ], ], ]; diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 8a15432a25..c5e389dd42 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -147,15 +147,21 @@ App::post('/v1/account') 'search' => implode(' ', [$userId, $email, $name]), 'accessedAt' => DateTime::now(), ]); - $userInternalId = $user->getInternalId(); $user->removeAttribute('$internalId'); - Authorization::skip(fn() => $dbForProject->createDocument('users', $user)); - Authorization::skip(fn() => $dbForProject->createDocument('targets', new Document([ + $user = Authorization::skip(fn() => $dbForProject->createDocument('users', $user)); + $target = Authorization::skip(fn() => $dbForProject->createDocument('targets', new Document([ + '$permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::user($userId)), + Permission::delete(Role::user($userId)), + ], 'userId' => $user->getId(), - 'userInternalId' => $userInternalId, + 'userInternalId' => $user->getInternalId(), 'providerType' => 'email', 'identifier' => $email, ]))); + $user->setAttribute('targets', [$target]); + $dbForProject->deleteCachedDocument('users', $user->getId()); } catch (Duplicate) { throw new Exception(Exception::USER_ALREADY_EXISTS); } @@ -663,7 +669,18 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') 'accessedAt' => DateTime::now(), ]); $user->removeAttribute('$internalId'); - Authorization::skip(fn() => $dbForProject->createDocument('users', $user)); + $userDoc = Authorization::skip(fn() => $dbForProject->createDocument('users', $user)); + $dbForProject->createDocument('targets', new Document([ + '$permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::user($user->getId())), + Permission::delete(Role::user($user->getId())), + ], + 'userId' => $userDoc->getId(), + 'userInternalId' => $userDoc->getInternalId(), + 'providerType' => 'email', + 'identifier' => $email, + ])); } catch (Duplicate) { $failureRedirect(Exception::USER_ALREADY_EXISTS); } @@ -1336,16 +1353,21 @@ App::post('/v1/account/sessions/phone') $target = $dbForProject->findOne('targets', [ Query::equal('identifier', [$phone]), - Query::equal('userInternalId', [$user->getInternalId()]) ]); if (!$target || $target->isEmpty()) { $target = $dbForProject->createDocument('targets', new Document([ + '$permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::user($user->getId())), + Permission::delete(Role::user($user->getId())), + ], 'userId' => $user->getId(), 'userInternalId' => $user->getInternalId(), 'providerType' => 'sms', 'identifier' => $phone, ])); + $dbForProject->deleteCachedDocument('users', $user->getId()); } $messageDoc = $dbForProject->createDocument('messages', new Document([ @@ -2029,7 +2051,6 @@ App::patch('/v1/account/email') $target = $dbForProject->findOne('targets', [ Query::equal('identifier', [$email]), - Query::equal('userInternalId', [$user->getInternalId()]) ]); if ($target && !$target->isEmpty()) { @@ -2041,9 +2062,16 @@ App::patch('/v1/account/email') */ $oldTarget = $user->find('identifier', $oldEmail, 'targets'); + if ($oldTarget !== false && !$oldTarget->isEmpty()) { + try { + $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $email)); + } catch (Duplicate) { + throw new Exception(Exception::USER_TARGET_ALREADY_EXISTS); + } + } + try { $user = $dbForProject->withRequestTimestamp($requestTimestamp, fn () => $dbForProject->updateDocument('users', $user->getId(), $user)); - $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $email)); } catch (Duplicate) { throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS); } @@ -2090,7 +2118,6 @@ App::patch('/v1/account/phone') $target = $dbForProject->findOne('targets', [ Query::equal('identifier', [$phone]), - Query::equal('userInternalId', [$user->getInternalId()]) ]); if ($target && !$target->isEmpty()) { @@ -2115,9 +2142,16 @@ App::patch('/v1/account/phone') ->setAttribute('passwordUpdate', DateTime::now()); } + if ($oldTarget !== false && !$oldTarget->isEmpty()) { + try { + $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $phone)); + } catch (Duplicate) { + throw new Exception(Exception::USER_TARGET_ALREADY_EXISTS); + } + } + try { $user = $dbForProject->withRequestTimestamp($requestTimestamp, fn () => $dbForProject->updateDocument('users', $user->getId(), $user)); - $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $phone)); } catch (Duplicate $th) { throw new Exception(Exception::USER_PHONE_ALREADY_EXISTS); } @@ -2991,9 +3025,23 @@ App::post('/v1/account/verification/phone') $target = $dbForProject->findOne('targets', [ Query::equal('identifier', [$user->getAttribute('phone')]), - Query::equal('userInternalId', [$user->getInternalId()]) ]); + if (!$target || $target->isEmpty()) { + $target = $dbForProject->createDocument('targets', new Document([ + '$permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::user($user->getId())), + Permission::delete(Role::user($user->getId())), + ], + 'userId' => $user->getId(), + 'userInternalId' => $user->getInternalId(), + 'providerType' => 'sms', + 'identifier' => $user->getAttribute('phone'), + ])); + $dbForProject->deleteCachedDocument('users', $user->getId()); + } + $messageDoc = $dbForProject->createDocument('messages', new Document([ '$id' => $verification->getId(), 'targets' => [$target->getId()], diff --git a/tests/e2e/Services/GraphQL/MessagingTest.php b/tests/e2e/Services/GraphQL/MessagingTest.php index 57ed825a5c..112e9e5633 100644 --- a/tests/e2e/Services/GraphQL/MessagingTest.php +++ b/tests/e2e/Services/GraphQL/MessagingTest.php @@ -680,120 +680,13 @@ class MessagingTest extends Scope */ public function testUpdateEmail(array $email) { - if (empty(App::getEnv('_APP_MESSAGE_EMAIL_TEST_DSN'))) { - $this->markTestSkipped('Email DSN not provided'); - } - - $emailDSN = new DSN(App::getEnv('_APP_MESSAGE_EMAIL_TEST_DSN')); - $to = $emailDSN->getParam('to'); - $from = $emailDSN->getParam('from'); - $isEuRegion = $emailDSN->getParam('isEuRegion'); - $apiKey = $emailDSN->getPassword(); - $domain = $emailDSN->getUser(); - - if (empty($to) || empty($from) || empty($apiKey) || empty($domain) || empty($isEuRegion)) { - $this->markTestSkipped('Email provider not configured'); - } - - $query = $this->getQuery(self::$CREATE_MAILGUN_PROVIDER); - $graphQLPayload = [ - 'query' => $query, - 'variables' => [ - 'providerId' => ID::unique(), - 'name' => 'Mailgun2', - 'apiKey' => $apiKey, - 'domain' => $domain, - 'from' => $from, - 'isEuRegion' => filter_var($isEuRegion, FILTER_VALIDATE_BOOLEAN), - ], - ]; - $provider = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), $graphQLPayload); - - $this->assertEquals(200, $provider['headers']['status-code']); - - $providerId = $provider['body']['data']['messagingCreateMailgunProvider']['_id']; - - $query = $this->getQuery(self::$CREATE_TOPIC); - $graphQLPayload = [ - 'query' => $query, - 'variables' => [ - 'topicId' => ID::unique(), - 'name' => 'topic1', - 'description' => 'Active users', - ], - ]; - $topic = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), $graphQLPayload); - - $this->assertEquals(200, $topic['headers']['status-code']); - - $query = $this->getQuery(self::$CREATE_USER); - $graphQLPayload = [ - 'query' => $query, - 'variables' => [ - 'userId' => ID::unique(), - 'email' => 'random2-mail@mail.org', - 'password' => 'password', - 'name' => 'Messaging User', - ] - ]; - $user = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), $graphQLPayload); - - $this->assertEquals(200, $user['headers']['status-code']); - - $query = $this->getQuery(self::$CREATE_USER_TARGET); - $graphQLPayload = [ - 'query' => $query, - 'variables' => [ - 'targetId' => ID::unique(), - 'providerType' => 'email', - 'userId' => $user['body']['data']['usersCreate']['_id'], - 'providerId' => $providerId, - 'identifier' => $to, - ], - ]; - $target = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), $graphQLPayload); - - $this->assertEquals(200, $target['headers']['status-code']); - - $query = $this->getQuery(self::$CREATE_SUBSCRIBER); - $graphQLPayload = [ - 'query' => $query, - 'variables' => [ - 'subscriberId' => ID::unique(), - 'topicId' => $topic['body']['data']['messagingCreateTopic']['_id'], - 'targetId' => $target['body']['data']['usersCreateTarget']['_id'], - ], - ]; - $subscriber = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), $graphQLPayload); - - $this->assertEquals(200, $subscriber['headers']['status-code']); - $query = $this->getQuery(self::$CREATE_EMAIL); $graphQLPayload = [ 'query' => $query, 'variables' => [ 'messageId' => ID::unique(), 'status' => 'draft', - 'topics' => [$topic['body']['data']['messagingCreateTopic']['_id']], + 'topics' => [$email['topics'][0]], 'subject' => 'Khali beats Undertaker', 'content' => 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', ], @@ -992,118 +885,13 @@ class MessagingTest extends Scope */ public function testUpdateSMS(array $sms) { - if (empty(App::getEnv('_APP_MESSAGE_SMS_TEST_DSN'))) { - $this->markTestSkipped('SMS DSN not provided'); - } - - $smsDSN = new DSN(App::getEnv('_APP_MESSAGE_SMS_TEST_DSN')); - $to = $smsDSN->getParam('to'); - $from = $smsDSN->getParam('from'); - $authKey = $smsDSN->getPassword(); - $senderId = $smsDSN->getUser(); - - if (empty($to) || empty($from) || empty($senderId) || empty($authKey)) { - $this->markTestSkipped('SMS provider not configured'); - } - - $query = $this->getQuery(self::$CREATE_MSG91_PROVIDER); - $graphQLPayload = [ - 'query' => $query, - 'variables' => [ - 'providerId' => ID::unique(), - 'name' => 'Msg91-2', - 'senderId' => $senderId, - 'authKey' => $authKey, - 'from' => $from, - ], - ]; - $provider = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), $graphQLPayload); - - $this->assertEquals(200, $provider['headers']['status-code']); - - $providerId = $provider['body']['data']['messagingCreateMsg91Provider']['_id']; - - $query = $this->getQuery(self::$CREATE_TOPIC); - $graphQLPayload = [ - 'query' => $query, - 'variables' => [ - 'topicId' => ID::unique(), - 'name' => 'topic1', - 'description' => 'Active users', - ], - ]; - $topic = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), $graphQLPayload); - - $this->assertEquals(200, $topic['headers']['status-code']); - - $query = $this->getQuery(self::$CREATE_USER); - $graphQLPayload = [ - 'query' => $query, - 'variables' => [ - 'userId' => ID::unique(), - 'email' => 'random4-email@mail.org', - 'password' => 'password', - 'name' => 'Messaging User', - ] - ]; - $user = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), $graphQLPayload); - - $this->assertEquals(200, $user['headers']['status-code']); - - $query = $this->getQuery(self::$CREATE_USER_TARGET); - $graphQLPayload = [ - 'query' => $query, - 'variables' => [ - 'targetId' => ID::unique(), - 'providerType' => 'sms', - 'userId' => $user['body']['data']['usersCreate']['_id'], - 'providerId' => $providerId, - 'identifier' => $to, - ], - ]; - $target = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), $graphQLPayload); - - $this->assertEquals(200, $target['headers']['status-code']); - - $query = $this->getQuery(self::$CREATE_SUBSCRIBER); - $graphQLPayload = [ - 'query' => $query, - 'variables' => [ - 'subscriberId' => ID::unique(), - 'topicId' => $topic['body']['data']['messagingCreateTopic']['_id'], - 'targetId' => $target['body']['data']['usersCreateTarget']['_id'], - ], - ]; - $subscriber = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), $graphQLPayload); - - $this->assertEquals(200, $subscriber['headers']['status-code']); - $query = $this->getQuery(self::$CREATE_SMS); $graphQLPayload = [ 'query' => $query, 'variables' => [ 'messageId' => ID::unique(), 'status' => 'draft', - 'topics' => [$topic['body']['data']['messagingCreateTopic']['_id']], + 'topics' => [$sms['topics'][0]], 'content' => '345463', ], ]; @@ -1299,113 +1087,13 @@ class MessagingTest extends Scope */ public function testUpdatePushNotification(array $push) { - if (empty(App::getEnv('_APP_MESSAGE_PUSH_TEST_DSN'))) { - $this->markTestSkipped('Push DSN empty'); - } - - $pushDSN = new DSN(App::getEnv('_APP_MESSAGE_PUSH_TEST_DSN')); - $to = $pushDSN->getParam('to'); - $serverKey = $pushDSN->getPassword(); - - if (empty($to) || empty($serverKey)) { - $this->markTestSkipped('Push provider not configured'); - } - - $query = $this->getQuery(self::$CREATE_FCM_PROVIDER); - $graphQLPayload = [ - 'query' => $query, - 'variables' => [ - 'providerId' => ID::unique(), - 'name' => 'FCM2', - 'serverKey' => $serverKey, - ], - ]; - $provider = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), $graphQLPayload); - - $this->assertEquals(200, $provider['headers']['status-code']); - $providerId = $provider['body']['data']['messagingCreateFcmProvider']['_id']; - - $query = $this->getQuery(self::$CREATE_TOPIC); - $graphQLPayload = [ - 'query' => $query, - 'variables' => [ - 'topicId' => ID::unique(), - 'name' => 'topic1', - 'description' => 'Active users', - ], - ]; - $topic = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), $graphQLPayload); - - $this->assertEquals(200, $topic['headers']['status-code']); - - $query = $this->getQuery(self::$CREATE_USER); - $graphQLPayload = [ - 'query' => $query, - 'variables' => [ - 'userId' => ID::unique(), - 'email' => 'random5-email@mail.org', - 'password' => 'password', - 'name' => 'Messaging User', - ] - ]; - $user = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), $graphQLPayload); - - $this->assertEquals(200, $user['headers']['status-code']); - - $query = $this->getQuery(self::$CREATE_USER_TARGET); - $graphQLPayload = [ - 'query' => $query, - 'variables' => [ - 'targetId' => ID::unique(), - 'providerType' => 'push', - 'userId' => $user['body']['data']['usersCreate']['_id'], - 'providerId' => $providerId, - 'identifier' => $to, - ], - ]; - $target = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), $graphQLPayload); - - $this->assertEquals(200, $target['headers']['status-code']); - - $query = $this->getQuery(self::$CREATE_SUBSCRIBER); - $graphQLPayload = [ - 'query' => $query, - 'variables' => [ - 'subscriberId' => ID::unique(), - 'topicId' => $topic['body']['data']['messagingCreateTopic']['_id'], - 'targetId' => $target['body']['data']['usersCreateTarget']['_id'], - ], - ]; - $subscriber = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), $graphQLPayload); - - $this->assertEquals(200, $subscriber['headers']['status-code']); - $query = $this->getQuery(self::$CREATE_PUSH_NOTIFICATION); $graphQLPayload = [ 'query' => $query, 'variables' => [ 'messageId' => ID::unique(), 'status' => 'draft', - 'topics' => [$topic['body']['data']['messagingCreateTopic']['_id']], + 'topics' => [$push['topics'][0]], 'title' => 'Push Notification Title', 'body' => 'Push Notifiaction Body', ], diff --git a/tests/e2e/Services/Messaging/MessagingBase.php b/tests/e2e/Services/Messaging/MessagingBase.php index 707ba2f7b5..daafd52e8f 100644 --- a/tests/e2e/Services/Messaging/MessagingBase.php +++ b/tests/e2e/Services/Messaging/MessagingBase.php @@ -649,21 +649,6 @@ trait MessagingBase */ public function testUpdateEmail(array $email) { - if (empty(App::getEnv('_APP_MESSAGE_EMAIL_TEST_DSN'))) { - $this->markTestSkipped('Email DSN not provided'); - } - - $emailDSN = new DSN(App::getEnv('_APP_MESSAGE_EMAIL_TEST_DSN')); - $to = $emailDSN->getParam('to'); - $from = $emailDSN->getParam('from'); - $isEuRegion = $emailDSN->getParam('isEuRegion'); - $apiKey = $emailDSN->getPassword(); - $domain = $emailDSN->getUser(); - - if (empty($to) || empty($from) || empty($apiKey) || empty($domain) || empty($isEuRegion)) { - $this->markTestSkipped('Email provider not configured'); - } - $message = $this->client->call(Client::METHOD_PATCH, '/messaging/messages/email/' . $email['body']['$id'], [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -673,74 +658,6 @@ trait MessagingBase // Test failure as the message has already been sent. $this->assertEquals(400, $message['headers']['status-code']); - // Create provider - $provider = $this->client->call(Client::METHOD_POST, '/messaging/providers/mailgun', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), [ - 'providerId' => ID::unique(), - 'name' => 'Mailgun-provider-2', - 'apiKey' => $apiKey, - 'domain' => $domain, - 'isEuRegion' => filter_var($isEuRegion, FILTER_VALIDATE_BOOLEAN), - 'from' => $from - ]); - - $this->assertEquals(201, $provider['headers']['status-code']); - - // Create Topic - $topic = $this->client->call(Client::METHOD_POST, '/messaging/topics', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ - 'topicId' => ID::unique(), - 'name' => 'topic1', - 'description' => 'Test Topic' - ]); - - $this->assertEquals(201, $topic['headers']['status-code']); - - // Create User - $user = $this->client->call(Client::METHOD_POST, '/users', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ - 'userId' => ID::unique(), - 'email' => 'random-email@mail.org', - 'password' => 'password', - 'name' => 'Messaging User', - ]); - - $this->assertEquals(201, $user['headers']['status-code']); - - // Create Target - $target = $this->client->call(Client::METHOD_POST, '/users/' . $user['body']['$id'] . '/targets', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ - 'targetId' => ID::unique(), - 'providerType' => 'email', - 'providerId' => $provider['body']['$id'], - 'identifier' => $to, - ]); - - $this->assertEquals(201, $target['headers']['status-code']); - - // Create Subscriber - $subscriber = $this->client->call(Client::METHOD_POST, '/messaging/topics/' . $topic['body']['$id'] . '/subscribers', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'subscriberId' => ID::unique(), - 'targetId' => $target['body']['$id'], - ]); - - $this->assertEquals(201, $subscriber['headers']['status-code']); - // Create Email $email = $this->client->call(Client::METHOD_POST, '/messaging/messages/email', [ 'content-type' => 'application/json', @@ -749,7 +666,7 @@ trait MessagingBase ], [ 'messageId' => ID::unique(), 'status' => 'draft', - 'topics' => [$topic['body']['$id']], + 'topics' => [$email['body']['topics'][0]], 'subject' => 'Khali beats Undertaker', 'content' => 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', ]); @@ -897,20 +814,6 @@ trait MessagingBase */ public function testUpdateSMS(array $sms) { - if (empty(App::getEnv('_APP_MESSAGE_SMS_TEST_DSN'))) { - $this->markTestSkipped('SMS DSN not provided'); - } - - $smsDSN = new DSN(App::getEnv('_APP_MESSAGE_SMS_TEST_DSN')); - $to = $smsDSN->getParam('to'); - $from = $smsDSN->getParam('from'); - $authKey = $smsDSN->getPassword(); - $senderId = $smsDSN->getUser(); - - if (empty($to) || empty($from) || empty($senderId) || empty($authKey)) { - $this->markTestSkipped('SMS provider not configured'); - } - $message = $this->client->call(Client::METHOD_PATCH, '/messaging/messages/sms/' . $sms['body']['$id'], [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -920,73 +823,6 @@ trait MessagingBase // Test failure as the message has already been sent. $this->assertEquals(400, $message['headers']['status-code']); - // Create provider - $provider = $this->client->call(Client::METHOD_POST, '/messaging/providers/msg91', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), [ - 'providerId' => ID::unique(), - 'name' => 'Msg91-2', - 'senderId' => $senderId, - 'authKey' => $authKey, - 'from' => $from - ]); - - $this->assertEquals(201, $provider['headers']['status-code']); - - // Create Topic - $topic = $this->client->call(Client::METHOD_POST, '/messaging/topics', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ - 'topicId' => ID::unique(), - 'name' => 'topic1', - 'description' => 'Test Topic' - ]); - - $this->assertEquals(201, $topic['headers']['status-code']); - - // Create User - $user = $this->client->call(Client::METHOD_POST, '/users', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ - 'userId' => ID::unique(), - 'email' => 'random2-email@mail.org', - 'password' => 'password', - 'name' => 'Messaging User', - ]); - - $this->assertEquals(201, $user['headers']['status-code']); - - // Create Target - $target = $this->client->call(Client::METHOD_POST, '/users/' . $user['body']['$id'] . '/targets', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ - 'targetId' => ID::unique(), - 'providerType' => 'sms', - 'providerId' => $provider['body']['$id'], - 'identifier' => $to, - ]); - - $this->assertEquals(201, $target['headers']['status-code']); - - // Create Subscriber - $subscriber = $this->client->call(Client::METHOD_POST, '/messaging/topics/' . $topic['body']['$id'] . '/subscribers', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'subscriberId' => ID::unique(), - 'targetId' => $target['body']['$id'], - ]); - - $this->assertEquals(201, $subscriber['headers']['status-code']); - // Create SMS $sms = $this->client->call(Client::METHOD_POST, '/messaging/messages/sms', [ 'content-type' => 'application/json', @@ -995,7 +831,7 @@ trait MessagingBase ], [ 'messageId' => ID::unique(), 'status' => 'draft', - 'topics' => [$topic['body']['$id']], + 'topics' => [$sms['body']['topics'][0]], 'content' => '047487', ]); @@ -1139,18 +975,6 @@ trait MessagingBase */ public function testUpdatePushNotification(array $push) { - if (empty(App::getEnv('_APP_MESSAGE_PUSH_TEST_DSN'))) { - $this->markTestSkipped('Push DSN empty'); - } - - $pushDSN = new DSN(App::getEnv('_APP_MESSAGE_PUSH_TEST_DSN')); - $to = $pushDSN->getParam('to'); - $serverKey = $pushDSN->getPassword(); - - if (empty($to) || empty($serverKey)) { - $this->markTestSkipped('Push provider not configured'); - } - $message = $this->client->call(Client::METHOD_PATCH, '/messaging/messages/push/' . $push['body']['$id'], [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -1160,71 +984,6 @@ trait MessagingBase // Test failure as the message has already been sent. $this->assertEquals(400, $message['headers']['status-code']); - // Create provider - $provider = $this->client->call(Client::METHOD_POST, '/messaging/providers/fcm', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), [ - 'providerId' => ID::unique(), - 'name' => 'FCM-2', - 'serverKey' => $serverKey, - ]); - - $this->assertEquals(201, $provider['headers']['status-code']); - - // Create Topic - $topic = $this->client->call(Client::METHOD_POST, '/messaging/topics', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ - 'topicId' => ID::unique(), - 'name' => 'topic1', - 'description' => 'Test Topic' - ]); - - $this->assertEquals(201, $topic['headers']['status-code']); - - // Create User - $user = $this->client->call(Client::METHOD_POST, '/users', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ - 'userId' => ID::unique(), - 'email' => 'random4-email@mail.org', - 'password' => 'password', - 'name' => 'Messaging User', - ]); - - $this->assertEquals(201, $user['headers']['status-code']); - - // Create Target - $target = $this->client->call(Client::METHOD_POST, '/users/' . $user['body']['$id'] . '/targets', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ - 'targetId' => ID::unique(), - 'providerType' => 'push', - 'providerId' => $provider['body']['$id'], - 'identifier' => $to, - ]); - - $this->assertEquals(201, $target['headers']['status-code']); - - // Create Subscriber - $subscriber = $this->client->call(Client::METHOD_POST, '/messaging/topics/' . $topic['body']['$id'] . '/subscribers', \array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'subscriberId' => ID::unique(), - 'targetId' => $target['body']['$id'], - ]); - - $this->assertEquals(201, $subscriber['headers']['status-code']); - // Create push notification $push = $this->client->call(Client::METHOD_POST, '/messaging/messages/push', [ 'content-type' => 'application/json', @@ -1233,7 +992,7 @@ trait MessagingBase ], [ 'messageId' => ID::unique(), 'status' => 'draft', - 'topics' => [$topic['body']['$id']], + 'topics' => [$push['body']['topics'][0]], 'title' => 'Test-Notification', 'body' => 'Test-Notification-Body', ]); From 2aa8391c5e2bc37228ba016a5924b32ed9017efb Mon Sep 17 00:00:00 2001 From: prateek banga Date: Wed, 15 Nov 2023 12:52:27 +0530 Subject: [PATCH 5/5] review fixes --- app/controllers/api/account.php | 12 ++---------- app/controllers/api/messaging.php | 4 ---- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index c5e389dd42..1d6780f48b 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -2063,11 +2063,7 @@ App::patch('/v1/account/email') $oldTarget = $user->find('identifier', $oldEmail, 'targets'); if ($oldTarget !== false && !$oldTarget->isEmpty()) { - try { - $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $email)); - } catch (Duplicate) { - throw new Exception(Exception::USER_TARGET_ALREADY_EXISTS); - } + $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $email)); } try { @@ -2143,11 +2139,7 @@ App::patch('/v1/account/phone') } if ($oldTarget !== false && !$oldTarget->isEmpty()) { - try { - $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $phone)); - } catch (Duplicate) { - throw new Exception(Exception::USER_TARGET_ALREADY_EXISTS); - } + $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $phone)); } try { diff --git a/app/controllers/api/messaging.php b/app/controllers/api/messaging.php index dd5ab2bd1a..1f4f7b62b6 100644 --- a/app/controllers/api/messaging.php +++ b/app/controllers/api/messaging.php @@ -814,10 +814,6 @@ App::patch('/v1/messaging/providers/mailgun/:providerId') if ($provider->getAttribute('internal') === true && $enabled === false) { throw new Exception(Exception::PROVIDER_INTERNAL_UPDATE_DISABLED); } - if ($provider->getAttribute('internal') === true && $enabled === false) { - throw new Exception(Exception::PROVIDER_INTERNAL_UPDATE_DISABLED); - } - $provider->setAttribute('enabled', $enabled); }