1
0
Fork 0
mirror of synced 2024-07-04 06:00:53 +12:00

Merge remote-tracking branch 'origin/feat-git-integration' into feat-git-integration-no-hook

This commit is contained in:
Jake Barnby 2023-08-29 11:59:44 -04:00
commit 84177b0fb0
No known key found for this signature in database
GPG key ID: C437A8CC85B96E9C
17 changed files with 359 additions and 256 deletions

2
.gitmodules vendored
View file

@ -1,4 +1,4 @@
[submodule "app/console"] [submodule "app/console"]
path = app/console path = app/console
url = https://github.com/appwrite/console url = https://github.com/appwrite/console
branch = 1.4.x branch = main

View file

@ -671,11 +671,6 @@ return [
'description' => 'Provided SMTP config is invalid. Please check the configured values and try again.', 'description' => 'Provided SMTP config is invalid. Please check the configured values and try again.',
'code' => 400, 'code' => 400,
], ],
Exception::PROJECT_SMTP_CONFIG_NOT_FOUND => [
'name' => Exception::PROJECT_SMTP_CONFIG_NOT_FOUND,
'description' => 'SMTP configuration on project is missing. Please configure a custom SMTP server to enable custom email templates.',
'code' => 404,
],
Exception::PROJECT_TEMPLATE_DEFAULT_DELETION => [ Exception::PROJECT_TEMPLATE_DEFAULT_DELETION => [
'name' => Exception::PROJECT_TEMPLATE_DEFAULT_DELETION, 'name' => Exception::PROJECT_TEMPLATE_DEFAULT_DELETION,
'description' => 'You can\'t delete default template. If you are trying to reset your template changes, you can ignore this error as it\'s already been reset.', 'description' => 'You can\'t delete default template. If you are trying to reset your template changes, you can ignore this error as it\'s already been reset.',

View file

@ -54,16 +54,6 @@
<div style="max-width:650px; word-wrap: break-wrod; overflow-wrap: break-word; <div style="max-width:650px; word-wrap: break-wrod; overflow-wrap: break-word;
word-break: break-all; margin:0 auto;"> word-break: break-all; margin:0 auto;">
<table style="margin-top: 32px"> <table style="margin-top: 32px">
<tr>
<td>
<h1>
{{subject}}
</h1>
</td>
</tr>
</table>
<table style="margin-top: 40px">
<tr> <tr>
<td> <td>
{{body}} {{body}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
Subproject commit 51aa80cc80e83a41466bb353ccdff0e0e37d492f Subproject commit 0534cf0a65f4d8766926cf391d345cc0ad1d3c20

View file

@ -1091,33 +1091,60 @@ App::post('/v1/account/sessions/magic-url')
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['userId' => $user->getId(), 'secret' => $loginSecret, 'expire' => $expire, 'project' => $project->getId()]); $url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['userId' => $user->getId(), 'secret' => $loginSecret, 'expire' => $expire, 'project' => $project->getId()]);
$url = Template::unParseURL($url); $url = Template::unParseURL($url);
$from = $project->isEmpty() || $project->getId() === 'console' ? '' : \sprintf($locale->getText('emails.sender'), $project->getAttribute('name'));
$body = $locale->getText("emails.magicSession.body"); $body = $locale->getText("emails.magicSession.body");
$subject = $locale->getText("emails.magicSession.subject"); $subject = $locale->getText("emails.magicSession.subject");
$smtpEnabled = $project->getAttribute('smtp', [])['enabled'] ?? false;
$customTemplate = $project->getAttribute('templates', [])['email.magicSession-' . $locale->default] ?? []; $customTemplate = $project->getAttribute('templates', [])['email.magicSession-' . $locale->default] ?? [];
if ($smtpEnabled && !empty($customTemplate)) {
$body = $customTemplate['message'] ?? ''; $message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
$subject = $customTemplate['subject'] ?? $subject; $message->setParam('{{body}}', $body);
$from = $customTemplate['senderName'] ?? $from; $body = $message->render();
$smtp = $project->getAttribute('smtp', []); $smtp = $project->getAttribute('smtp', []);
$smtpEnabled = $smtp['enabled'] ?? false;
$senderEmail = App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM);
$senderName = App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
$replyTo = "";
if ($smtpEnabled) {
if (!empty($smtp['senderEmail'])) {
$senderEmail = $smtp['senderEmail'];
}
if (!empty($smtp['senderName'])) {
$senderName = $smtp['senderName'];
}
if (!empty($smtp['replyTo'])) {
$replyTo = $smtp['replyTo'];
}
$mails $mails
->setSmtpHost($smtp['host'] ?? '') ->setSmtpHost($smtp['host'] ?? '')
->setSmtpPort($smtp['port'] ?? '') ->setSmtpPort($smtp['port'] ?? '')
->setSmtpUsername($smtp['username'] ?? '') ->setSmtpUsername($smtp['username'] ?? '')
->setSmtpPassword($smtp['password'] ?? '') ->setSmtpPassword($smtp['password'] ?? '')
->setSmtpSecure($smtp['secure'] ?? '') ->setSmtpSecure($smtp['secure'] ?? '');
->setSmtpReplyTo($customTemplate['replyTo'] ?? '')
->setSmtpSenderEmail($customTemplate['senderEmail'] ?? '')
->setSmtpSenderName($customTemplate['senderName'] ?? '');
} else {
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
$message->setParam('{{body}}', $body);
$body = $message->render();
} }
if (!empty($customTemplate)) {
if (!empty($customTemplate['senderEmail'])) {
$senderEmail = $customTemplate['senderEmail'];
}
if (!empty($customTemplate['senderName'])) {
$senderName = $customTemplate['senderName'];
}
if (!empty($customTemplate['replyTo'])) {
$replyTo = $customTemplate['replyTo'];
}
$body = $customTemplate['message'] ?? '';
$subject = $customTemplate['subject'] ?? $subject;
}
$mails
->setSmtpReplyTo($replyTo)
->setSmtpSenderEmail($senderEmail)
->setSmtpSenderName($senderName);
$emailVariables = [ $emailVariables = [
'subject' => $subject, 'subject' => $subject,
'hello' => $locale->getText("emails.magicSession.hello"), 'hello' => $locale->getText("emails.magicSession.hello"),
@ -1138,7 +1165,6 @@ App::post('/v1/account/sessions/magic-url')
->setSubject($subject) ->setSubject($subject)
->setBody($body) ->setBody($body)
->setVariables($emailVariables) ->setVariables($emailVariables)
->setFrom($from)
->setRecipient($user->getAttribute('email')) ->setRecipient($user->getAttribute('email'))
->trigger() ->trigger()
; ;
@ -2522,33 +2548,60 @@ App::post('/v1/account/recovery')
$url = Template::unParseURL($url); $url = Template::unParseURL($url);
$projectName = $project->isEmpty() ? 'Console' : $project->getAttribute('name', '[APP-NAME]'); $projectName = $project->isEmpty() ? 'Console' : $project->getAttribute('name', '[APP-NAME]');
$from = $project->isEmpty() || $project->getId() === 'console' ? '' : \sprintf($locale->getText('emails.sender'), $projectName);
$body = $locale->getText("emails.recovery.body"); $body = $locale->getText("emails.recovery.body");
$subject = $locale->getText("emails.recovery.subject"); $subject = $locale->getText("emails.recovery.subject");
$smtpEnabled = $project->getAttribute('smtp', [])['enabled'] ?? false;
$customTemplate = $project->getAttribute('templates', [])['email.recovery-' . $locale->default] ?? []; $customTemplate = $project->getAttribute('templates', [])['email.recovery-' . $locale->default] ?? [];
if ($smtpEnabled && !empty($customTemplate)) {
$body = $customTemplate['message']; $message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
$subject = $customTemplate['subject'] ?? $subject; $message->setParam('{{body}}', $body);
$from = $customTemplate['senderName'] ?? $from; $body = $message->render();
$smtp = $project->getAttribute('smtp', []); $smtp = $project->getAttribute('smtp', []);
$smtpEnabled = $smtp['enabled'] ?? false;
$senderEmail = App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM);
$senderName = App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
$replyTo = "";
if ($smtpEnabled) {
if (!empty($smtp['senderEmail'])) {
$senderEmail = $smtp['senderEmail'];
}
if (!empty($smtp['senderName'])) {
$senderName = $smtp['senderName'];
}
if (!empty($smtp['replyTo'])) {
$replyTo = $smtp['replyTo'];
}
$mails $mails
->setSmtpHost($smtp['host'] ?? '') ->setSmtpHost($smtp['host'] ?? '')
->setSmtpPort($smtp['port'] ?? '') ->setSmtpPort($smtp['port'] ?? '')
->setSmtpUsername($smtp['username'] ?? '') ->setSmtpUsername($smtp['username'] ?? '')
->setSmtpPassword($smtp['password'] ?? '') ->setSmtpPassword($smtp['password'] ?? '')
->setSmtpSecure($smtp['secure'] ?? '') ->setSmtpSecure($smtp['secure'] ?? '');
->setSmtpReplyTo($customTemplate['replyTo'] ?? '')
->setSmtpSenderEmail($customTemplate['senderEmail'] ?? '')
->setSmtpSenderName($customTemplate['senderName'] ?? '');
} else {
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
$message->setParam('{{body}}', $body);
$body = $message->render();
} }
if (!empty($customTemplate)) {
if (!empty($customTemplate['senderEmail'])) {
$senderEmail = $customTemplate['senderEmail'];
}
if (!empty($customTemplate['senderName'])) {
$senderName = $customTemplate['senderName'];
}
if (!empty($customTemplate['replyTo'])) {
$replyTo = $customTemplate['replyTo'];
}
$body = $customTemplate['message'] ?? '';
$subject = $customTemplate['subject'] ?? $subject;
}
$mails
->setSmtpReplyTo($replyTo)
->setSmtpSenderEmail($senderEmail)
->setSmtpSenderName($senderName);
$emailVariables = [ $emailVariables = [
'subject' => $subject, 'subject' => $subject,
'hello' => $locale->getText("emails.recovery.hello"), 'hello' => $locale->getText("emails.recovery.hello"),
@ -2571,7 +2624,6 @@ App::post('/v1/account/recovery')
->setName($profile->getAttribute('name')) ->setName($profile->getAttribute('name'))
->setBody($body) ->setBody($body)
->setVariables($emailVariables) ->setVariables($emailVariables)
->setFrom($from)
->setSubject($subject) ->setSubject($subject)
->trigger(); ->trigger();
; ;
@ -2747,33 +2799,60 @@ App::post('/v1/account/verification')
$url = Template::unParseURL($url); $url = Template::unParseURL($url);
$projectName = $project->isEmpty() ? 'Console' : $project->getAttribute('name', '[APP-NAME]'); $projectName = $project->isEmpty() ? 'Console' : $project->getAttribute('name', '[APP-NAME]');
$from = $project->isEmpty() || $project->getId() === 'console' ? '' : \sprintf($locale->getText('emails.sender'), $projectName);
$body = $locale->getText("emails.verification.body"); $body = $locale->getText("emails.verification.body");
$subject = $locale->getText("emails.verification.subject"); $subject = $locale->getText("emails.verification.subject");
$smtpEnabled = $project->getAttribute('smtp', [])['enabled'] ?? false;
$customTemplate = $project->getAttribute('templates', [])['email.verification-' . $locale->default] ?? []; $customTemplate = $project->getAttribute('templates', [])['email.verification-' . $locale->default] ?? [];
if ($smtpEnabled && !empty($customTemplate)) {
$body = $customTemplate['message'] ?? ''; $message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
$subject = $customTemplate['subject'] ?? $subject; $message->setParam('{{body}}', $body);
$from = $customTemplate['senderName'] ?? $from; $body = $message->render();
$smtp = $project->getAttribute('smtp', []); $smtp = $project->getAttribute('smtp', []);
$smtpEnabled = $smtp['enabled'] ?? false;
$senderEmail = App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM);
$senderName = App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
$replyTo = "";
if ($smtpEnabled) {
if (!empty($smtp['senderEmail'])) {
$senderEmail = $smtp['senderEmail'];
}
if (!empty($smtp['senderName'])) {
$senderName = $smtp['senderName'];
}
if (!empty($smtp['replyTo'])) {
$replyTo = $smtp['replyTo'];
}
$mails $mails
->setSmtpHost($smtp['host'] ?? '') ->setSmtpHost($smtp['host'] ?? '')
->setSmtpPort($smtp['port'] ?? '') ->setSmtpPort($smtp['port'] ?? '')
->setSmtpUsername($smtp['username'] ?? '') ->setSmtpUsername($smtp['username'] ?? '')
->setSmtpPassword($smtp['password'] ?? '') ->setSmtpPassword($smtp['password'] ?? '')
->setSmtpSecure($smtp['secure'] ?? '') ->setSmtpSecure($smtp['secure'] ?? '');
->setSmtpReplyTo($customTemplate['replyTo'] ?? '')
->setSmtpSenderEmail($customTemplate['senderEmail'] ?? '')
->setSmtpSenderName($customTemplate['senderName'] ?? '');
} else {
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
$message->setParam('{{body}}', $body);
$body = $message->render();
} }
if (!empty($customTemplate)) {
if (!empty($customTemplate['senderEmail'])) {
$senderEmail = $customTemplate['senderEmail'];
}
if (!empty($customTemplate['senderName'])) {
$senderName = $customTemplate['senderName'];
}
if (!empty($customTemplate['replyTo'])) {
$replyTo = $customTemplate['replyTo'];
}
$body = $customTemplate['message'] ?? '';
$subject = $customTemplate['subject'] ?? $subject;
}
$mails
->setSmtpReplyTo($replyTo)
->setSmtpSenderEmail($senderEmail)
->setSmtpSenderName($senderName);
$emailVariables = [ $emailVariables = [
'subject' => $subject, 'subject' => $subject,
'hello' => $locale->getText("emails.verification.hello"), 'hello' => $locale->getText("emails.verification.hello"),
@ -2794,7 +2873,6 @@ App::post('/v1/account/verification')
->setSubject($subject) ->setSubject($subject)
->setBody($body) ->setBody($body)
->setVariables($emailVariables) ->setVariables($emailVariables)
->setFrom($from)
->setRecipient($user->getAttribute('email')) ->setRecipient($user->getAttribute('email'))
->setName($user->getAttribute('name') ?? '') ->setName($user->getAttribute('name') ?? '')
->trigger() ->trigger()

View file

@ -29,6 +29,10 @@ App::get('/v1/console/variables')
->label('sdk.response.model', Response::MODEL_CONSOLE_VARIABLES) ->label('sdk.response.model', Response::MODEL_CONSOLE_VARIABLES)
->inject('response') ->inject('response')
->action(function (Response $response) { ->action(function (Response $response) {
$isDomainEnabled = !empty(App::getEnv('_APP_DOMAIN', ''))
&& !empty(App::getEnv('_APP_DOMAIN_TARGET', ''))
&& App::getEnv('_APP_DOMAIN', '') !== 'localhost'
&& App::getEnv('_APP_DOMAIN_TARGET', '') !== 'localhost';
$isVcsEnabled = !empty(App::getEnv('_APP_VCS_GITHUB_APP_NAME', '')) $isVcsEnabled = !empty(App::getEnv('_APP_VCS_GITHUB_APP_NAME', ''))
&& !empty(App::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY', '')) && !empty(App::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY', ''))
@ -44,6 +48,7 @@ App::get('/v1/console/variables')
'_APP_FUNCTIONS_SIZE_LIMIT' => +App::getEnv('_APP_FUNCTIONS_SIZE_LIMIT'), '_APP_FUNCTIONS_SIZE_LIMIT' => +App::getEnv('_APP_FUNCTIONS_SIZE_LIMIT'),
'_APP_USAGE_STATS' => App::getEnv('_APP_USAGE_STATS'), '_APP_USAGE_STATS' => App::getEnv('_APP_USAGE_STATS'),
'_APP_VCS_ENABLED' => $isVcsEnabled, '_APP_VCS_ENABLED' => $isVcsEnabled,
'_APP_DOMAIN_ENABLED' => $isDomainEnabled,
'_APP_ASSISTANT_ENABLED' => $isAssistantEnabled '_APP_ASSISTANT_ENABLED' => $isAssistantEnabled
]); ]);

View file

@ -843,8 +843,7 @@ App::delete('/v1/projects/:projectId')
$deletes $deletes
->setType(DELETE_TYPE_DOCUMENT) ->setType(DELETE_TYPE_DOCUMENT)
->setDocument($project) ->setDocument($project);
;
if (!$dbForConsole->deleteDocument('projects', $projectId)) { if (!$dbForConsole->deleteDocument('projects', $projectId)) {
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove project from DB'); throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove project from DB');
@ -1022,8 +1021,7 @@ App::put('/v1/projects/:projectId/webhooks/:webhookId')
->setAttribute('url', $url) ->setAttribute('url', $url)
->setAttribute('security', $security) ->setAttribute('security', $security)
->setAttribute('httpUser', $httpUser) ->setAttribute('httpUser', $httpUser)
->setAttribute('httpPass', $httpPass) ->setAttribute('httpPass', $httpPass);
;
$dbForConsole->updateDocument('webhooks', $webhook->getId(), $webhook); $dbForConsole->updateDocument('webhooks', $webhook->getId(), $webhook);
$dbForConsole->deleteCachedDocument('projects', $project->getId()); $dbForConsole->deleteCachedDocument('projects', $project->getId());
@ -1262,8 +1260,7 @@ App::put('/v1/projects/:projectId/keys/:keyId')
$key $key
->setAttribute('name', $name) ->setAttribute('name', $name)
->setAttribute('scopes', $scopes) ->setAttribute('scopes', $scopes)
->setAttribute('expire', $expire) ->setAttribute('expire', $expire);
;
$dbForConsole->updateDocument('keys', $key->getId(), $key); $dbForConsole->updateDocument('keys', $key->getId(), $key);
@ -1465,8 +1462,7 @@ App::put('/v1/projects/:projectId/platforms/:platformId')
->setAttribute('name', $name) ->setAttribute('name', $name)
->setAttribute('key', $key) ->setAttribute('key', $key)
->setAttribute('store', $store) ->setAttribute('store', $store)
->setAttribute('hostname', $hostname) ->setAttribute('hostname', $hostname);
;
$dbForConsole->updateDocument('platforms', $platform->getId(), $platform); $dbForConsole->updateDocument('platforms', $platform->getId(), $platform);
@ -1525,15 +1521,17 @@ App::patch('/v1/projects/:projectId/smtp')
->label('sdk.response.model', Response::MODEL_PROJECT) ->label('sdk.response.model', Response::MODEL_PROJECT)
->param('projectId', '', new UID(), 'Project unique ID.') ->param('projectId', '', new UID(), 'Project unique ID.')
->param('enabled', false, new Boolean(), 'Enable custom SMTP service') ->param('enabled', false, new Boolean(), 'Enable custom SMTP service')
->param('sender', '', new Email(), 'SMTP sender email') ->param('senderName', '', new Text(255, 0), 'Name of the email sender', true)
->param('host', '', new HostName(), 'SMTP server host name') ->param('senderEmail', '', new Email(), 'Email of the sender', true)
->param('port', null, new Integer(), 'SMTP server port') ->param('replyTo', '', new Email(), 'Reply to email', true)
->param('username', null, new Text(0), 'SMTP server username') ->param('host', '', new HostName(), 'SMTP server host name', true)
->param('password', null, new Text(0), 'SMTP server password') ->param('port', 587, new Integer(), 'SMTP server port', true)
->param('username', '', new Text(0), 'SMTP server username', true)
->param('password', '', new Text(0), 'SMTP server password', true)
->param('secure', '', new WhiteList(['tls'], true), 'Does SMTP server use secure connection', true) ->param('secure', '', new WhiteList(['tls'], true), 'Does SMTP server use secure connection', true)
->inject('response') ->inject('response')
->inject('dbForConsole') ->inject('dbForConsole')
->action(function (string $projectId, bool $enabled, string $sender, string $host, int $port, string $username, string $password, string $secure, Response $response, Database $dbForConsole) { ->action(function (string $projectId, bool $enabled, string $senderName, string $senderEmail, string $replyTo, string $host, int $port, string $username, string $password, string $secure, Response $response, Database $dbForConsole) {
$project = $dbForConsole->getDocument('projects', $projectId); $project = $dbForConsole->getDocument('projects', $projectId);
@ -1541,7 +1539,25 @@ App::patch('/v1/projects/:projectId/smtp')
throw new Exception(Exception::PROJECT_NOT_FOUND); throw new Exception(Exception::PROJECT_NOT_FOUND);
} }
// Ensure required params for when enabling SMTP
if ($enabled) {
if (empty($senderName)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Sender name is required when enabling SMTP.');
} elseif (empty($senderEmail)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Sender email is required when enabling SMTP.');
} elseif (empty($host)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Host is required when enabling SMTP.');
} elseif (empty($port)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Port is required when enabling SMTP.');
} elseif (empty($username)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Username is required when enabling SMTP.');
} elseif (empty($password)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Password is required when enabling SMTP.');
}
}
// validate SMTP settings // validate SMTP settings
if ($enabled) {
$mail = new PHPMailer(true); $mail = new PHPMailer(true);
$mail->isSMTP(); $mail->isSMTP();
$mail->Username = $username; $mail->Username = $username;
@ -1561,16 +1577,26 @@ App::patch('/v1/projects/:projectId/smtp')
} catch (Throwable $error) { } catch (Throwable $error) {
throw new Exception(Exception::PROJECT_SMTP_CONFIG_INVALID, 'Could not connect to SMTP server: ' . $error->getMessage()); throw new Exception(Exception::PROJECT_SMTP_CONFIG_INVALID, 'Could not connect to SMTP server: ' . $error->getMessage());
} }
}
// Save SMTP settings
if ($enabled) {
$smtp = [ $smtp = [
'enabled' => $enabled, 'enabled' => $enabled,
'sender' => $sender, 'senderName' => $senderName,
'senderEmail' => $senderEmail,
'replyTo' => $replyTo,
'host' => $host, 'host' => $host,
'port' => $port, 'port' => $port,
'username' => $username, 'username' => $username,
'password' => $password, 'password' => $password,
'secure' => $secure, 'secure' => $secure,
]; ];
} else {
$smtp = [
'enabled' => false
];
}
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project->setAttribute('smtp', $smtp)); $project = $dbForConsole->updateDocument('projects', $project->getId(), $project->setAttribute('smtp', $smtp));
@ -1656,13 +1682,11 @@ App::get('/v1/projects/:projectId/templates/email/:type/:locale')
->setParam('{{direction}}', $localeObj->getText('settings.direction')); ->setParam('{{direction}}', $localeObj->getText('settings.direction'));
$message = $message->render(); $message = $message->render();
$from = $project->isEmpty() || $project->getId() === 'console' ? '' : \sprintf($localeObj->getText('emails.sender'), $project->getAttribute('name'));
$from = empty($from) ? \urldecode(App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server')) : $from;
$template = [ $template = [
'message' => $message, 'message' => $message,
'subject' => $localeObj->getText('emails.' . $type . '.subject'), 'subject' => $localeObj->getText('emails.' . $type . '.subject'),
'senderEmail' => App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', ''), 'senderEmail' => '',
'senderName' => $from 'senderName' => ''
]; ];
} }
@ -1698,8 +1722,6 @@ App::patch('/v1/projects/:projectId/templates/sms/:type/:locale')
throw new Exception(Exception::PROJECT_NOT_FOUND); throw new Exception(Exception::PROJECT_NOT_FOUND);
} }
// TODO: Ensure SMS is enabled on project
$templates = $project->getAttribute('templates', []); $templates = $project->getAttribute('templates', []);
$templates['sms.' . $type . '-' . $locale] = [ $templates['sms.' . $type . '-' . $locale] = [
'message' => $message 'message' => $message
@ -1727,14 +1749,14 @@ App::patch('/v1/projects/:projectId/templates/email/:type/:locale')
->param('projectId', '', new UID(), 'Project unique ID.') ->param('projectId', '', new UID(), 'Project unique ID.')
->param('type', '', new WhiteList(Config::getParam('locale-templates')['email'] ?? []), 'Template type') ->param('type', '', new WhiteList(Config::getParam('locale-templates')['email'] ?? []), 'Template type')
->param('locale', '', fn ($localeCodes) => new WhiteList($localeCodes), 'Template locale', false, ['localeCodes']) ->param('locale', '', fn ($localeCodes) => new WhiteList($localeCodes), 'Template locale', false, ['localeCodes'])
->param('senderName', '', new Text(255), 'Name of the email sender')
->param('senderEmail', '', new Email(), 'Email of the sender')
->param('subject', '', new Text(255), 'Email Subject') ->param('subject', '', new Text(255), 'Email Subject')
->param('message', '', new Text(0), 'Template message') ->param('message', '', new Text(0), 'Template message')
->param('senderName', '', new Text(255, 0), 'Name of the email sender', true)
->param('senderEmail', '', new Email(), 'Email of the sender', true)
->param('replyTo', '', new Email(), 'Reply to email', true) ->param('replyTo', '', new Email(), 'Reply to email', true)
->inject('response') ->inject('response')
->inject('dbForConsole') ->inject('dbForConsole')
->action(function (string $projectId, string $type, string $locale, string $senderName, string $senderEmail, string $subject, string $message, string $replyTo, Response $response, Database $dbForConsole) { ->action(function (string $projectId, string $type, string $locale, string $subject, string $message, string $senderName, string $senderEmail, string $replyTo, Response $response, Database $dbForConsole) {
$project = $dbForConsole->getDocument('projects', $projectId); $project = $dbForConsole->getDocument('projects', $projectId);
@ -1742,11 +1764,6 @@ App::patch('/v1/projects/:projectId/templates/email/:type/:locale')
throw new Exception(Exception::PROJECT_NOT_FOUND); throw new Exception(Exception::PROJECT_NOT_FOUND);
} }
$smtpEnabled = $project->getAttribute('smtp', [])['enabled'] ?? false;
if (!$smtpEnabled) {
throw new Exception(Exception::PROJECT_SMTP_CONFIG_NOT_FOUND);
}
$templates = $project->getAttribute('templates', []); $templates = $project->getAttribute('templates', []);
$templates['email.' . $type . '-' . $locale] = [ $templates['email.' . $type . '-' . $locale] = [
'senderName' => $senderName, 'senderName' => $senderName,

View file

@ -543,33 +543,60 @@ App::post('/v1/teams/:teamId/memberships')
if (!empty($email)) { if (!empty($email)) {
$projectName = $project->isEmpty() ? 'Console' : $project->getAttribute('name', '[APP-NAME]'); $projectName = $project->isEmpty() ? 'Console' : $project->getAttribute('name', '[APP-NAME]');
$from = $project->isEmpty() || $project->getId() === 'console' ? '' : \sprintf($locale->getText('emails.sender'), $projectName);
$body = $locale->getText("emails.invitation.body"); $body = $locale->getText("emails.invitation.body");
$subject = \sprintf($locale->getText("emails.invitation.subject"), $team->getAttribute('name'), $projectName); $subject = \sprintf($locale->getText("emails.invitation.subject"), $team->getAttribute('name'), $projectName);
$smtpEnabled = $project->getAttribute('smtp', [])['enabled'] ?? false;
$customTemplate = $project->getAttribute('templates', [])['email.invitation-' . $locale->default] ?? []; $customTemplate = $project->getAttribute('templates', [])['email.invitation-' . $locale->default] ?? [];
if ($smtpEnabled && !empty($customTemplate)) {
$body = Template::fromString($customTemplate['message'] ?? ''); $message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
$subject = $customTemplate['subject'] ?? $subject; $message->setParam('{{body}}', $body);
$from = $customTemplate['senderName'] ?? $from; $body = $message->render();
$smtp = $project->getAttribute('smtp', []); $smtp = $project->getAttribute('smtp', []);
$smtpEnabled = $smtp['enabled'] ?? false;
$senderEmail = App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM);
$senderName = App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
$replyTo = "";
if ($smtpEnabled) {
if (!empty($smtp['senderEmail'])) {
$senderEmail = $smtp['senderEmail'];
}
if (!empty($smtp['senderName'])) {
$senderName = $smtp['senderName'];
}
if (!empty($smtp['replyTo'])) {
$replyTo = $smtp['replyTo'];
}
$mails $mails
->setSmtpHost($smtp['host'] ?? '') ->setSmtpHost($smtp['host'] ?? '')
->setSmtpPort($smtp['port'] ?? '') ->setSmtpPort($smtp['port'] ?? '')
->setSmtpUsername($smtp['username'] ?? '') ->setSmtpUsername($smtp['username'] ?? '')
->setSmtpPassword($smtp['password'] ?? '') ->setSmtpPassword($smtp['password'] ?? '')
->setSmtpSecure($smtp['secure'] ?? '') ->setSmtpSecure($smtp['secure'] ?? '');
->setSmtpReplyTo($customTemplate['replyTo'] ?? '')
->setSmtpSenderEmail($customTemplate['senderEmail'] ?? '')
->setSmtpSenderName($customTemplate['senderName'] ?? '');
} else {
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
$message->setParam('{{body}}', $body);
$body = $message->render();
} }
if (!empty($customTemplate)) {
if (!empty($customTemplate['senderEmail'])) {
$senderEmail = $customTemplate['senderEmail'];
}
if (!empty($customTemplate['senderName'])) {
$senderName = $customTemplate['senderName'];
}
if (!empty($customTemplate['replyTo'])) {
$replyTo = $customTemplate['replyTo'];
}
$body = $customTemplate['message'] ?? '';
$subject = $customTemplate['subject'] ?? $subject;
}
$mails
->setSmtpReplyTo($replyTo)
->setSmtpSenderEmail($senderEmail)
->setSmtpSenderName($senderName);
$emailVariables = [ $emailVariables = [
'owner' => $user->getAttribute('name'), 'owner' => $user->getAttribute('name'),
'team' => $team->getAttribute('name'), 'team' => $team->getAttribute('name'),
@ -591,7 +618,6 @@ App::post('/v1/teams/:teamId/memberships')
$mails $mails
->setSubject($subject) ->setSubject($subject)
->setBody($body) ->setBody($body)
->setFrom($from)
->setRecipient($invitee->getAttribute('email')) ->setRecipient($invitee->getAttribute('email'))
->setName($invitee->getAttribute('name')) ->setName($invitee->getAttribute('name'))
->setVariables($emailVariables) ->setVariables($emailVariables)

View file

@ -38,7 +38,6 @@ class MailsV1 extends Worker
$name = $this->args['name']; $name = $this->args['name'];
$body = $this->args['body']; $body = $this->args['body'];
$variables = $this->args['variables']; $variables = $this->args['variables'];
$from = $this->args['from'];
$body = Template::fromFile(__DIR__ . '/../config/locale/templates/email-base.tpl'); $body = Template::fromFile(__DIR__ . '/../config/locale/templates/email-base.tpl');
@ -62,6 +61,11 @@ class MailsV1 extends Worker
$mail->Body = $body; $mail->Body = $body;
$mail->AltBody = \strip_tags($body); $mail->AltBody = \strip_tags($body);
$mail->setFrom($smtp['senderEmail'], $smtp['senderName']);
if (!empty($smtp['replyTo'])) {
$mail->addReplyTo($smtp['replyTo'], $smtp['senderName']);
}
try { try {
$mail->send(); $mail->send();
} catch (\Exception $error) { } catch (\Exception $error) {
@ -88,12 +92,6 @@ class MailsV1 extends Worker
$mail->SMTPAutoTLS = false; $mail->SMTPAutoTLS = false;
$mail->CharSet = 'UTF-8'; $mail->CharSet = 'UTF-8';
$from = \urldecode($smtp['senderName'] ?? App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server'));
$email = $smtp['senderEmail'] ?? App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM);
$mail->setFrom($email, $from);
$mail->addReplyTo($email, $from);
$mail->isHTML(true); $mail->isHTML(true);
return $mail; return $mail;

View file

@ -49,7 +49,7 @@
"utopia-php/cache": "0.8.*", "utopia-php/cache": "0.8.*",
"utopia-php/cli": "0.15.*", "utopia-php/cli": "0.15.*",
"utopia-php/config": "0.2.*", "utopia-php/config": "0.2.*",
"utopia-php/database": "0.42.*", "utopia-php/database": "0.43.*",
"utopia-php/domains": "0.3.*", "utopia-php/domains": "0.3.*",
"utopia-php/dsn": "0.1.*", "utopia-php/dsn": "0.1.*",
"utopia-php/framework": "0.30.0", "utopia-php/framework": "0.30.0",

98
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "7cb5852653a858c1846543914c20f87f", "content-hash": "a60b9a87c757ec717c0f7c9c7abd1051",
"packages": [ "packages": [
{ {
"name": "adhocore/jwt", "name": "adhocore/jwt",
@ -1846,16 +1846,16 @@
}, },
{ {
"name": "symfony/polyfill-php80", "name": "symfony/polyfill-php80",
"version": "v1.27.0", "version": "v1.28.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php80.git", "url": "https://github.com/symfony/polyfill-php80.git",
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1864,7 +1864,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.27-dev" "dev-main": "1.28-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -1909,7 +1909,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0"
}, },
"funding": [ "funding": [
{ {
@ -1925,27 +1925,27 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-11-03T14:55:06+00:00" "time": "2023-01-26T09:26:14+00:00"
}, },
{ {
"name": "utopia-php/abuse", "name": "utopia-php/abuse",
"version": "0.31.0", "version": "0.31.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/utopia-php/abuse.git", "url": "https://github.com/utopia-php/abuse.git",
"reference": "d771c2c8d7d1237b1d04b5bf57b07a9b4736e627" "reference": "b2ad372d1070f55f9545cb811b6ed2d40094e6dd"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/d771c2c8d7d1237b1d04b5bf57b07a9b4736e627", "url": "https://api.github.com/repos/utopia-php/abuse/zipball/b2ad372d1070f55f9545cb811b6ed2d40094e6dd",
"reference": "d771c2c8d7d1237b1d04b5bf57b07a9b4736e627", "reference": "b2ad372d1070f55f9545cb811b6ed2d40094e6dd",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-curl": "*", "ext-curl": "*",
"ext-pdo": "*", "ext-pdo": "*",
"php": ">=8.0", "php": ">=8.0",
"utopia-php/database": "0.42.*" "utopia-php/database": "0.43.*"
}, },
"require-dev": { "require-dev": {
"laravel/pint": "1.5.*", "laravel/pint": "1.5.*",
@ -1972,9 +1972,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/utopia-php/abuse/issues", "issues": "https://github.com/utopia-php/abuse/issues",
"source": "https://github.com/utopia-php/abuse/tree/0.31.0" "source": "https://github.com/utopia-php/abuse/tree/0.31.1"
}, },
"time": "2023-08-11T01:17:15+00:00" "time": "2023-08-29T11:07:46+00:00"
}, },
{ {
"name": "utopia-php/analytics", "name": "utopia-php/analytics",
@ -2024,21 +2024,21 @@
}, },
{ {
"name": "utopia-php/audit", "name": "utopia-php/audit",
"version": "0.33.0", "version": "0.33.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/utopia-php/audit.git", "url": "https://github.com/utopia-php/audit.git",
"reference": "6fb82331c58c66cbdb8a419314a687fcb18a1d22" "reference": "c117e8e9ce4e3e1b369e8b5b55b2d6ab3138eadd"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/utopia-php/audit/zipball/6fb82331c58c66cbdb8a419314a687fcb18a1d22", "url": "https://api.github.com/repos/utopia-php/audit/zipball/c117e8e9ce4e3e1b369e8b5b55b2d6ab3138eadd",
"reference": "6fb82331c58c66cbdb8a419314a687fcb18a1d22", "reference": "c117e8e9ce4e3e1b369e8b5b55b2d6ab3138eadd",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=8.0", "php": ">=8.0",
"utopia-php/database": "0.42.*" "utopia-php/database": "0.43.*"
}, },
"require-dev": { "require-dev": {
"laravel/pint": "1.5.*", "laravel/pint": "1.5.*",
@ -2065,9 +2065,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/utopia-php/audit/issues", "issues": "https://github.com/utopia-php/audit/issues",
"source": "https://github.com/utopia-php/audit/tree/0.33.0" "source": "https://github.com/utopia-php/audit/tree/0.33.1"
}, },
"time": "2023-08-11T01:17:28+00:00" "time": "2023-08-29T11:07:40+00:00"
}, },
{ {
"name": "utopia-php/cache", "name": "utopia-php/cache",
@ -2220,16 +2220,16 @@
}, },
{ {
"name": "utopia-php/database", "name": "utopia-php/database",
"version": "0.42.3", "version": "0.43.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/utopia-php/database.git", "url": "https://github.com/utopia-php/database.git",
"reference": "2d52ce8ac92436cd51c36cff2ec7bfdf00c44189" "reference": "fb96fc6c94d5efcd43913c34bece62daba76a5e9"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/2d52ce8ac92436cd51c36cff2ec7bfdf00c44189", "url": "https://api.github.com/repos/utopia-php/database/zipball/fb96fc6c94d5efcd43913c34bece62daba76a5e9",
"reference": "2d52ce8ac92436cd51c36cff2ec7bfdf00c44189", "reference": "fb96fc6c94d5efcd43913c34bece62daba76a5e9",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2271,9 +2271,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/utopia-php/database/issues", "issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/0.42.3" "source": "https://github.com/utopia-php/database/tree/0.43.0"
}, },
"time": "2023-08-25T06:18:31+00:00" "time": "2023-08-29T10:18:39+00:00"
}, },
{ {
"name": "utopia-php/domains", "name": "utopia-php/domains",
@ -5736,16 +5736,16 @@
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
"version": "v1.27.0", "version": "v1.28.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git", "url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a" "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a", "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5760,7 +5760,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.27-dev" "dev-main": "1.28-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -5798,7 +5798,7 @@
"portable" "portable"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0"
}, },
"funding": [ "funding": [
{ {
@ -5814,20 +5814,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-11-03T14:55:06+00:00" "time": "2023-01-26T09:26:14+00:00"
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
"version": "v1.27.0", "version": "v1.28.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git", "url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" "reference": "42292d99c55abe617799667f454222c54c60e229"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229",
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", "reference": "42292d99c55abe617799667f454222c54c60e229",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5842,7 +5842,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.27-dev" "dev-main": "1.28-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -5881,7 +5881,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0"
}, },
"funding": [ "funding": [
{ {
@ -5897,7 +5897,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-11-03T14:55:06+00:00" "time": "2023-07-28T09:04:16+00:00"
}, },
{ {
"name": "textalk/websocket", "name": "textalk/websocket",
@ -6000,16 +6000,16 @@
}, },
{ {
"name": "twig/twig", "name": "twig/twig",
"version": "v3.7.0", "version": "v3.7.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/twigphp/Twig.git", "url": "https://github.com/twigphp/Twig.git",
"reference": "5cf942bbab3df42afa918caeba947f1b690af64b" "reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/5cf942bbab3df42afa918caeba947f1b690af64b", "url": "https://api.github.com/repos/twigphp/Twig/zipball/a0ce373a0ca3bf6c64b9e3e2124aca502ba39554",
"reference": "5cf942bbab3df42afa918caeba947f1b690af64b", "reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -6019,7 +6019,7 @@
}, },
"require-dev": { "require-dev": {
"psr/container": "^1.0|^2.0", "psr/container": "^1.0|^2.0",
"symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" "symfony/phpunit-bridge": "^5.4.9|^6.3"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@ -6055,7 +6055,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/twigphp/Twig/issues", "issues": "https://github.com/twigphp/Twig/issues",
"source": "https://github.com/twigphp/Twig/tree/v3.7.0" "source": "https://github.com/twigphp/Twig/tree/v3.7.1"
}, },
"funding": [ "funding": [
{ {
@ -6067,7 +6067,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-07-26T07:16:09+00:00" "time": "2023-08-28T11:09:02+00:00"
} }
], ],
"aliases": [], "aliases": [],

View file

@ -8,7 +8,6 @@ use Utopia\Database\Document;
class Mail extends Event class Mail extends Event
{ {
protected string $recipient = ''; protected string $recipient = '';
protected string $from = '';
protected string $name = ''; protected string $name = '';
protected string $subject = ''; protected string $subject = '';
protected string $body = ''; protected string $body = '';
@ -66,29 +65,6 @@ class Mail extends Event
return $this->recipient; return $this->recipient;
} }
/**
* Sets from for the mail event.
*
* @param string $from
* @return self
*/
public function setFrom(string $from): self
{
$this->from = $from;
return $this;
}
/**
* Returns from for mail event.
*
* @return string
*/
public function getFrom(): string
{
return $this->from;
}
/** /**
* Sets body for the mail event. * Sets body for the mail event.
* *
@ -342,7 +318,6 @@ class Mail extends Event
public function trigger(): string|bool public function trigger(): string|bool
{ {
return Resque::enqueue($this->queue, $this->class, [ return Resque::enqueue($this->queue, $this->class, [
'from' => $this->from,
'recipient' => $this->recipient, 'recipient' => $this->recipient,
'name' => $this->name, 'name' => $this->name,
'subject' => $this->subject, 'subject' => $this->subject,

View file

@ -189,7 +189,6 @@ class Exception extends \Exception
public const PROJECT_KEY_EXPIRED = 'project_key_expired'; public const PROJECT_KEY_EXPIRED = 'project_key_expired';
public const PROJECT_SMTP_CONFIG_INVALID = 'project_smtp_config_invalid'; public const PROJECT_SMTP_CONFIG_INVALID = 'project_smtp_config_invalid';
public const PROJECT_SMTP_CONFIG_NOT_FOUND = 'project_smtp_config_not_found';
public const PROJECT_TEMPLATE_DEFAULT_DELETION = 'project_template_default_deletion'; public const PROJECT_TEMPLATE_DEFAULT_DELETION = 'project_template_default_deletion';

View file

@ -40,6 +40,12 @@ class ConsoleVariables extends Model
'default' => false, 'default' => false,
'example' => true, 'example' => true,
]) ])
->addRule('_APP_DOMAIN_ENABLED', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Defines if main domain is configured. If so, custom domains can be created.',
'default' => false,
'example' => true,
])
->addRule('_APP_ASSISTANT_ENABLED', [ ->addRule('_APP_ASSISTANT_ENABLED', [
'type' => self::TYPE_BOOLEAN, 'type' => self::TYPE_BOOLEAN,
'description' => 'Defines if AI assistant is enabled.', 'description' => 'Defines if AI assistant is enabled.',

View file

@ -173,12 +173,24 @@ class Project extends Model
'example' => false, 'example' => false,
'array' => false 'array' => false
]) ])
->addRule('smtpSender', [ ->addRule('smtpSenderName', [
'type' => self::TYPE_STRING,
'description' => 'SMTP sender name',
'default' => '',
'example' => 'John Appwrite',
])
->addRule('smtpSenderEmail', [
'type' => self::TYPE_STRING, 'type' => self::TYPE_STRING,
'description' => 'SMTP sender email', 'description' => 'SMTP sender email',
'default' => '', 'default' => '',
'example' => 'john@appwrite.io', 'example' => 'john@appwrite.io',
]) ])
->addRule('smtpReplyTo', [
'type' => self::TYPE_STRING,
'description' => 'SMTP reply to email',
'default' => '',
'example' => 'support@appwrite.io',
])
->addRule('smtpHost', [ ->addRule('smtpHost', [
'type' => self::TYPE_STRING, 'type' => self::TYPE_STRING,
'description' => 'SMTP server host name', 'description' => 'SMTP server host name',
@ -277,7 +289,9 @@ class Project extends Model
// SMTP // SMTP
$smtp = $document->getAttribute('smtp', []); $smtp = $document->getAttribute('smtp', []);
$document->setAttribute('smtpEnabled', $smtp['enabled'] ?? false); $document->setAttribute('smtpEnabled', $smtp['enabled'] ?? false);
$document->setAttribute('smtpSender', $smtp['sender'] ?? ''); $document->setAttribute('smtpSenderEmail', $smtp['senderEmail'] ?? '');
$document->setAttribute('smtpSenderName', $smtp['senderName'] ?? '');
$document->setAttribute('smtpReplyTo', $smtp['replyTo'] ?? '');
$document->setAttribute('smtpHost', $smtp['host'] ?? ''); $document->setAttribute('smtpHost', $smtp['host'] ?? '');
$document->setAttribute('smtpPort', $smtp['port'] ?? ''); $document->setAttribute('smtpPort', $smtp['port'] ?? '');
$document->setAttribute('smtpUsername', $smtp['username'] ?? ''); $document->setAttribute('smtpUsername', $smtp['username'] ?? '');