Update base template for session alert email

This commit is contained in:
Hemachandar
2025-10-31 17:52:47 +05:30
parent 0e6d3279d7
commit f9542e2be2
3 changed files with 131 additions and 4 deletions
+21
View File
@@ -75,6 +75,14 @@ function sendSessionAlert(Locale $locale, Document $user, Document $project, Doc
$subject = $locale->getText("emails.sessionAlert.subject");
$preview = $locale->getText("emails.sessionAlert.preview");
$customTemplate = $project->getAttribute('templates', [])['email.sessionAlert-' . $locale->default] ?? [];
$smtpBaseTemplate = $project->getAttribute('smtpBaseTemplate', 'email-base');
$validator = new FileName();
if (!$validator->isValid($smtpBaseTemplate)) {
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Invalid template path');
}
$bodyTemplate = __DIR__ . '/../../config/locale/templates/' . $smtpBaseTemplate . '.tpl';
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-session-alert.tpl');
$message
@@ -157,12 +165,25 @@ function sendSessionAlert(Locale $locale, Document $user, Document $project, Doc
'country' => $locale->getText('countries.' . $session->getAttribute('countryCode'), $locale->getText('locale.country.unknown')),
];
if ($smtpBaseTemplate === APP_BRANDED_EMAIL_BASE_TEMPLATE) {
$emailVariables = array_merge($emailVariables, [
'accentColor' => APP_EMAIL_ACCENT_COLOR,
'logoUrl' => APP_EMAIL_LOGO_URL,
'twitterUrl' => APP_SOCIAL_TWITTER,
'discordUrl' => APP_SOCIAL_DISCORD,
'githubUrl' => APP_SOCIAL_GITHUB_APPWRITE,
'termsUrl' => APP_EMAIL_TERMS_URL,
'privacyUrl' => APP_EMAIL_PRIVACY_URL,
]);
}
$email = $user->getAttribute('email');
$queueForMails
->setSubject($subject)
->setPreview($preview)
->setBody($body)
->setBodyTemplate($bodyTemplate)
->setVariables($emailVariables)
->setRecipient($email)
->trigger();
@@ -88,4 +88,112 @@ class AccountConsoleClientTest extends Scope
$this->assertEquals($response['headers']['status-code'], 204);
}
public function testSessionAlert(): void
{
$email = uniqid() . 'session-alert@appwrite.io';
$password = 'password123';
$name = 'Session Alert Tester';
// Create a new account
$response = $this->client->call(Client::METHOD_POST, '/account', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-dev-key' => $this->getProject()['devKey'] ?? ''
]), [
'userId' => ID::unique(),
'email' => $email,
'password' => $password,
'name' => $name,
]);
$this->assertEquals(201, $response['headers']['status-code']);
// Create first session for the new account
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
]), [
'email' => $email,
'password' => $password,
]);
$this->assertEquals(201, $response['headers']['status-code']);
// Create second session for the new account
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
]), [
'email' => $email,
'password' => $password,
]);
// Check the alert email
$lastEmail = $this->getLastEmail();
$this->assertEquals($email, $lastEmail['to'][0]['address']);
$this->assertStringContainsString('Security alert: new session', $lastEmail['subject']);
$this->assertStringContainsString($response['body']['ip'], $lastEmail['text']); // IP Address
$this->assertStringContainsString('Unknown', $lastEmail['text']); // Country
$this->assertStringContainsString($response['body']['clientName'], $lastEmail['text']); // Client name
$this->assertStringContainsStringIgnoringCase('Appwrite logo', $lastEmail['html']);
// Verify no alert sent in OTP login
$response = $this->client->call(Client::METHOD_POST, '/account/tokens/email', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
]), [
'userId' => ID::unique(),
'email' => 'otpuser2@appwrite.io'
]);
$this->assertEquals($response['headers']['status-code'], 201);
$this->assertNotEmpty($response['body']['$id']);
$this->assertNotEmpty($response['body']['$createdAt']);
$this->assertNotEmpty($response['body']['userId']);
$this->assertNotEmpty($response['body']['expire']);
$this->assertEmpty($response['body']['secret']);
$this->assertEmpty($response['body']['phrase']);
$this->assertStringContainsStringIgnoringCase('New login detected on '. $this->getProject()['name'], $lastEmail['text']);
$userId = $response['body']['userId'];
$lastEmail = $this->getLastEmail();
$this->assertEquals('otpuser2@appwrite.io', $lastEmail['to'][0]['address']);
$this->assertEquals('OTP for ' . $this->getProject()['name'] . ' Login', $lastEmail['subject']);
// Find 6 concurrent digits in email text - OTP
preg_match_all("/\b\d{6}\b/", $lastEmail['text'], $matches);
$code = ($matches[0] ?? [])[0] ?? '';
$this->assertNotEmpty($code);
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/token', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
]), [
'userId' => $userId,
'secret' => $code
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertEquals($userId, $response['body']['userId']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertNotEmpty($response['body']['expire']);
$this->assertEmpty($response['body']['secret']);
$lastEmailId = $lastEmail['id'];
$lastEmail = $this->getLastEmail();
$this->assertEquals($lastEmailId, $lastEmail['id']);
}
}
@@ -1348,10 +1348,7 @@ class AccountCustomClientTest extends Scope
return $data;
}
/**
* @depends testCreateAccountSession
*/
public function testSessionAlert($data): void
public function testSessionAlert(): void
{
$email = uniqid() . 'session-alert@appwrite.io';
$password = 'password123';
@@ -1417,6 +1414,7 @@ class AccountCustomClientTest extends Scope
$this->assertStringContainsString($response['body']['ip'], $lastEmail['text']); // IP Address
$this->assertStringContainsString('Unknown', $lastEmail['text']); // Country
$this->assertStringContainsString($response['body']['clientName'], $lastEmail['text']); // Client name
$this->assertStringNotContainsStringIgnoringCase('Appwrite logo', $lastEmail['html']);
// Verify no alert sent in OTP login
$response = $this->client->call(Client::METHOD_POST, '/account/tokens/email', array_merge([