Merge pull request #7641 from appwrite/fix-mfa-email-templates-1.5.x
fix: email templates
This commit is contained in:
commit
5fdeedb5b4
7 changed files with 175 additions and 41 deletions
|
@ -6,10 +6,12 @@ return [
|
||||||
'magicSession',
|
'magicSession',
|
||||||
'recovery',
|
'recovery',
|
||||||
'invitation',
|
'invitation',
|
||||||
|
'mfaChallenge'
|
||||||
],
|
],
|
||||||
'sms' => [
|
'sms' => [
|
||||||
'verification',
|
'verification',
|
||||||
'login',
|
'login',
|
||||||
'invitation'
|
'invitation',
|
||||||
|
'mfaChallenge'
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<p>{{hello}}</p>
|
<p>{{hello}},</p>
|
||||||
|
|
||||||
<p>{{optionButton}}</p>
|
<p>{{optionButton}}</p>
|
||||||
|
|
||||||
|
|
16
app/config/locale/templates/email-mfa-challenge.tpl
Normal file
16
app/config/locale/templates/email-mfa-challenge.tpl
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<p>{{hello}},</p>
|
||||||
|
|
||||||
|
<p>{{description}}</p>
|
||||||
|
|
||||||
|
<table border="0" cellspacing="0" cellpadding="0" style="padding-top: 10px; padding-bottom: 10px; display: inline-block;">
|
||||||
|
<tr>
|
||||||
|
<td align="center" style="border-radius: 8px; background-color: #ffffff;">
|
||||||
|
<p style="font-size: 24px; text-indent: 18px; letter-spacing: 18px; font-family: Inter; color: #414146; text-decoration: none; border-radius: 8px; padding: 24px 12px; border: 1px solid #EDEDF0; display: inline-block; font-weight: bold; ">{{otp}}</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p>{{clientInfo}}</p>
|
||||||
|
|
||||||
|
<p style="margin-bottom: 0px;">{{thanks}}</p>
|
||||||
|
<p style="margin-top: 0px;">{{signature}}</p>
|
|
@ -1,4 +1,4 @@
|
||||||
<p>{{hello}}</p>
|
<p>{{hello}},</p>
|
||||||
|
|
||||||
<p>{{description}}</p>
|
<p>{{description}}</p>
|
||||||
|
|
||||||
|
|
|
@ -4,36 +4,42 @@
|
||||||
"settings.direction": "ltr",
|
"settings.direction": "ltr",
|
||||||
"emails.sender": "%s Team",
|
"emails.sender": "%s Team",
|
||||||
"emails.verification.subject": "Account Verification",
|
"emails.verification.subject": "Account Verification",
|
||||||
"emails.verification.hello": "Hey {{user}}",
|
"emails.verification.hello": "Hello {{user}}",
|
||||||
"emails.verification.body": "Follow this link to verify your email address.",
|
"emails.verification.body": "Follow this link to verify your email address to your {{b}}{{project}}{{/b}} account.",
|
||||||
"emails.verification.footer": "If you didn’t ask to verify this address, you can ignore this message.",
|
"emails.verification.footer": "If you didn’t ask to verify this address, you can ignore this message.",
|
||||||
"emails.verification.thanks": "Thanks",
|
"emails.verification.thanks": "Thanks",
|
||||||
"emails.verification.signature": "{{project}} team",
|
"emails.verification.signature": "{{project}} team",
|
||||||
"emails.magicSession.subject": "{{project}} Login",
|
"emails.magicSession.subject": "{{project}} Login",
|
||||||
"emails.magicSession.hello": "Hello,",
|
"emails.magicSession.hello": "Hello {{user}}",
|
||||||
"emails.magicSession.optionButton": "Click the button below to securely sign in to your {{project}} account. This link will expire in 1 hour.",
|
"emails.magicSession.optionButton": "Click the button below to securely sign in to your {{b}}{{project}}{{/b}} account. This link will expire in 1 hour.",
|
||||||
"emails.magicSession.buttonText": "Sign in to {{project}}",
|
"emails.magicSession.buttonText": "Sign in to {{project}}",
|
||||||
"emails.magicSession.optionUrl": "If you are unable to sign in using the button above, please visit the following link:",
|
"emails.magicSession.optionUrl": "If you are unable to sign in using the button above, please visit the following link:",
|
||||||
"emails.magicSession.clientInfo": "This sign in was requested using {{agentClient}} on {{agentDevice}} {{agentOs}}. If you didn't request the sign in, you can safely ignore this email.",
|
"emails.magicSession.clientInfo": "This sign in was requested using {{b}}{{agentClient}}{{/b}} on {{b}}{{agentDevice}}{{/b}} {{b}}{{agentOs}}{{/b}}. If you didn't request the sign in, you can safely ignore this email.",
|
||||||
"emails.magicSession.securityPhrase": "Security phrase for this email is {{phrase}}. You can trust this email if this phrase matches the phrase shown during sign in.",
|
"emails.magicSession.securityPhrase": "Security phrase for this email is {{b}}{{phrase}}{{/b}}. You can trust this email if this phrase matches the phrase shown during sign in.",
|
||||||
"emails.magicSession.thanks": "Thanks,",
|
"emails.magicSession.thanks": "Thanks,",
|
||||||
"emails.magicSession.signature": "{{project}} team",
|
"emails.magicSession.signature": "{{project}} team",
|
||||||
"emails.otpSession.subject": "OTP for {{project}} Login",
|
"emails.otpSession.subject": "OTP for {{project}} Login",
|
||||||
"emails.otpSession.hello": "Hello,",
|
"emails.otpSession.hello": "Hello {{user}}",
|
||||||
"emails.otpSession.description": "Enter the following verification code when prompted to securely sign in to your {{project}} account. This code will expire in 15 minutes.",
|
"emails.otpSession.description": "Enter the following verification code when prompted to securely sign in to your {{b}}{{project}}{{/b}} account. This code will expire in 15 minutes.",
|
||||||
"emails.otpSession.clientInfo": "This sign in was requested using {{agentClient}} on {{agentDevice}} {{agentOs}}. If you didn't request the sign in, you can safely ignore this email.",
|
"emails.otpSession.clientInfo": "This sign in was requested using {{b}}{{agentClient}}{{/b}} on {{b}}{{agentDevice}}{{/b}} {{b}}{{agentOs}}{{/b}}. If you didn't request the sign in, you can safely ignore this email.",
|
||||||
"emails.otpSession.securityPhrase": "Security phrase for this email is {{phrase}}. You can trust this email if this phrase matches the phrase shown during sign in.",
|
"emails.otpSession.securityPhrase": "Security phrase for this email is {{b}}{{phrase}}{{/b}}. You can trust this email if this phrase matches the phrase shown during sign in.",
|
||||||
"emails.otpSession.thanks": "Thanks,",
|
"emails.otpSession.thanks": "Thanks,",
|
||||||
"emails.otpSession.signature": "{{project}} team",
|
"emails.otpSession.signature": "{{project}} team",
|
||||||
|
"emails.mfaChallenge.subject": "Verification Code for {{project}}",
|
||||||
|
"emails.mfaChallenge.hello": "Hello {{user}}",
|
||||||
|
"emails.mfaChallenge.description": "Enter the following verification code to verify your email and activate two-step verification in {{b}}{{project}}{{/b}}. This code will expire in 15 minutes.",
|
||||||
|
"emails.mfaChallenge.clientInfo": "This verification code was requested using {{b}}{{agentClient}}{{/b}} on {{b}}{{agentDevice}}{{/b}} {{b}}{{agentOs}}{{/b}}. If you didn't request the verification code, you can safely ignore this email.",
|
||||||
|
"emails.mfaChallenge.thanks": "Thanks,",
|
||||||
|
"emails.mfaChallenge.signature": "{{project}} team",
|
||||||
"emails.recovery.subject": "Password Reset",
|
"emails.recovery.subject": "Password Reset",
|
||||||
"emails.recovery.hello": "Hello {{user}}",
|
"emails.recovery.hello": "Hello {{user}}",
|
||||||
"emails.recovery.body": "Follow this link to reset your {{project}} password.",
|
"emails.recovery.body": "Follow this link to reset your {{b}}{{project}}{{/b}} password.",
|
||||||
"emails.recovery.footer": "If you didn’t ask to reset your password, you can ignore this message.",
|
"emails.recovery.footer": "If you didn’t ask to reset your password, you can ignore this message.",
|
||||||
"emails.recovery.thanks": "Thanks",
|
"emails.recovery.thanks": "Thanks",
|
||||||
"emails.recovery.signature": "{{project}} team",
|
"emails.recovery.signature": "{{project}} team",
|
||||||
"emails.invitation.subject": "Invitation to %s Team at %s",
|
"emails.invitation.subject": "Invitation to %s Team at %s",
|
||||||
"emails.invitation.hello": "Hello",
|
"emails.invitation.hello": "Hello {{user}}",
|
||||||
"emails.invitation.body": "This mail was sent to you because {{owner}} wanted to invite you to become a member of the {{team}} team at {{project}}.",
|
"emails.invitation.body": "This mail was sent to you because {{b}}{{owner}}{{/b}} wanted to invite you to become a member of the {{b}}{{team}}{{/b}} team at {{b}}{{project}}{{/b}}.",
|
||||||
"emails.invitation.footer": "If you are not interested, you can ignore this message.",
|
"emails.invitation.footer": "If you are not interested, you can ignore this message.",
|
||||||
"emails.invitation.thanks": "Thanks",
|
"emails.invitation.thanks": "Thanks",
|
||||||
"emails.invitation.signature": "{{project}} team",
|
"emails.invitation.signature": "{{project}} team",
|
||||||
|
|
|
@ -1259,15 +1259,16 @@ App::post('/v1/account/tokens/magic-url')
|
||||||
|
|
||||||
$emailVariables = [
|
$emailVariables = [
|
||||||
'direction' => $locale->getText('settings.direction'),
|
'direction' => $locale->getText('settings.direction'),
|
||||||
/* {{user}}, {{team}}, {{redirect}} and {{project}} are required in default and custom templates */
|
// {{user}}, {{redirect}} and {{project}} are required in default and custom templates
|
||||||
'user' => '',
|
'user' => $user->getAttribute('name'),
|
||||||
'team' => '',
|
|
||||||
'project' => $project->getAttribute('name'),
|
'project' => $project->getAttribute('name'),
|
||||||
'redirect' => $url,
|
'redirect' => $url,
|
||||||
'agentDevice' => '<strong>' . ( $agentDevice['deviceBrand'] ?? $agentDevice['deviceBrand'] ?? 'UNKNOWN') . '</strong>',
|
'agentDevice' => $agentDevice['deviceBrand'] ?? $agentDevice['deviceBrand'] ?? 'UNKNOWN',
|
||||||
'agentClient' => '<strong>' . ($agentClient['clientName'] ?? 'UNKNOWN') . '</strong>',
|
'agentClient' => $agentClient['clientName'] ?? 'UNKNOWN',
|
||||||
'agentOs' => '<strong>' . ($agentOs['osName'] ?? 'UNKNOWN') . '</strong>',
|
'agentOs' => $agentOs['osName'] ?? 'UNKNOWN',
|
||||||
'phrase' => '<strong>' . (!empty($phrase) ? $phrase : '') . '</strong>'
|
'phrase' => !empty($phrase) ? $phrase : '',
|
||||||
|
// TODO: remove unnecessary team variable from this email
|
||||||
|
'team' => '',
|
||||||
];
|
];
|
||||||
|
|
||||||
$queueForMails
|
$queueForMails
|
||||||
|
@ -1487,15 +1488,16 @@ App::post('/v1/account/tokens/email')
|
||||||
|
|
||||||
$emailVariables = [
|
$emailVariables = [
|
||||||
'direction' => $locale->getText('settings.direction'),
|
'direction' => $locale->getText('settings.direction'),
|
||||||
/* {{user}} ,{{team}}, {{project}} and {{otp}} are required in the templates */
|
// {{user}}, {{project}} and {{otp}} are required in the templates
|
||||||
'user' => '',
|
'user' => $user->getAttribute('name'),
|
||||||
'team' => '',
|
|
||||||
'project' => $project->getAttribute('name'),
|
'project' => $project->getAttribute('name'),
|
||||||
'otp' => $tokenSecret,
|
'otp' => $tokenSecret,
|
||||||
'agentDevice' => '<strong>' . ( $agentDevice['deviceBrand'] ?? $agentDevice['deviceBrand'] ?? 'UNKNOWN') . '</strong>',
|
'agentDevice' => $agentDevice['deviceBrand'] ?? $agentDevice['deviceBrand'] ?? 'UNKNOWN',
|
||||||
'agentClient' => '<strong>' . ($agentClient['clientName'] ?? 'UNKNOWN') . '</strong>',
|
'agentClient' => $agentClient['clientName'] ?? 'UNKNOWN',
|
||||||
'agentOs' => '<strong>' . ($agentOs['osName'] ?? 'UNKNOWN') . '</strong>',
|
'agentOs' => $agentOs['osName'] ?? 'UNKNOWN',
|
||||||
'phrase' => '<strong>' . (!empty($phrase) ? $phrase : '') . '</strong>'
|
'phrase' => !empty($phrase) ? $phrase : '',
|
||||||
|
// TODO: remove unnecessary team variable from this email
|
||||||
|
'team' => '',
|
||||||
];
|
];
|
||||||
|
|
||||||
$queueForMails
|
$queueForMails
|
||||||
|
@ -2953,11 +2955,12 @@ App::post('/v1/account/recovery')
|
||||||
|
|
||||||
$emailVariables = [
|
$emailVariables = [
|
||||||
'direction' => $locale->getText('settings.direction'),
|
'direction' => $locale->getText('settings.direction'),
|
||||||
/* {{user}}, {{team}}, {{redirect}} and {{project}} are required in default and custom templates */
|
// {{user}}, {{redirect}} and {{project}} are required in default and custom templates
|
||||||
'user' => $profile->getAttribute('name'),
|
'user' => $profile->getAttribute('name'),
|
||||||
'team' => '',
|
|
||||||
'redirect' => $url,
|
'redirect' => $url,
|
||||||
'project' => $projectName
|
'project' => $projectName,
|
||||||
|
// TODO: remove unnecessary team variable from this email
|
||||||
|
'team' => ''
|
||||||
];
|
];
|
||||||
|
|
||||||
$queueForMails
|
$queueForMails
|
||||||
|
@ -3200,11 +3203,12 @@ App::post('/v1/account/verification')
|
||||||
|
|
||||||
$emailVariables = [
|
$emailVariables = [
|
||||||
'direction' => $locale->getText('settings.direction'),
|
'direction' => $locale->getText('settings.direction'),
|
||||||
/* {{user}}, {{team}}, {{redirect}} and {{project}} are required in default and custom templates */
|
// {{user}}, {{redirect}} and {{project}} are required in default and custom templates
|
||||||
'user' => $user->getAttribute('name'),
|
'user' => $user->getAttribute('name'),
|
||||||
'team' => '',
|
|
||||||
'redirect' => $url,
|
'redirect' => $url,
|
||||||
'project' => $projectName
|
'project' => $projectName,
|
||||||
|
// TODO: remove unnecessary team variable from this email
|
||||||
|
'team' => '',
|
||||||
];
|
];
|
||||||
|
|
||||||
$queueForMails
|
$queueForMails
|
||||||
|
@ -3707,11 +3711,13 @@ App::post('/v1/account/mfa/challenge')
|
||||||
->inject('response')
|
->inject('response')
|
||||||
->inject('dbForProject')
|
->inject('dbForProject')
|
||||||
->inject('user')
|
->inject('user')
|
||||||
|
->inject('locale')
|
||||||
|
->inject('project')
|
||||||
|
->inject('request')
|
||||||
->inject('queueForEvents')
|
->inject('queueForEvents')
|
||||||
->inject('queueForMessaging')
|
->inject('queueForMessaging')
|
||||||
->inject('queueForMails')
|
->inject('queueForMails')
|
||||||
->inject('locale')
|
->action(function (string $factor, Response $response, Database $dbForProject, Document $user, Locale $locale, Document $project, Request $request, Event $queueForEvents, Messaging $queueForMessaging, Mail $queueForMails) {
|
||||||
->action(function (string $factor, Response $response, Database $dbForProject, Document $user, Event $queueForEvents, Messaging $queueForMessaging, Mail $queueForMails, Locale $locale) {
|
|
||||||
|
|
||||||
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_CONFIRM);
|
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_CONFIRM);
|
||||||
$code = Auth::codeGenerator();
|
$code = Auth::codeGenerator();
|
||||||
|
@ -3743,6 +3749,22 @@ App::post('/v1/account/mfa/challenge')
|
||||||
throw new Exception(Exception::USER_PHONE_NOT_VERIFIED);
|
throw new Exception(Exception::USER_PHONE_NOT_VERIFIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/sms-base.tpl');
|
||||||
|
|
||||||
|
$customTemplate = $project->getAttribute('templates', [])['sms.mfaChallenge-' . $locale->default] ?? [];
|
||||||
|
if (!empty($customTemplate)) {
|
||||||
|
$message = $customTemplate['message'] ?? $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
$messageContent = Template::fromString($locale->getText("sms.verification.body"));
|
||||||
|
$messageContent
|
||||||
|
->setParam('{{project}}', $project->getAttribute('name'))
|
||||||
|
->setParam('{{secret}}', $code);
|
||||||
|
$messageContent = \strip_tags($messageContent->render());
|
||||||
|
$message = $message->setParam('{{token}}', $messageContent);
|
||||||
|
|
||||||
|
$message = $message->render();
|
||||||
|
|
||||||
$queueForMessaging
|
$queueForMessaging
|
||||||
->setType(MESSAGE_SEND_TYPE_INTERNAL)
|
->setType(MESSAGE_SEND_TYPE_INTERNAL)
|
||||||
->setMessage(new Document([
|
->setMessage(new Document([
|
||||||
|
@ -3751,7 +3773,8 @@ App::post('/v1/account/mfa/challenge')
|
||||||
'content' => $code,
|
'content' => $code,
|
||||||
],
|
],
|
||||||
]))
|
]))
|
||||||
->setRecipients([$user->getAttribute('phone')]);
|
->setRecipients([$user->getAttribute('phone')])
|
||||||
|
->setProviderType(MESSAGE_TYPE_SMS);
|
||||||
break;
|
break;
|
||||||
case 'email':
|
case 'email':
|
||||||
if (empty(App::getEnv('_APP_SMTP_HOST'))) {
|
if (empty(App::getEnv('_APP_SMTP_HOST'))) {
|
||||||
|
@ -3764,9 +3787,85 @@ App::post('/v1/account/mfa/challenge')
|
||||||
throw new Exception(Exception::USER_EMAIL_NOT_VERIFIED);
|
throw new Exception(Exception::USER_EMAIL_NOT_VERIFIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$subject = $locale->getText("emails.mfaChallenge.subject");
|
||||||
|
$customTemplate = $project->getAttribute('templates', [])['email.mfaChallenge-' . $locale->default] ?? [];
|
||||||
|
|
||||||
|
$detector = new Detector($request->getUserAgent('UNKNOWN'));
|
||||||
|
$agentOs = $detector->getOS();
|
||||||
|
$agentClient = $detector->getClient();
|
||||||
|
$agentDevice = $detector->getDevice();
|
||||||
|
|
||||||
|
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-mfa-challenge.tpl');
|
||||||
|
$message
|
||||||
|
->setParam('{{hello}}', $locale->getText("emails.mfaChallenge.hello"))
|
||||||
|
->setParam('{{description}}', $locale->getText("emails.mfaChallenge.description"))
|
||||||
|
->setParam('{{clientInfo}}', $locale->getText("emails.mfaChallenge.clientInfo"))
|
||||||
|
->setParam('{{thanks}}', $locale->getText("emails.mfaChallenge.thanks"))
|
||||||
|
->setParam('{{signature}}', $locale->getText("emails.mfaChallenge.signature"));
|
||||||
|
|
||||||
|
$body = $message->render();
|
||||||
|
|
||||||
|
$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'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$queueForMails
|
||||||
|
->setSmtpHost($smtp['host'] ?? '')
|
||||||
|
->setSmtpPort($smtp['port'] ?? '')
|
||||||
|
->setSmtpUsername($smtp['username'] ?? '')
|
||||||
|
->setSmtpPassword($smtp['password'] ?? '')
|
||||||
|
->setSmtpSecure($smtp['secure'] ?? '');
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$queueForMails
|
||||||
|
->setSmtpReplyTo($replyTo)
|
||||||
|
->setSmtpSenderEmail($senderEmail)
|
||||||
|
->setSmtpSenderName($senderName);
|
||||||
|
}
|
||||||
|
|
||||||
|
$emailVariables = [
|
||||||
|
'direction' => $locale->getText('settings.direction'),
|
||||||
|
// {{user}}, {{project}} and {{otp}} are required in the templates
|
||||||
|
'user' => $user->getAttribute('name'),
|
||||||
|
'project' => $project->getAttribute('name'),
|
||||||
|
'otp' => $code,
|
||||||
|
'agentDevice' => $agentDevice['deviceBrand'] ?? $agentDevice['deviceBrand'] ?? 'UNKNOWN',
|
||||||
|
'agentClient' => $agentClient['clientName'] ?? 'UNKNOWN',
|
||||||
|
'agentOs' => $agentOs['osName'] ?? 'UNKNOWN'
|
||||||
|
];
|
||||||
|
|
||||||
$queueForMails
|
$queueForMails
|
||||||
->setSubject("{$code} is your 6-digit code")
|
->setSubject($subject)
|
||||||
->setBody($code)
|
->setBody($body)
|
||||||
|
->setVariables($emailVariables)
|
||||||
->setRecipient($user->getAttribute('email'))
|
->setRecipient($user->getAttribute('email'))
|
||||||
->trigger();
|
->trigger();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -32,6 +32,14 @@ class Mails extends Action
|
||||||
->callback(fn (Message $message, Registry $register, Log $log) => $this->action($message, $register, $log));
|
->callback(fn (Message $message, Registry $register, Log $log) => $this->action($message, $register, $log));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array<string, string>
|
||||||
|
*/
|
||||||
|
protected array $richTextParams = [
|
||||||
|
'b' => '<strong>',
|
||||||
|
'/b' => '</strong>',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Message $message
|
* @param Message $message
|
||||||
* @param Registry $register
|
* @param Registry $register
|
||||||
|
@ -81,6 +89,9 @@ class Mails extends Action
|
||||||
// TODO: hotfix for redirect param
|
// TODO: hotfix for redirect param
|
||||||
$bodyTemplate->setParam('{{' . $key . '}}', $value, escapeHtml: $key !== 'redirect');
|
$bodyTemplate->setParam('{{' . $key . '}}', $value, escapeHtml: $key !== 'redirect');
|
||||||
}
|
}
|
||||||
|
foreach ($this->richTextParams as $key => $value) {
|
||||||
|
$bodyTemplate->setParam('{{' . $key . '}}', $value, escapeHtml: false);
|
||||||
|
}
|
||||||
$body = $bodyTemplate->render();
|
$body = $bodyTemplate->render();
|
||||||
|
|
||||||
$subjectTemplate = Template::fromString($subject);
|
$subjectTemplate = Template::fromString($subject);
|
||||||
|
|
Loading…
Reference in a new issue