diff --git a/app/controllers/api/messaging.php b/app/controllers/api/messaging.php index 352b084b90..258c193a52 100644 --- a/app/controllers/api/messaging.php +++ b/app/controllers/api/messaging.php @@ -35,6 +35,7 @@ use Utopia\Validator\ArrayList; use Utopia\Validator\Boolean; use Utopia\Validator\Integer; use Utopia\Validator\JSON; +use Utopia\Validator\Range; use Utopia\Validator\Text; use MaxMind\Db\Reader; use Utopia\Database\DateTime; @@ -61,30 +62,20 @@ App::post('/v1/messaging/providers/mailgun') ->param('apiKey', '', new Text(0), 'Mailgun API Key.', true) ->param('domain', '', new Text(0), 'Mailgun Domain.', true) ->param('isEuRegion', null, new Boolean(), 'Set as EU region.', true) - ->param('enabled', null, new Boolean(), 'Set as enabled.', true) ->param('fromName', '', new Text(128, 0), 'Sender Name.', true) ->param('fromEmail', '', new Email(), 'Sender email address.', true) ->param('replyToName', '', new Text(128, 0), 'Name set in the reply to field for the mail. Default value is sender name. Reply to name must have reply to email as well.', true) ->param('replyToEmail', '', new Email(), 'Email set in the reply to field for the mail. Default value is sender email. Reply to email must have reply to name as well.', true) + ->param('enabled', null, new Boolean(), 'Set as enabled.', true) ->inject('queueForEvents') ->inject('dbForProject') ->inject('response') - ->action(function (string $providerId, string $name, string $apiKey, string $domain, ?bool $isEuRegion, ?bool $enabled, string $fromName, string $fromEmail, string $replyToName, string $replyToEmail, Event $queueForEvents, Database $dbForProject, Response $response) { + ->action(function (string $providerId, string $name, string $apiKey, string $domain, ?bool $isEuRegion, string $fromName, string $fromEmail, string $replyToName, string $replyToEmail, ?bool $enabled, Event $queueForEvents, Database $dbForProject, Response $response) { $providerId = $providerId == 'unique()' ? ID::unique() : $providerId; - $options = [ - 'fromName' => $fromName, - 'fromEmail' => $fromEmail, - ]; - - if (!empty($replyToName) && !empty($replyToEmail)) { - $options['replyToName'] = $replyToName; - $options['replyToEmail'] = $replyToEmail; - } - $credentials = []; - if ($isEuRegion === true || $isEuRegion === false) { + if (!\is_null($isEuRegion)) { $credentials['isEuRegion'] = $isEuRegion; } @@ -96,12 +87,19 @@ App::post('/v1/messaging/providers/mailgun') $credentials['domain'] = $domain; } + $options = [ + 'fromName' => $fromName, + 'fromEmail' => $fromEmail, + 'replyToName' => $replyToName, + 'replyToEmail' => $replyToEmail, + ]; + if ( - $enabled === true && - \array_key_exists('isEuRegion', $credentials) && - \array_key_exists('apiKey', $credentials) && - \array_key_exists('domain', $credentials) && - \array_key_exists('fromEmail', $options) + $enabled === true + && !empty($fromEmail) + && \array_key_exists('isEuRegion', $credentials) + && \array_key_exists('apiKey', $credentials) + && \array_key_exists('domain', $credentials) ) { $enabled = true; } else { @@ -149,37 +147,34 @@ App::post('/v1/messaging/providers/sendgrid') ->param('providerId', '', new CustomId(), 'Provider 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('name', '', new Text(128), 'Provider name.') ->param('apiKey', '', new Text(0), 'Sendgrid API key.', true) - ->param('enabled', null, new Boolean(), 'Set as enabled.', true) ->param('fromName', '', new Text(128, 0), 'Sender Name.', true) ->param('fromEmail', '', new Email(), 'Sender email address.', true) ->param('replyToName', '', new Text(128, 0), 'Name set in the reply to field for the mail. Default value is sender name.', true) ->param('replyToEmail', '', new Email(), 'Email set in the reply to field for the mail. Default value is sender email.', true) + ->param('enabled', null, new Boolean(), 'Set as enabled.', true) ->inject('queueForEvents') ->inject('dbForProject') ->inject('response') - ->action(function (string $providerId, string $name, string $apiKey, ?bool $enabled, string $fromName, string $fromEmail, string $replyToName, string $replyToEmail, Event $queueForEvents, Database $dbForProject, Response $response) { + ->action(function (string $providerId, string $name, string $apiKey, string $fromName, string $fromEmail, string $replyToName, string $replyToEmail, ?bool $enabled, Event $queueForEvents, Database $dbForProject, Response $response) { $providerId = $providerId == 'unique()' ? ID::unique() : $providerId; - $options = [ - 'fromName' => $fromName, - 'fromEmail' => $fromEmail, - ]; - - if (!empty($replyToName) && !empty($replyToEmail)) { - $options['replyToName'] = $replyToName; - $options['replyToEmail'] = $replyToEmail; - } - $credentials = []; if (!empty($apiKey)) { $credentials['apiKey'] = $apiKey; } + $options = [ + 'fromName' => $fromName, + 'fromEmail' => $fromEmail, + 'replyToName' => $replyToName, + 'replyToEmail' => $replyToEmail, + ]; + if ( $enabled === true + && !empty($fromEmail) && \array_key_exists('apiKey', $credentials) - && \array_key_exists('fromEmail', $options) ) { $enabled = true; } else { @@ -210,6 +205,94 @@ App::post('/v1/messaging/providers/sendgrid') ->dynamic($provider, Response::MODEL_PROVIDER); }); +App::post('/v1/messaging/providers/smtp') + ->desc('Create SMTP provider') + ->groups(['api', 'messaging']) + ->label('audits.event', 'provider.create') + ->label('audits.resource', 'provider/{response.$id}') + ->label('event', 'providers.[providerId].create') + ->label('scope', 'providers.write') + ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) + ->label('sdk.namespace', 'messaging') + ->label('sdk.method', 'createSMTPProvider') + ->label('sdk.description', '/docs/references/messaging/create-smtp-provider.md') + ->label('sdk.response.code', Response::STATUS_CODE_CREATED) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_PROVIDER) + ->param('providerId', '', new CustomId(), 'Provider 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('name', '', new Text(128), 'Provider name.') + ->param('host', '', new Text(0), 'SMTP hosts. Either a single hostname or multiple semicolon-delimited hostnames. You can also specify a different port for each host by using this format: [hostname:port] (e.g. "smtp1.example.com:25;smtp2.example.com"). You can also specify encryption type, for example: (e.g. "tls://smtp1.example.com:587;ssl://smtp2.example.com:465"). Hosts will be tried in order.') + ->param('port', 587, new Range(1, 65535), 'The default SMTP server port.', true) + ->param('username', '', new Text(0), 'Authentication username.', true) + ->param('password', '', new Text(0), 'Authentication password.', true) + ->param('encryption', '', new WhiteList(['none', 'ssl', 'tls']), 'Encryption type. Can be omitted, \'ssl\', or \'tls\'', true) + ->param('autoTLS', true, new Boolean(), 'Enable SMTP AutoTLS feature.', true) + ->param('mailer', '', new Text(0), 'The value to use for the X-Mailer header.', true) + ->param('fromName', '', new Text(128, 0), 'Sender Name.', true) + ->param('fromEmail', '', new Email(), 'Sender email address.', true) + ->param('replyToName', '', new Text(128, 0), 'Name set in the reply to field for the mail. Default value is sender name.', true) + ->param('replyToEmail', '', new Email(), 'Email set in the reply to field for the mail. Default value is sender email.', true) + ->param('enabled', null, new Boolean(), 'Set as enabled.', true) + ->inject('queueForEvents') + ->inject('dbForProject') + ->inject('response') + ->action(function (string $providerId, string $name, string $host, int $port, string $username, string $password, string $encryption, bool $autoTLS, string $mailer, string $fromName, string $fromEmail, string $replyToName, string $replyToEmail, ?bool $enabled, Event $queueForEvents, Database $dbForProject, Response $response) { + $providerId = $providerId == 'unique()' ? ID::unique() : $providerId; + + $credentials = [ + 'port' => $port, + 'username' => $username, + 'password' => $password, + ]; + + if (!empty($host)) { + $credentials['host'] = $host; + } + + $options = [ + 'fromName' => $fromName, + 'fromEmail' => $fromEmail, + 'replyToName' => $replyToName, + 'replyToEmail' => $replyToEmail, + 'encryption' => $encryption === 'none' ? '' : $encryption, + 'autoTLS' => $autoTLS, + 'mailer' => $mailer, + ]; + + if ( + $enabled === true + && !empty($fromEmail) + && \array_key_exists('host', $credentials) + ) { + $enabled = true; + } else { + $enabled = false; + } + + $provider = new Document([ + '$id' => $providerId, + 'name' => $name, + 'provider' => 'smtp', + 'type' => MESSAGE_TYPE_EMAIL, + 'enabled' => $enabled, + 'credentials' => $credentials, + 'options' => $options, + ]); + + try { + $provider = $dbForProject->createDocument('providers', $provider); + } catch (DuplicateException) { + throw new Exception(Exception::PROVIDER_ALREADY_EXISTS); + } + + $queueForEvents + ->setParam('providerId', $provider->getId()); + + $response + ->setStatusCode(Response::STATUS_CODE_CREATED) + ->dynamic($provider, Response::MODEL_PROVIDER); + }); + App::post('/v1/messaging/providers/msg91') ->desc('Create Msg91 provider') ->groups(['api', 'messaging']) @@ -1085,6 +1168,125 @@ App::patch('/v1/messaging/providers/sendgrid/:providerId') ->dynamic($provider, Response::MODEL_PROVIDER); }); +App::patch('/v1/messaging/providers/smtp/:providerId') + ->desc('Update SMTP provider') + ->groups(['api', 'messaging']) + ->label('audits.event', 'provider.update') + ->label('audits.resource', 'provider/{response.$id}') + ->label('event', 'providers.[providerId].update') + ->label('scope', 'providers.write') + ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) + ->label('sdk.namespace', 'messaging') + ->label('sdk.method', 'updateSMTPProvider') + ->label('sdk.description', '/docs/references/messaging/update-smtp-provider.md') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_PROVIDER) + ->param('providerId', '', new UID(), 'Provider ID.') + ->param('name', '', new Text(128), 'Provider name.', true) + ->param('host', '', new Text(0), 'SMTP hosts. Either a single hostname or multiple semicolon-delimited hostnames. You can also specify a different port for each host by using this format: [hostname:port] (e.g. "smtp1.example.com:25;smtp2.example.com"). You can also specify encryption type, for example: (e.g. "tls://smtp1.example.com:587;ssl://smtp2.example.com:465"). Hosts will be tried in order.', true) + ->param('port', null, new Range(1, 65535), 'SMTP port.', true) + ->param('username', '', new Text(0), 'Authentication username.', true) + ->param('password', '', new Text(0), 'Authentication password.', true) + ->param('encryption', '', new WhiteList(['none', 'ssl', 'tls']), 'Encryption type. Can be \'ssl\' or \'tls\'', true) + ->param('autoTLS', null, new Boolean(), 'Enable SMTP AutoTLS feature.', true) + ->param('fromName', '', new Text(128), 'Sender Name.', true) + ->param('fromEmail', '', new Email(), 'Sender email address.', true) + ->param('replyToName', '', new Text(128), 'Name set in the Reply To field for the mail. Default value is Sender Name.', true) + ->param('replyToEmail', '', new Text(128), 'Email set in the Reply To field for the mail. Default value is Sender Email.', true) + ->param('enabled', null, new Boolean(), 'Set as enabled.', true) + ->inject('queueForEvents') + ->inject('dbForProject') + ->inject('response') + ->action(function (string $providerId, string $name, string $host, ?int $port, string $username, string $password, string $encryption, ?bool $autoTLS, string $fromName, string $fromEmail, string $replyToName, string $replyToEmail, ?bool $enabled, Event $queueForEvents, Database $dbForProject, Response $response) { + $provider = $dbForProject->getDocument('providers', $providerId); + + if ($provider->isEmpty()) { + throw new Exception(Exception::PROVIDER_NOT_FOUND); + } + + $providerAttr = $provider->getAttribute('provider'); + + if ($providerAttr !== 'smtp') { + throw new Exception(Exception::PROVIDER_INCORRECT_TYPE); + } + + if (!empty($name)) { + $provider->setAttribute('name', $name); + } + + $options = $provider->getAttribute('options'); + + if (!empty($fromName)) { + $options['fromName'] = $fromName; + } + + if (!empty($fromEmail)) { + $options['fromEmail'] = $fromEmail; + } + + if (!empty($replyToName)) { + $options['replyToName'] = $replyToName; + } + + if (!empty($replyToEmail)) { + $options['replyToEmail'] = $replyToEmail; + } + + $provider->setAttribute('options', $options); + + $credentials = $provider->getAttribute('credentials'); + + if (!empty($host)) { + $credentials['host'] = $host; + } + + if (!\is_null($port)) { + $credentials['port'] = $port; + } + + if (!empty($username)) { + $credentials['username'] = $username; + } + + if (!empty($password)) { + $credentials['password'] = $password; + } + + if (!empty($encryption)) { + $credentials['encryption'] = $encryption === 'none' ? '' : $encryption; + } + + if (!\is_null($autoTLS)) { + $credentials['autoTLS'] = $autoTLS; + } + + $provider->setAttribute('credentials', $credentials); + + if (!\is_null($enabled)) { + if ($enabled) { + if ( + !empty($options['fromEmail']) + && \array_key_exists('host', $credentials) + ) { + $provider->setAttribute('enabled', true); + } else { + throw new Exception(Exception::PROVIDER_MISSING_CREDENTIALS); + } + } else { + $provider->setAttribute('enabled', false); + } + } + + $provider = $dbForProject->updateDocument('providers', $provider->getId(), $provider); + + $queueForEvents + ->setParam('providerId', $provider->getId()); + + $response + ->dynamic($provider, Response::MODEL_PROVIDER); + }); + App::patch('/v1/messaging/providers/msg91/:providerId') ->desc('Update Msg91 provider') ->groups(['api', 'messaging']) diff --git a/composer.json b/composer.json index b9d43a8227..b6951e9a43 100644 --- a/composer.json +++ b/composer.json @@ -56,7 +56,7 @@ "utopia-php/image": "0.6.*", "utopia-php/locale": "0.4.*", "utopia-php/logger": "0.3.*", - "utopia-php/messaging": "0.8.*", + "utopia-php/messaging": "0.9.*", "utopia-php/migration": "0.3.*", "utopia-php/orchestration": "0.9.*", "utopia-php/platform": "0.5.*", diff --git a/composer.lock b/composer.lock index 34b655a887..7ef20a73c3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b692b61971354d653a0a0aa27bd5a646", + "content-hash": "4b9b6ff602a179493e0196636d961e9c", "packages": [ { "name": "adhocore/jwt", @@ -1358,16 +1358,16 @@ }, { "name": "utopia-php/framework", - "version": "0.33.1", + "version": "0.33.2", "source": { "type": "git", "url": "https://github.com/utopia-php/http.git", - "reference": "b745607aa1875554a0ad52e28f6db918da1ce11c" + "reference": "b1423ca3e3b61c6c4c2e619d2cb80672809a19f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/http/zipball/b745607aa1875554a0ad52e28f6db918da1ce11c", - "reference": "b745607aa1875554a0ad52e28f6db918da1ce11c", + "url": "https://api.github.com/repos/utopia-php/http/zipball/b1423ca3e3b61c6c4c2e619d2cb80672809a19f3", + "reference": "b1423ca3e3b61c6c4c2e619d2cb80672809a19f3", "shasum": "" }, "require": { @@ -1397,9 +1397,9 @@ ], "support": { "issues": "https://github.com/utopia-php/http/issues", - "source": "https://github.com/utopia-php/http/tree/0.33.1" + "source": "https://github.com/utopia-php/http/tree/0.33.2" }, - "time": "2024-01-17T16:48:32+00:00" + "time": "2024-01-31T10:35:59+00:00" }, { "name": "utopia-php/image", @@ -1555,16 +1555,16 @@ }, { "name": "utopia-php/messaging", - "version": "0.8.1", + "version": "0.9.0", "source": { "type": "git", "url": "https://github.com/utopia-php/messaging.git", - "reference": "bfb5014d3a8752901e50da1ae21bf309a6af5006" + "reference": "df54ba51570e886724590edeb03dbd455bb0464d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/messaging/zipball/bfb5014d3a8752901e50da1ae21bf309a6af5006", - "reference": "bfb5014d3a8752901e50da1ae21bf309a6af5006", + "url": "https://api.github.com/repos/utopia-php/messaging/zipball/df54ba51570e886724590edeb03dbd455bb0464d", + "reference": "df54ba51570e886724590edeb03dbd455bb0464d", "shasum": "" }, "require": { @@ -1599,9 +1599,9 @@ ], "support": { "issues": "https://github.com/utopia-php/messaging/issues", - "source": "https://github.com/utopia-php/messaging/tree/0.8.1" + "source": "https://github.com/utopia-php/messaging/tree/0.9.0" }, - "time": "2024-01-10T23:55:03+00:00" + "time": "2024-01-31T11:51:27+00:00" }, { "name": "utopia-php/migration", @@ -2474,16 +2474,16 @@ }, { "name": "doctrine/deprecations", - "version": "1.1.2", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931" + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/4f2d4f2836e7ec4e7a8625e75c6aa916004db931", - "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", "shasum": "" }, "require": { @@ -2515,9 +2515,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.2" + "source": "https://github.com/doctrine/deprecations/tree/1.1.3" }, - "time": "2023-09-27T20:04:15+00:00" + "time": "2024-01-30T19:34:25+00:00" }, { "name": "doctrine/instantiator", diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index a5c8154b91..f1a0bea6e6 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -18,6 +18,7 @@ use Utopia\Database\Query; use Utopia\Messaging\Adapter\Email as EmailAdapter; use Utopia\Messaging\Adapter\Email\Mailgun; use Utopia\Messaging\Adapter\Email\Sendgrid; +use Utopia\Messaging\Adapter\Email\SMTP; use Utopia\Messaging\Adapter\Push as PushAdapter; use Utopia\Messaging\Adapter\Push\APNS; use Utopia\Messaging\Adapter\Push\FCM; @@ -216,8 +217,8 @@ class Messaging extends Action $batches = \array_chunk($identifiers, $maxBatchSize); $batchIndex = 0; - return batch(\array_map(function ($batch) use ($message, $provider, $adapter, $batchIndex, $dbForProject) { - return function () use ($batch, $message, $provider, $adapter, $batchIndex, $dbForProject) { + return batch(\array_map(function ($batch) use ($message, $provider, $adapter, &$batchIndex, $dbForProject) { + return function () use ($batch, $message, $provider, $adapter, &$batchIndex, $dbForProject) { $deliveredTotal = 0; $deliveryErrors = []; $messageData = clone $message; @@ -407,10 +408,24 @@ class Messaging extends Action private function email(Document $provider): ?EmailAdapter { - $credentials = $provider->getAttribute('credentials'); + $credentials = $provider->getAttribute('credentials', []); + $options = $provider->getAttribute('options', []); return match ($provider->getAttribute('provider')) { 'mock' => new Mock('username', 'password'), - 'mailgun' => new Mailgun($credentials['apiKey'], $credentials['domain'], $credentials['isEuRegion']), + 'smtp' => new SMTP( + $credentials['host'], + $credentials['port'], + $credentials['username'], + $credentials['password'], + $options['encryption'], + $options['autoTLS'], + $options['mailer'], + ), + 'mailgun' => new Mailgun( + $credentials['apiKey'], + $credentials['domain'], + $credentials['isEuRegion'] + ), 'sendgrid' => new Sendgrid($credentials['apiKey']), default => null }; @@ -418,16 +433,10 @@ class Messaging extends Action private function buildEmailMessage(Database $dbForProject, Document $message, Document $provider): Email { - $fromName = $provider['options']['fromName']; - $fromEmail = $provider['options']['fromEmail']; - $replyToEmail = null; - $replyToName = null; - - if (isset($provider['options']['replyToName']) && isset($provider['options']['replyToEmail'])) { - $replyToName = $provider['options']['replyToName']; - $replyToEmail = $provider['options']['replyToEmail']; - } - + $fromName = $provider['options']['fromName'] ?? null; + $fromEmail = $provider['options']['fromEmail'] ?? null; + $replyToEmail = $provider['options']['replyToEmail'] ?? null; + $replyToName = $provider['options']['replyToName'] ?? null; $data = $message['data'] ?? []; $ccTargets = $data['cc'] ?? []; $bccTargets = $data['bcc'] ?? []; diff --git a/tests/e2e/Services/GraphQL/Base.php b/tests/e2e/Services/GraphQL/Base.php index 9ffabc8fcb..0396895749 100644 --- a/tests/e2e/Services/GraphQL/Base.php +++ b/tests/e2e/Services/GraphQL/Base.php @@ -207,6 +207,7 @@ trait Base // Providers public static string $CREATE_MAILGUN_PROVIDER = 'create_mailgun_provider'; public static string $CREATE_SENDGRID_PROVIDER = 'create_sendgrid_provider'; + public static string $CREATE_SMTP_PROVIDER = 'create_smtp_provider'; public static string $CREATE_TWILIO_PROVIDER = 'create_twilio_provider'; public static string $CREATE_TELESIGN_PROVIDER = 'create_telesign_provider'; public static string $CREATE_TEXTMAGIC_PROVIDER = 'create_textmagic_provider'; @@ -218,6 +219,7 @@ trait Base public static string $GET_PROVIDER = 'get_provider'; public static string $UPDATE_MAILGUN_PROVIDER = 'update_mailgun_provider'; public static string $UPDATE_SENDGRID_PROVIDER = 'update_sendgrid_provider'; + public static string $UPDATE_SMTP_PROVIDER = 'update_smtp_provider'; public static string $UPDATE_TWILIO_PROVIDER = 'update_twilio_provider'; public static string $UPDATE_TELESIGN_PROVIDER = 'update_telesign_provider'; public static string $UPDATE_TEXTMAGIC_PROVIDER = 'update_textmagic_provider'; @@ -1809,6 +1811,16 @@ trait Base enabled } }'; + case self::$CREATE_SMTP_PROVIDER: + return 'mutation createSMTPProvider($providerId: String!, $name: String!, $host: String!, $port: Int!, $username: String!, $password: String!, $encryption: String!, $autoTLS: Boolean! $fromName: String!, $fromEmail: String!, $replyToName: String, $replyToEmail: String) { + messagingCreateSMTPProvider(providerId: $providerId, name: $name, host: $host, port: $port, username: $username, password: $password, encryption: $encryption, autoTLS: $autoTLS, fromName: $fromName, fromEmail: $fromEmail, replyToName: $replyToName, replyToEmail: $replyToEmail) { + _id + name + provider + type + enabled + } + }'; case self::$CREATE_TWILIO_PROVIDER: return 'mutation createTwilioProvider($providerId: String!, $name: String!, $from: String!, $accountSid: String!, $authToken: String!) { messagingCreateTwilioProvider(providerId: $providerId, name: $name, from: $from, accountSid: $accountSid, authToken: $authToken) { @@ -1923,6 +1935,16 @@ trait Base enabled } }'; + case self::$UPDATE_SMTP_PROVIDER: + return 'mutation updateSMTPProvider($providerId: String!, $name: String!, $host: String!, $port: Int!, $username: String!, $password: String!, $encryption: String!, $autoTLS: Boolean!, $fromName: String, $fromEmail: String, $enabled: Boolean) { + messagingUpdateSMTPProvider(providerId: $providerId, name: $name, host: $host, port: $port, username: $username, password: $password, encryption: $encryption, autoTLS: $autoTLS, fromName: $fromName, fromEmail: $fromEmail, enabled: $enabled) { + _id + name + provider + type + enabled + } + }'; case self::$UPDATE_TWILIO_PROVIDER: return 'mutation updateTwilioProvider($providerId: String!, $name: String!, $accountSid: String!, $authToken: String!) { messagingUpdateTwilioProvider(providerId: $providerId, name: $name, accountSid: $accountSid, authToken: $authToken) { diff --git a/tests/e2e/Services/Messaging/MessagingBase.php b/tests/e2e/Services/Messaging/MessagingBase.php index 99c058444f..d5ac040a75 100644 --- a/tests/e2e/Services/Messaging/MessagingBase.php +++ b/tests/e2e/Services/Messaging/MessagingBase.php @@ -29,6 +29,17 @@ trait MessagingBase 'fromEmail' => 'sender-email@my-domain.com', 'isEuRegion' => false, ], + 'smtp' => [ + 'providerId' => ID::unique(), + 'name' => 'SMTP1', + 'host' => 'smtp.appwrite.io', + 'port' => 587, + 'security' => 'tls', + 'username' => 'my-username', + 'password' => 'my-password', + 'fromName' => 'sender name', + 'fromEmail' => 'tester@appwrite.io', + ], 'twilio' => [ 'providerId' => ID::unique(), 'name' => 'Twilio1', @@ -115,6 +126,14 @@ trait MessagingBase 'apiKey' => 'my-apikey', 'domain' => 'my-domain', ], + 'smtp' => [ + 'name' => 'SMTP2', + 'host' => 'smtp.appwrite.io', + 'port' => 587, + 'security' => 'tls', + 'username' => 'my-username', + 'password' => 'my-password', + ], 'twilio' => [ 'name' => 'Twilio2', 'accountSid' => 'my-accountSid', @@ -224,7 +243,7 @@ trait MessagingBase ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals(10, \count($response['body']['providers'])); + $this->assertEquals(11, \count($response['body']['providers'])); return $providers; }