1
0
Fork 0
mirror of synced 2024-06-28 19:20:25 +12:00

Implement proper behaviour for SMTP sender

This commit is contained in:
Matej Bačo 2023-08-28 14:19:37 +02:00
parent e3576fd460
commit 89c9f8da6a
10 changed files with 204 additions and 109 deletions

View file

@ -671,11 +671,6 @@ return [
'description' => 'Provided SMTP config is invalid. Please check the configured values and try again.',
'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 => [
'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.',

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 8ced2e82dd1cba2c2790c6562211b36f44198d89
Subproject commit e9b113b169f54b879d4d97ce775f5829e0a716ef

View file

@ -1102,6 +1102,18 @@ App::post('/v1/account/sessions/magic-url')
$subject = $customTemplate['subject'] ?? $subject;
$from = $customTemplate['senderName'] ?? $from;
$senderEmail = $customTemplate['senderEmail'] ?? '';
$senderEmail = $senderEmail ?: ($smtp['senderEmail'] ?? '');
$senderEmail = $senderEmail ?: App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM);
$senderName = $customTemplate['senderName'] ?? '';
$senderName = $senderName ?: ($smtp['senderName'] ?? '');
$senderName = $senderName ?: App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
$replyTo = $customTemplate['replyTo'] ?? '';
$replyTo = $replyTo ?: ($smtp['replyTo'] ?? '');
$replyTo = $senderEmail;
$smtp = $project->getAttribute('smtp', []);
$mails
->setSmtpHost($smtp['host'] ?? '')
@ -1109,13 +1121,18 @@ App::post('/v1/account/sessions/magic-url')
->setSmtpUsername($smtp['username'] ?? '')
->setSmtpPassword($smtp['password'] ?? '')
->setSmtpSecure($smtp['secure'] ?? '')
->setSmtpReplyTo($customTemplate['replyTo'] ?? '')
->setSmtpSenderEmail($customTemplate['senderEmail'] ?? '')
->setSmtpSenderName($customTemplate['senderName'] ?? '');
->setSmtpReplyTo($replyTo)
->setSmtpSenderEmail($senderEmail)
->setSmtpSenderName($senderName);
} else {
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
$message->setParam('{{body}}', $body);
$body = $message->render();
$mails
->setSmtpReplyTo(App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM))
->setSmtpSenderEmail(App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM))
->setSmtpSenderName(App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server'));
}
$emailVariables = [
@ -2533,6 +2550,18 @@ App::post('/v1/account/recovery')
$subject = $customTemplate['subject'] ?? $subject;
$from = $customTemplate['senderName'] ?? $from;
$senderEmail = $customTemplate['senderEmail'] ?? '';
$senderEmail = $senderEmail ?: ($smtp['senderEmail'] ?? '');
$senderEmail = $senderEmail ?: App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM);
$senderName = $customTemplate['senderName'] ?? '';
$senderName = $senderName ?: ($smtp['senderName'] ?? '');
$senderName = $senderName ?: App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
$replyTo = $customTemplate['replyTo'] ?? '';
$replyTo = $replyTo ?: ($smtp['replyTo'] ?? '');
$replyTo = $senderEmail;
$smtp = $project->getAttribute('smtp', []);
$mails
->setSmtpHost($smtp['host'] ?? '')
@ -2540,13 +2569,18 @@ App::post('/v1/account/recovery')
->setSmtpUsername($smtp['username'] ?? '')
->setSmtpPassword($smtp['password'] ?? '')
->setSmtpSecure($smtp['secure'] ?? '')
->setSmtpReplyTo($customTemplate['replyTo'] ?? '')
->setSmtpSenderEmail($customTemplate['senderEmail'] ?? '')
->setSmtpSenderName($customTemplate['senderName'] ?? '');
->setSmtpReplyTo($replyTo)
->setSmtpSenderEmail($senderEmail)
->setSmtpSenderName($senderName);
} else {
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
$message->setParam('{{body}}', $body);
$body = $message->render();
$mails
->setSmtpReplyTo(App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM))
->setSmtpSenderEmail(App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM))
->setSmtpSenderName(App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server'));
}
$emailVariables = [
@ -2758,6 +2792,18 @@ App::post('/v1/account/verification')
$subject = $customTemplate['subject'] ?? $subject;
$from = $customTemplate['senderName'] ?? $from;
$senderEmail = $customTemplate['senderEmail'] ?? '';
$senderEmail = $senderEmail ?: ($smtp['senderEmail'] ?? '');
$senderEmail = $senderEmail ?: App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM);
$senderName = $customTemplate['senderName'] ?? '';
$senderName = $senderName ?: ($smtp['senderName'] ?? '');
$senderName = $senderName ?: App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
$replyTo = $customTemplate['replyTo'] ?? '';
$replyTo = $replyTo ?: ($smtp['replyTo'] ?? '');
$replyTo = $senderEmail;
$smtp = $project->getAttribute('smtp', []);
$mails
->setSmtpHost($smtp['host'] ?? '')
@ -2765,13 +2811,18 @@ App::post('/v1/account/verification')
->setSmtpUsername($smtp['username'] ?? '')
->setSmtpPassword($smtp['password'] ?? '')
->setSmtpSecure($smtp['secure'] ?? '')
->setSmtpReplyTo($customTemplate['replyTo'] ?? '')
->setSmtpSenderEmail($customTemplate['senderEmail'] ?? '')
->setSmtpSenderName($customTemplate['senderName'] ?? '');
->setSmtpReplyTo($replyTo)
->setSmtpSenderEmail($senderEmail)
->setSmtpSenderName($senderName);
} else {
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
$message->setParam('{{body}}', $body);
$body = $message->render();
$mails
->setSmtpReplyTo(App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM))
->setSmtpSenderEmail(App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM))
->setSmtpSenderName(App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server'));
}
$emailVariables = [

View file

@ -61,7 +61,7 @@ App::post('/v1/projects')
->param('projectId', '', new ProjectId(), 'Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, and hyphen. Can\'t start with a special char. Max length is 36 chars.')
->param('name', null, new Text(128), 'Project name. Max length: 128 chars.')
->param('teamId', '', new UID(), 'Team unique ID.')
->param('region', App::getEnv('_APP_REGION', 'default'), new Whitelist(array_keys(array_filter(Config::getParam('regions'), fn($config) => !$config['disabled']))), 'Project Region.', true)
->param('region', App::getEnv('_APP_REGION', 'default'), new Whitelist(array_keys(array_filter(Config::getParam('regions'), fn ($config) => !$config['disabled']))), 'Project Region.', true)
->param('description', '', new Text(256), 'Project description. Max length: 256 chars.', true)
->param('logo', '', new Text(1024), 'Project logo.', true)
->param('url', '', new URL(), 'Project URL.', true)
@ -436,17 +436,17 @@ App::patch('/v1/projects/:projectId')
}
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project
->setAttribute('name', $name)
->setAttribute('description', $description)
->setAttribute('logo', $logo)
->setAttribute('url', $url)
->setAttribute('legalName', $legalName)
->setAttribute('legalCountry', $legalCountry)
->setAttribute('legalState', $legalState)
->setAttribute('legalCity', $legalCity)
->setAttribute('legalAddress', $legalAddress)
->setAttribute('legalTaxId', $legalTaxId)
->setAttribute('search', implode(' ', [$projectId, $name])));
->setAttribute('name', $name)
->setAttribute('description', $description)
->setAttribute('logo', $logo)
->setAttribute('url', $url)
->setAttribute('legalName', $legalName)
->setAttribute('legalCountry', $legalCountry)
->setAttribute('legalState', $legalState)
->setAttribute('legalCity', $legalCity)
->setAttribute('legalAddress', $legalAddress)
->setAttribute('legalTaxId', $legalTaxId)
->setAttribute('search', implode(' ', [$projectId, $name])));
$response->dynamic($project, Response::MODEL_PROJECT);
});
@ -479,14 +479,14 @@ App::patch('/v1/projects/:projectId/team')
}
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project
->setAttribute('teamId', $teamId)
->setAttribute('$permissions', [
Permission::read(Role::team(ID::custom($teamId))),
Permission::update(Role::team(ID::custom($teamId), 'owner')),
Permission::update(Role::team(ID::custom($teamId), 'developer')),
Permission::delete(Role::team(ID::custom($teamId), 'owner')),
Permission::delete(Role::team(ID::custom($teamId), 'developer')),
]));
->setAttribute('teamId', $teamId)
->setAttribute('$permissions', [
Permission::read(Role::team(ID::custom($teamId))),
Permission::update(Role::team(ID::custom($teamId), 'owner')),
Permission::update(Role::team(ID::custom($teamId), 'developer')),
Permission::delete(Role::team(ID::custom($teamId), 'owner')),
Permission::delete(Role::team(ID::custom($teamId), 'developer')),
]));
$response->dynamic($project, Response::MODEL_PROJECT);
});
@ -502,7 +502,7 @@ App::patch('/v1/projects/:projectId/service')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_PROJECT)
->param('projectId', '', new UID(), 'Project unique ID.')
->param('service', '', new WhiteList(array_keys(array_filter(Config::getParam('services'), fn($element) => $element['optional'])), true), 'Service name.')
->param('service', '', new WhiteList(array_keys(array_filter(Config::getParam('services'), fn ($element) => $element['optional'])), true), 'Service name.')
->param('status', null, new Boolean(), 'Service status.')
->inject('response')
->inject('dbForConsole')
@ -544,7 +544,7 @@ App::patch('/v1/projects/:projectId/service/all')
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$allServices = array_keys(array_filter(Config::getParam('services'), fn($element) => $element['optional']));
$allServices = array_keys(array_filter(Config::getParam('services'), fn ($element) => $element['optional']));
$services = [];
foreach ($allServices as $service) {
@ -843,8 +843,7 @@ App::delete('/v1/projects/:projectId')
$deletes
->setType(DELETE_TYPE_DOCUMENT)
->setDocument($project)
;
->setDocument($project);
if (!$dbForConsole->deleteDocument('projects', $projectId)) {
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('security', $security)
->setAttribute('httpUser', $httpUser)
->setAttribute('httpPass', $httpPass)
;
->setAttribute('httpPass', $httpPass);
$dbForConsole->updateDocument('webhooks', $webhook->getId(), $webhook);
$dbForConsole->deleteCachedDocument('projects', $project->getId());
@ -1262,8 +1260,7 @@ App::put('/v1/projects/:projectId/keys/:keyId')
$key
->setAttribute('name', $name)
->setAttribute('scopes', $scopes)
->setAttribute('expire', $expire)
;
->setAttribute('expire', $expire);
$dbForConsole->updateDocument('keys', $key->getId(), $key);
@ -1465,8 +1462,7 @@ App::put('/v1/projects/:projectId/platforms/:platformId')
->setAttribute('name', $name)
->setAttribute('key', $key)
->setAttribute('store', $store)
->setAttribute('hostname', $hostname)
;
->setAttribute('hostname', $hostname);
$dbForConsole->updateDocument('platforms', $platform->getId(), $platform);
@ -1525,15 +1521,17 @@ App::patch('/v1/projects/:projectId/smtp')
->label('sdk.response.model', Response::MODEL_PROJECT)
->param('projectId', '', new UID(), 'Project unique ID.')
->param('enabled', false, new Boolean(), 'Enable custom SMTP service')
->param('sender', '', new Email(), 'SMTP sender email')
->param('host', '', new HostName(), 'SMTP server host name')
->param('port', null, new Integer(), 'SMTP server port')
->param('username', null, new Text(0), 'SMTP server username')
->param('password', null, new Text(0), 'SMTP server password')
->param('senderName', '', new Text(255), 'Name of the email sender', true)
->param('senderEmail', '', new Email(), 'Email of the sender', true)
->param('replyTo', '', new Email(), 'Reply to email', true)
->param('host', '', new HostName(), 'SMTP server host name', true)
->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)
->inject('response')
->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);
@ -1541,36 +1539,65 @@ App::patch('/v1/projects/:projectId/smtp')
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
// validate SMTP settings
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Username = $username;
$mail->Password = $password;
$mail->Host = $host;
$mail->Port = $port;
$mail->SMTPSecure = $secure;
$mail->SMTPAutoTLS = false;
$mail->Timeout = 5;
try {
$valid = $mail->SmtpConnect();
if (!$valid) {
throw new Exception('Connection is not valid.');
// 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.');
} else if (empty($senderEmail)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Sender email is required when enabling SMTP.');
} else if (empty($host)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Host is required when enabling SMTP.');
} else if (empty($port)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Port is required when enabling SMTP.');
} else if (empty($username)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Username is required when enabling SMTP.');
} else if (empty($password)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Password is required when enabling SMTP.');
}
} catch (Throwable $error) {
throw new Exception(Exception::PROJECT_SMTP_CONFIG_INVALID, 'Could not connect to SMTP server: ' . $error->getMessage());
}
$smtp = [
'enabled' => $enabled,
'sender' => $sender,
'host' => $host,
'port' => $port,
'username' => $username,
'password' => $password,
'secure' => $secure,
];
// validate SMTP settings
if ($enabled) {
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Username = $username;
$mail->Password = $password;
$mail->Host = $host;
$mail->Port = $port;
$mail->SMTPSecure = $secure;
$mail->SMTPAutoTLS = false;
$mail->Timeout = 5;
try {
$valid = $mail->SmtpConnect();
if (!$valid) {
throw new Exception('Connection is not valid.');
}
} catch (Throwable $error) {
throw new Exception(Exception::PROJECT_SMTP_CONFIG_INVALID, 'Could not connect to SMTP server: ' . $error->getMessage());
}
}
// Save SMTP settings
if ($enabled) {
$smtp = [
'enabled' => $enabled,
'senderName' => $senderName,
'senderEmail' => $senderEmail,
'replyTo' => $replyTo,
'host' => $host,
'port' => $port,
'username' => $username,
'password' => $password,
'secure' => $secure,
];
} else {
$smtp = [
'enabled' => false
];
}
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project->setAttribute('smtp', $smtp));
@ -1589,7 +1616,7 @@ App::get('/v1/projects/:projectId/templates/sms/:type/:locale')
->label('sdk.response.model', Response::MODEL_SMS_TEMPLATE)
->param('projectId', '', new UID(), 'Project unique ID.')
->param('type', '', new WhiteList(Config::getParam('locale-templates')['sms'] ?? []), 'Template type')
->param('locale', '', fn($localeCodes) => new WhiteList($localeCodes), 'Template locale', false, ['localeCodes'])
->param('locale', '', fn ($localeCodes) => new WhiteList($localeCodes), 'Template locale', false, ['localeCodes'])
->inject('response')
->inject('dbForConsole')
->action(function (string $projectId, string $type, string $locale, Response $response, Database $dbForConsole) {
@ -1607,7 +1634,7 @@ App::get('/v1/projects/:projectId/templates/sms/:type/:locale')
if (is_null($template)) {
$template = [
'message' => Template::fromFile(__DIR__ . '/../../config/locale/templates/sms-base.tpl')->render(),
'message' => Template::fromFile(__DIR__ . '/../../config/locale/templates/sms-base.tpl')->render(),
];
}
@ -1629,7 +1656,7 @@ App::get('/v1/projects/:projectId/templates/email/:type/:locale')
->label('sdk.response.model', Response::MODEL_EMAIL_TEMPLATE)
->param('projectId', '', new UID(), 'Project unique ID.')
->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'])
->inject('response')
->inject('dbForConsole')
->action(function (string $projectId, string $type, string $locale, Response $response, Database $dbForConsole) {
@ -1684,7 +1711,7 @@ App::patch('/v1/projects/:projectId/templates/sms/:type/:locale')
->label('sdk.response.model', Response::MODEL_SMS_TEMPLATE)
->param('projectId', '', new UID(), 'Project unique ID.')
->param('type', '', new WhiteList(Config::getParam('locale-templates')['sms'] ?? []), '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('message', '', new Text(0), 'Template message')
->inject('response')
->inject('dbForConsole')
@ -1698,8 +1725,6 @@ App::patch('/v1/projects/:projectId/templates/sms/:type/:locale')
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
// TODO: Ensure SMS is enabled on project
$templates = $project->getAttribute('templates', []);
$templates['sms.' . $type . '-' . $locale] = [
'message' => $message
@ -1726,15 +1751,15 @@ App::patch('/v1/projects/:projectId/templates/email/:type/:locale')
->label('sdk.response.model', Response::MODEL_PROJECT)
->param('projectId', '', new UID(), 'Project unique ID.')
->param('type', '', new WhiteList(Config::getParam('locale-templates')['email'] ?? []), 'Template type')
->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('locale', '', fn ($localeCodes) => new WhiteList($localeCodes), 'Template locale', false, ['localeCodes'])
->param('subject', '', new Text(255), 'Email Subject')
->param('message', '', new Text(0), 'Template message')
->param('senderName', '', new Text(255), 'Name of the email sender', true)
->param('senderEmail', '', new Email(), 'Email of the sender', true)
->param('replyTo', '', new Email(), 'Reply to email', true)
->inject('response')
->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);
@ -1742,11 +1767,6 @@ App::patch('/v1/projects/:projectId/templates/email/:type/:locale')
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['email.' . $type . '-' . $locale] = [
'senderName' => $senderName,
@ -1781,7 +1801,7 @@ App::delete('/v1/projects/:projectId/templates/sms/:type/:locale')
->label('sdk.response.model', Response::MODEL_SMS_TEMPLATE)
->param('projectId', '', new UID(), 'Project unique ID.')
->param('type', '', new WhiteList(Config::getParam('locale-templates')['sms'] ?? []), 'Template type')
->param('locale', '', fn($localeCodes) => new WhiteList($localeCodes), 'Template locale', false, ['localeCodes'])
->param('locale', '', fn ($localeCodes) => new WhiteList($localeCodes), 'Template locale', false, ['localeCodes'])
->inject('response')
->inject('dbForConsole')
->action(function (string $projectId, string $type, string $locale, Response $response, Database $dbForConsole) {
@ -1824,7 +1844,7 @@ App::delete('/v1/projects/:projectId/templates/email/:type/:locale')
->label('sdk.response.model', Response::MODEL_EMAIL_TEMPLATE)
->param('projectId', '', new UID(), 'Project unique ID.')
->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'])
->inject('response')
->inject('dbForConsole')
->action(function (string $projectId, string $type, string $locale, Response $response, Database $dbForConsole) {

View file

@ -554,6 +554,18 @@ App::post('/v1/teams/:teamId/memberships')
$subject = $customTemplate['subject'] ?? $subject;
$from = $customTemplate['senderName'] ?? $from;
$senderEmail = $customTemplate['senderEmail'] ?? '';
$senderEmail = $senderEmail ?: ($smtp['senderEmail'] ?? '');
$senderEmail = $senderEmail ?: App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM);
$senderName = $customTemplate['senderName'] ?? '';
$senderName = $senderName ?: ($smtp['senderName'] ?? '');
$senderName = $senderName ?: App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
$replyTo = $customTemplate['replyTo'] ?? '';
$replyTo = $replyTo ?: ($smtp['replyTo'] ?? '');
$replyTo = $senderEmail;
$smtp = $project->getAttribute('smtp', []);
$mails
->setSmtpHost($smtp['host'] ?? '')
@ -561,13 +573,18 @@ App::post('/v1/teams/:teamId/memberships')
->setSmtpUsername($smtp['username'] ?? '')
->setSmtpPassword($smtp['password'] ?? '')
->setSmtpSecure($smtp['secure'] ?? '')
->setSmtpReplyTo($customTemplate['replyTo'] ?? '')
->setSmtpSenderEmail($customTemplate['senderEmail'] ?? '')
->setSmtpSenderName($customTemplate['senderName'] ?? '');
->setSmtpReplyTo($replyTo)
->setSmtpSenderEmail($senderEmail)
->setSmtpSenderName($senderName);
} else {
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
$message->setParam('{{body}}', $body);
$body = $message->render();
$mails
->setSmtpReplyTo(App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM))
->setSmtpSenderEmail(App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM))
->setSmtpSenderName(App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server'));
}
$emailVariables = [

View file

@ -62,6 +62,11 @@ class MailsV1 extends Worker
$mail->Body = $body;
$mail->AltBody = \strip_tags($body);
$mail->setFrom($smtp['senderEmail'], $smtp['senderName']);
if (!empty($smtp['replyTo'])) {
$mail->addReplyTo($smtp['replyTo'], $smtp['senderName']);
}
try {
$mail->send();
} catch (\Exception $error) {
@ -88,12 +93,6 @@ class MailsV1 extends Worker
$mail->SMTPAutoTLS = false;
$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);
return $mail;

View file

@ -189,7 +189,6 @@ class Exception extends \Exception
public const PROJECT_KEY_EXPIRED = 'project_key_expired';
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';

View file

@ -173,12 +173,24 @@ class Project extends Model
'example' => 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,
'description' => 'SMTP sender email',
'default' => '',
'example' => 'john@appwrite.io',
])
->addRule('smtpReplyTo', [
'type' => self::TYPE_STRING,
'description' => 'SMTP reply to email',
'default' => '',
'example' => 'support@appwrite.io',
])
->addRule('smtpHost', [
'type' => self::TYPE_STRING,
'description' => 'SMTP server host name',
@ -277,7 +289,9 @@ class Project extends Model
// SMTP
$smtp = $document->getAttribute('smtp', []);
$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('smtpPort', $smtp['port'] ?? '');
$document->setAttribute('smtpUsername', $smtp['username'] ?? '');