|
{{body}}
diff --git a/app/config/locale/templates/email-base.tpl b/app/config/locale/templates/email-base.tpl
index 8c94c3f63e..5153b3e4fc 100644
--- a/app/config/locale/templates/email-base.tpl
+++ b/app/config/locale/templates/email-base.tpl
@@ -44,6 +44,21 @@
color: currentColor;
word-break: break-all;
}
+ a.button {
+ box-sizing: border-box;
+ display: inline-block;
+ text-align: center;
+ text-decoration: none;
+ padding: 9px 14px;
+ color: #ffffff;
+ background-color: #2D2D31;
+ border: 1px solid #414146;
+ border-radius: 8px;
+ }
+ a.button:hover,
+ a.button:focus {
+ opacity: 0.8;
+ }
table {
width: 100%;
border-spacing: 0 !important;
diff --git a/app/config/locale/templates/email-inner-base.tpl b/app/config/locale/templates/email-inner-base.tpl
index 677f70ce7d..4b68f224db 100644
--- a/app/config/locale/templates/email-inner-base.tpl
+++ b/app/config/locale/templates/email-inner-base.tpl
@@ -1,6 +1,6 @@
{{hello}}
{{body}}
-{{buttonText}}
+{{buttonText}}
{{footer}}
{{thanks}}
diff --git a/app/config/locale/templates/email-magic-url.tpl b/app/config/locale/templates/email-magic-url.tpl
index 21988c5bc1..618993e0e9 100644
--- a/app/config/locale/templates/email-magic-url.tpl
+++ b/app/config/locale/templates/email-magic-url.tpl
@@ -5,7 +5,7 @@
diff --git a/app/config/locale/templates/email-verification.tpl b/app/config/locale/templates/email-verification.tpl
deleted file mode 100644
index 4b68f224db..0000000000
--- a/app/config/locale/templates/email-verification.tpl
+++ /dev/null
@@ -1,9 +0,0 @@
-{{hello}}
-{{body}}
-{{buttonText}}
-{{footer}}
-
- {{thanks}}
-
- {{signature}}
-
\ No newline at end of file
diff --git a/app/config/locale/translations/en.json b/app/config/locale/translations/en.json
index e2ee20b2d7..69328e61a7 100644
--- a/app/config/locale/translations/en.json
+++ b/app/config/locale/translations/en.json
@@ -5,6 +5,7 @@
"emails.sender": "{{project}} Team",
"emails.verification.subject": "Account Verification",
"emails.verification.preview": "Verify your email to activate your {{project}} account.",
+ "emails.verification.heading": "Verify your email to start using Appwrite Cloud",
"emails.verification.hello": "Hello {{user}},",
"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.",
@@ -33,6 +34,7 @@
"emails.sessionAlert.signature": "{{project}} team",
"emails.otpSession.subject": "OTP for {{project}} Login",
"emails.otpSession.preview": "Use OTP {{otp}} to sign in to {{project}}. Expires in 15 minutes.",
+ "emails.otpSession.heading": "Login with OTP to use Appwrite Cloud",
"emails.otpSession.hello": "Hello {{user}},",
"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 {{b}}{{agentClient}}{{/b}} on {{b}}{{agentDevice}}{{/b}} {{b}}{{agentOs}}{{/b}}. If you didn't request the sign in, you can safely ignore this email.",
@@ -41,6 +43,7 @@
"emails.otpSession.signature": "{{project}} team",
"emails.mfaChallenge.subject": "Verification Code for {{project}}",
"emails.mfaChallenge.preview": "Use code {{otp}} for two-step verification in {{project}}. Expires in 15 minutes.",
+ "emails.mfaChallenge.heading": "Complete two-step verification to use Appwrite Cloud",
"emails.mfaChallenge.hello": "Hello {{user}},",
"emails.mfaChallenge.description": "Enter the following code to confirm your 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.",
diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php
index 3aa9678a72..e98376dfc7 100644
--- a/app/controllers/api/account.php
+++ b/app/controllers/api/account.php
@@ -2296,11 +2296,11 @@ App::post('/v1/account/tokens/email')
$subject = $locale->getText("emails.otpSession.subject");
$preview = $locale->getText("emails.otpSession.preview");
- $customTemplate = $project->getAttribute('templates', [])['email.otpSession-' . $locale->default] ?? [];
+ $heading = $locale->getText("emails.otpSession.heading");
- $customEmails = $project->getAttribute('customEmails', false);
- $bodyTemplate = '';
- $heading = '';
+ $customTemplate = $project->getAttribute('templates', [])['email.otpSession-' . $locale->default] ?? [];
+ $smtpBaseTemplate = $project->getAttribute('smtpBaseTemplate', 'email-base');
+ $bodyTemplate = __DIR__ . '/../../config/locale/templates/' . $smtpBaseTemplate . '.tpl';
$detector = new Detector($request->getUserAgent('UNKNOWN'));
$agentOs = $detector->getOS();
@@ -2369,23 +2369,6 @@ App::post('/v1/account/tokens/email')
->setSmtpReplyTo($replyTo)
->setSmtpSenderEmail($senderEmail)
->setSmtpSenderName($senderName);
- } elseif ($customEmails && !empty($customTemplate)) {
- $subject = $customTemplate['subject'];
- $preview = $customTemplate['preview'];
- $heading = $customTemplate['heading'];
-
- $message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-otp.tpl');
- $message
- ->setParam('{{hello}}', $customTemplate['hello'])
- ->setParam('{{description}}', $customTemplate['body'], escapeHtml: false)
- ->setParam('{{thanks}}', $customTemplate['thanks'])
- ->setParam('{{signature}}', $customTemplate['signature'])
- ->setParam('{{clientInfo}}', '')
- ->setParam('{{securityPhrase}}', '')
- ->setParam('{{securityPhraseDividerDisplay}}', 'none');
-
- $body = $message->render();
- $bodyTemplate = __DIR__ . '/../../config/locale/templates/email-auth-styled.tpl';
}
$emailVariables = [
@@ -2402,7 +2385,7 @@ App::post('/v1/account/tokens/email')
'team' => '',
];
- if ($customEmails && !empty($customTemplate)) {
+ if ($smtpBaseTemplate === 'email-base-styled') {
$emailVariables = array_merge($emailVariables, [
'heading' => $heading,
'accentColor' => APP_EMAIL_ACCENT_COLOR,
@@ -3624,7 +3607,11 @@ App::post('/v1/account/verification')
$body = $locale->getText("emails.verification.body");
$preview = $locale->getText("emails.verification.preview");
$subject = $locale->getText("emails.verification.subject");
+ $heading = $locale->getText("emails.verification.heading");
+
$customTemplate = $project->getAttribute('templates', [])['email.verification-' . $locale->default] ?? [];
+ $smtpBaseTemplate = $project->getAttribute('smtpBaseTemplate', 'email-base');
+ $bodyTemplate = __DIR__ . '/../../config/locale/templates/' . $smtpBaseTemplate . '.tpl';
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
$message
@@ -3644,10 +3631,6 @@ App::post('/v1/account/verification')
$senderName = System::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
$replyTo = "";
- $customEmails = $project->getAttribute('customEmails', false);
- $bodyTemplate = '';
- $heading = '';
-
if ($smtpEnabled) {
if (!empty($smtp['senderEmail'])) {
$senderEmail = $smtp['senderEmail'];
@@ -3685,22 +3668,6 @@ App::post('/v1/account/verification')
->setSmtpReplyTo($replyTo)
->setSmtpSenderEmail($senderEmail)
->setSmtpSenderName($senderName);
- } elseif ($customEmails && !empty($customTemplate)) {
- $subject = $customTemplate['subject'];
- $preview = $customTemplate['preview'];
- $heading = $customTemplate['heading'];
-
- $message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-verification.tpl');
- $message
- ->setParam('{{hello}}', $customTemplate['hello'])
- ->setParam('{{body}}', $customTemplate['body'], escapeHtml: false)
- ->setParam('{{buttonText}}', $customTemplate['buttonText'])
- ->setParam('{{footer}}', $customTemplate['footer'])
- ->setParam('{{thanks}}', $customTemplate['thanks'])
- ->setParam('{{signature}}', $customTemplate['signature']);
-
- $body = $message->render();
- $bodyTemplate = __DIR__ . '/../../config/locale/templates/email-auth-styled.tpl';
}
$emailVariables = [
@@ -3713,7 +3680,7 @@ App::post('/v1/account/verification')
'team' => '',
];
- if ($customEmails && !empty($customTemplate)) {
+ if ($smtpBaseTemplate === 'email-base-styled') {
$emailVariables = array_merge($emailVariables, [
'heading' => $heading,
'accentColor' => APP_EMAIL_ACCENT_COLOR,
@@ -4736,7 +4703,11 @@ App::post('/v1/account/mfa/challenge')
$subject = $locale->getText("emails.mfaChallenge.subject");
$preview = $locale->getText("emails.mfaChallenge.preview");
+ $heading = $locale->getText("emails.mfaChallenge.heading");
+
$customTemplate = $project->getAttribute('templates', [])['email.mfaChallenge-' . $locale->default] ?? [];
+ $smtpBaseTemplate = $project->getAttribute('smtpBaseTemplate', 'email-base');
+ $bodyTemplate = __DIR__ . '/../../config/locale/templates/' . $smtpBaseTemplate . '.tpl';
$detector = new Detector($request->getUserAgent('UNKNOWN'));
$agentOs = $detector->getOS();
@@ -4760,10 +4731,6 @@ App::post('/v1/account/mfa/challenge')
$senderName = System::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
$replyTo = "";
- $customEmails = $project->getAttribute('customEmails', false);
- $bodyTemplate = '';
- $heading = '';
-
if ($smtpEnabled) {
if (!empty($smtp['senderEmail'])) {
$senderEmail = $smtp['senderEmail'];
@@ -4801,21 +4768,6 @@ App::post('/v1/account/mfa/challenge')
->setSmtpReplyTo($replyTo)
->setSmtpSenderEmail($senderEmail)
->setSmtpSenderName($senderName);
- } elseif ($customEmails && !empty($customTemplate)) {
- $subject = $customTemplate['subject'];
- $preview = $customTemplate['preview'];
- $heading = $customTemplate['heading'];
-
- $message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-mfa-challenge.tpl');
- $message
- ->setParam('{{hello}}', $customTemplate['hello'])
- ->setParam('{{description}}', $customTemplate['body'], escapeHtml: false)
- ->setParam('{{thanks}}', $customTemplate['thanks'])
- ->setParam('{{signature}}', $customTemplate['signature'])
- ->setParam('{{clientInfo}}', '');
-
- $body = $message->render();
- $bodyTemplate = __DIR__ . '/../../config/locale/templates/email-auth-styled.tpl';
}
$emailVariables = [
@@ -4829,7 +4781,7 @@ App::post('/v1/account/mfa/challenge')
'agentOs' => $agentOs['osName'] ?? 'UNKNOWN',
];
- if ($customEmails && !empty($customTemplate)) {
+ if ($smtpBaseTemplate === 'email-base-styled') {
$emailVariables = array_merge($emailVariables, [
'heading' => $heading,
'accentColor' => APP_EMAIL_ACCENT_COLOR,
diff --git a/src/Appwrite/Platform/Workers/Mails.php b/src/Appwrite/Platform/Workers/Mails.php
index 117b689863..efca484ebf 100644
--- a/src/Appwrite/Platform/Workers/Mails.php
+++ b/src/Appwrite/Platform/Workers/Mails.php
@@ -82,6 +82,7 @@ class Mails extends Action
$preview = $payload['preview'] ?? '';
$variables['subject'] = $subject;
+ $variables['heading'] = $variables['heading'] ?? $subject;
$variables['year'] = date("Y");
$attachment = $payload['attachment'] ?? [];
diff --git a/tests/e2e/Services/Account/AccountBase.php b/tests/e2e/Services/Account/AccountBase.php
index 46283e8f86..b2f85637a8 100644
--- a/tests/e2e/Services/Account/AccountBase.php
+++ b/tests/e2e/Services/Account/AccountBase.php
@@ -192,11 +192,6 @@ trait AccountBase
$this->assertStringNotContainsStringIgnoringCase('Appwrite logo', $lastEmail['html']);
}
- // TODO: Remove this once OTP login is supported for Console.
- if ($isConsoleProject) {
- return;
- }
-
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/token', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
|