diff --git a/app/config/locale/templates/email-certificate-failed.tpl b/app/config/locale/templates/email-certificate-failed.tpl
index 18751ff412..0363fc6538 100644
--- a/app/config/locale/templates/email-certificate-failed.tpl
+++ b/app/config/locale/templates/email-certificate-failed.tpl
@@ -4,7 +4,9 @@
|
- {{error}}
+
+ {{error}}
+
|
diff --git a/app/config/locale/translations/en.json b/app/config/locale/translations/en.json
index 953888013a..3a4a199e38 100644
--- a/app/config/locale/translations/en.json
+++ b/app/config/locale/translations/en.json
@@ -52,6 +52,12 @@
"emails.invitation.footer": "If you are not interested, you can ignore this message.",
"emails.invitation.thanks": "Thanks",
"emails.invitation.signature": "{{project}} team",
+ "emails.certificate.subject": "Certificate failure for %s",
+ "emails.certificate.hello": "Hello",
+ "emails.certificate.body": "Certificate for your domain '{{domain}}' could not be generated. This is attempt no. {{attempt}}, and the failure was caused by: {{error}}",
+ "emails.certificate.footer": "Your previous certificate will be valid for 30 days since the first failure. We highly recommend investigating this case, otherwise your domain will end up without a valid SSL communication.",
+ "emails.certificate.thanks": "Thanks",
+ "emails.certificate.signature": "{{project}} team",
"sms.verification.body": "{{secret}}",
"locale.country.unknown": "Unknown",
"countries.af": "Afghanistan",
diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php
index 7cab92da09..8b32349957 100644
--- a/app/controllers/api/users.php
+++ b/app/controllers/api/users.php
@@ -1786,7 +1786,7 @@ App::post('/v1/users/:userId/sessions')
throw new Exception(Exception::USER_NOT_FOUND);
}
- $secret = Auth::codeGenerator();
+ $secret = Auth::tokenGenerator(Auth::TOKEN_LENGTH_SESSION);
$detector = new Detector($request->getUserAgent('UNKNOWN'));
$record = $geodb->get($request->getIP());
@@ -1803,6 +1803,7 @@ App::post('/v1/users/:userId/sessions')
'userAgent' => $request->getUserAgent('UNKNOWN'),
'ip' => $request->getIP(),
'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--',
+ 'expire' => $expire,
],
$detector->getOS(),
$detector->getClient(),
@@ -1814,7 +1815,6 @@ App::post('/v1/users/:userId/sessions')
$session = $dbForProject->createDocument('sessions', $session);
$session
->setAttribute('secret', $secret)
- ->setAttribute('expire', $expire)
->setAttribute('countryName', $countryName);
$queueForEvents
diff --git a/app/init.php b/app/init.php
index a0bd3b837b..2166fa812b 100644
--- a/app/init.php
+++ b/app/init.php
@@ -116,7 +116,7 @@ const APP_LIMIT_LIST_DEFAULT = 25; // Default maximum number of items to return
const APP_KEY_ACCCESS = 24 * 60 * 60; // 24 hours
const APP_USER_ACCCESS = 24 * 60 * 60; // 24 hours
const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours
-const APP_CACHE_BUSTER = 443;
+const APP_CACHE_BUSTER = 4314;
const APP_VERSION_STABLE = '1.5.7';
const APP_DATABASE_ATTRIBUTE_EMAIL = 'email';
const APP_DATABASE_ATTRIBUTE_ENUM = 'enum';
@@ -621,9 +621,9 @@ Database::addFilter(
])
));
if (\count($targetIds) > 0) {
- return $database->find('targets', [
+ return $database->skipValidation(fn () => $database->find('targets', [
Query::equal('$internalId', $targetIds)
- ]);
+ ]));
}
return [];
}
diff --git a/composer.json b/composer.json
index 9bdf194f73..d7b3e97c62 100644
--- a/composer.json
+++ b/composer.json
@@ -44,13 +44,13 @@
"ext-sockets": "*",
"appwrite/php-runtimes": "0.14.*",
"appwrite/php-clamav": "2.0.*",
- "utopia-php/abuse": "0.37.*",
+ "utopia-php/abuse": "0.38.*",
"utopia-php/analytics": "0.10.*",
- "utopia-php/audit": "0.39.*",
+ "utopia-php/audit": "0.40.*",
"utopia-php/cache": "0.10.*",
"utopia-php/cli": "0.15.*",
"utopia-php/config": "0.2.*",
- "utopia-php/database": "0.49.*",
+ "utopia-php/database": "0.50.*",
"utopia-php/domains": "0.5.*",
"utopia-php/dsn": "0.2.1",
"utopia-php/framework": "0.33.*",
diff --git a/composer.lock b/composer.lock
index e18350a15a..e0e6628e43 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1428,23 +1428,23 @@
},
{
"name": "utopia-php/abuse",
- "version": "0.37.1",
+ "version": "0.38.0",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/abuse.git",
- "reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981"
+ "reference": "b7be9086c9d9b4561d810cbd42fdda798742f56c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/utopia-php/abuse/zipball/4dfcff4754c7804d1a70039792c0f2d59a5cc981",
- "reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981",
+ "url": "https://api.github.com/repos/utopia-php/abuse/zipball/b7be9086c9d9b4561d810cbd42fdda798742f56c",
+ "reference": "b7be9086c9d9b4561d810cbd42fdda798742f56c",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-pdo": "*",
"php": ">=8.0",
- "utopia-php/database": "0.49.*"
+ "utopia-php/database": "0.50.*"
},
"require-dev": {
"laravel/pint": "1.5.*",
@@ -1471,9 +1471,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/abuse/issues",
- "source": "https://github.com/utopia-php/abuse/tree/0.37.1"
+ "source": "https://github.com/utopia-php/abuse/tree/0.38.0"
},
- "time": "2024-06-05T18:03:59+00:00"
+ "time": "2024-06-24T00:52:02+00:00"
},
{
"name": "utopia-php/analytics",
@@ -1523,21 +1523,21 @@
},
{
"name": "utopia-php/audit",
- "version": "0.39.1",
+ "version": "0.40.0",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/audit.git",
- "reference": "7ea91e0ceea7b94293612fea94022b73315677c2"
+ "reference": "735ae211ce5fee5b52b736731571b4030b1d7cdc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/utopia-php/audit/zipball/7ea91e0ceea7b94293612fea94022b73315677c2",
- "reference": "7ea91e0ceea7b94293612fea94022b73315677c2",
+ "url": "https://api.github.com/repos/utopia-php/audit/zipball/735ae211ce5fee5b52b736731571b4030b1d7cdc",
+ "reference": "735ae211ce5fee5b52b736731571b4030b1d7cdc",
"shasum": ""
},
"require": {
"php": ">=8.0",
- "utopia-php/database": "0.49.*"
+ "utopia-php/database": "0.50.*"
},
"require-dev": {
"laravel/pint": "1.5.*",
@@ -1564,9 +1564,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/audit/issues",
- "source": "https://github.com/utopia-php/audit/tree/0.39.1"
+ "source": "https://github.com/utopia-php/audit/tree/0.40.0"
},
- "time": "2024-06-05T19:28:22+00:00"
+ "time": "2024-06-24T00:52:17+00:00"
},
{
"name": "utopia-php/cache",
@@ -1720,16 +1720,16 @@
},
{
"name": "utopia-php/database",
- "version": "0.49.14",
+ "version": "0.50.0",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/database.git",
- "reference": "415588c0b98edee9d72cdfe269ff79b14cd8f56d"
+ "reference": "ce3eaccb2f3bbd34b2b97419836fec633b26b8f7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/utopia-php/database/zipball/415588c0b98edee9d72cdfe269ff79b14cd8f56d",
- "reference": "415588c0b98edee9d72cdfe269ff79b14cd8f56d",
+ "url": "https://api.github.com/repos/utopia-php/database/zipball/ce3eaccb2f3bbd34b2b97419836fec633b26b8f7",
+ "reference": "ce3eaccb2f3bbd34b2b97419836fec633b26b8f7",
"shasum": ""
},
"require": {
@@ -1770,9 +1770,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/database/issues",
- "source": "https://github.com/utopia-php/database/tree/0.49.14"
+ "source": "https://github.com/utopia-php/database/tree/0.50.0"
},
- "time": "2024-06-20T02:39:23+00:00"
+ "time": "2024-06-21T03:21:42+00:00"
},
{
"name": "utopia-php/domains",
diff --git a/src/Appwrite/Migration/Migration.php b/src/Appwrite/Migration/Migration.php
index 15c14daf51..e3a2021c1a 100644
--- a/src/Appwrite/Migration/Migration.php
+++ b/src/Appwrite/Migration/Migration.php
@@ -239,7 +239,7 @@ abstract class Migration
}
/**
- * Creates colletion from the config collection.
+ * Creates collection from the config collection.
*
* @param string $id
* @param string|null $name
@@ -266,6 +266,7 @@ abstract class Migration
'type' => $attribute['type'],
'size' => $attribute['size'],
'required' => $attribute['required'],
+ 'default' => $attribute['default'] ?? null,
'signed' => $attribute['signed'],
'array' => $attribute['array'],
'filters' => $attribute['filters'],
diff --git a/src/Appwrite/Migration/Version/V20.php b/src/Appwrite/Migration/Version/V20.php
index 1a599d32f2..5a0807cedf 100644
--- a/src/Appwrite/Migration/Version/V20.php
+++ b/src/Appwrite/Migration/Version/V20.php
@@ -336,6 +336,32 @@ class V20 extends Migration
Console::warning("Purge cache from {$id}: {$th->getMessage()}");
}
+ break;
+ case 'topics':
+ try {
+ $this->projectDB->updateAttributeDefault($id, 'emailTotal', 0);
+ } catch (Throwable $th) {
+ Console::warning("'topics' from {$id}: {$th->getMessage()}");
+ }
+
+ try {
+ $this->projectDB->updateAttributeDefault($id, 'pushTotal', 0);
+ } catch (Throwable $th) {
+ Console::warning("'topics' from {$id}: {$th->getMessage()}");
+ }
+
+ try {
+ $this->projectDB->updateAttributeDefault($id, 'smsTotal', 0);
+ } catch (Throwable $th) {
+ Console::warning("'topics' from {$id}: {$th->getMessage()}");
+ }
+
+ try {
+ $this->projectDB->purgeCachedCollection($id);
+ } catch (Throwable $th) {
+ Console::warning("Purge cache from {$id}: {$th->getMessage()}");
+ }
+
break;
}
diff --git a/src/Appwrite/Platform/Workers/Certificates.php b/src/Appwrite/Platform/Workers/Certificates.php
index ad6cf09fa7..58dc1dd28a 100644
--- a/src/Appwrite/Platform/Workers/Certificates.php
+++ b/src/Appwrite/Platform/Workers/Certificates.php
@@ -439,40 +439,24 @@ class Certificates extends Action
$locale = new Locale(System::getEnv('_APP_LOCALE', 'en'));
- // Send mail to administratore mail
+ // Send mail to administrator mail
$template = Template::fromFile(__DIR__ . '/../../../../app/config/locale/templates/email-certificate-failed.tpl');
$template->setParam('{{domain}}', $domain);
$template->setParam('{{error}}', \nl2br($errorMessage));
$template->setParam('{{attempts}}', $attempt);
-
- // TODO: Use setbodyTemplate once #7307 is merged
- $subject = 'Certificate failed to generate';
- $body = Template::fromFile(__DIR__ . '/../../../../app/config/locale/templates/email-base-styled.tpl');
-
- $subject = \sprintf($locale->getText("emails.certificate.subject"), $domain);
-
- $message = Template::fromFile(__DIR__ . '/../../../../app/config/locale/templates/email-inner-base.tpl');
- $message
- ->setParam('{{body}}', $locale->getText("emails.certificate.body"), escapeHtml: false)
- ->setParam('{{hello}}', $locale->getText("emails.certificate.hello"))
- ->setParam('{{footer}}', $locale->getText("emails.certificate.footer"))
- ->setParam('{{thanks}}', $locale->getText("emails.certificate.thanks"))
- ->setParam('{{signature}}', $locale->getText("emails.certificate.signature"));
- $body = $message->render();
+ $body = $template->render();
$emailVariables = [
'direction' => $locale->getText('settings.direction'),
- 'domain' => $domain,
- 'error' => '
' . $errorMessage . '
',
- 'attempt' => $attempt,
- 'project' => 'Console',
- 'redirect' => 'https://' . $domain,
];
+ $subject = \sprintf($locale->getText("emails.certificate.subject"), $domain);
+
$queueForMails
->setSubject($subject)
->setBody($body)
->setName('Appwrite Administrator')
+ ->setbodyTemplate(__DIR__ . '/../../../../app/config/locale/templates/email-base-styled.tpl')
->setVariables($emailVariables)
->setRecipient(System::getEnv('_APP_EMAIL_CERTIFICATES', System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS')))
->trigger();
diff --git a/tests/e2e/Services/Health/HealthCustomServerTest.php b/tests/e2e/Services/Health/HealthCustomServerTest.php
index 335e44be1b..8360af542e 100644
--- a/tests/e2e/Services/Health/HealthCustomServerTest.php
+++ b/tests/e2e/Services/Health/HealthCustomServerTest.php
@@ -455,7 +455,7 @@ class HealthCustomServerTest extends Scope
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals('/CN=www.google.com', $response['body']['name']);
$this->assertEquals('www.google.com', $response['body']['subjectSN']);
- $this->assertEquals('Google Trust Services', $response['body']['issuerOrganisation']);
+ $this->assertStringContainsString('Google Trust Services', $response['body']['issuerOrganisation']);
$this->assertIsInt($response['body']['validFrom']);
$this->assertIsInt($response['body']['validTo']);
diff --git a/tests/e2e/Services/Messaging/MessagingBase.php b/tests/e2e/Services/Messaging/MessagingBase.php
index 0540479eb5..dc5ddb9d70 100644
--- a/tests/e2e/Services/Messaging/MessagingBase.php
+++ b/tests/e2e/Services/Messaging/MessagingBase.php
@@ -511,6 +511,55 @@ trait MessagingBase
];
}
+ public function testSubscriberTargetSubQuery()
+ {
+ $response = $this->client->call(Client::METHOD_POST, '/messaging/topics', [
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id'],
+ 'x-appwrite-key' => $this->getProject()['apiKey'],
+ ], [
+ 'topicId' => 'sub-query-test',
+ 'name' => 'sub-query-test',
+ ]);
+
+ $this->assertEquals(201, $response['headers']['status-code']);
+
+ $topic = $response['body'];
+
+ $prefix = uniqid();
+
+ for ($i = 1; $i <= 101; $i++) {
+ $response = $this->client->call(Client::METHOD_POST, '/users', [
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id'],
+ 'x-appwrite-key' => $this->getProject()['apiKey'],
+ ], [
+ 'userId' => "$prefix-$i",
+ 'email' => "$prefix-$i@example.com",
+ 'password' => 'password',
+ 'name' => "User $prefix $i",
+ ]);
+
+ $this->assertEquals(201, $response['headers']['status-code']);
+ $user = $response['body'];
+ $targets = $user['targets'] ?? [];
+
+ $this->assertGreaterThan(0, count($targets));
+
+ $target = $targets[0];
+
+ $response = $this->client->call(Client::METHOD_POST, '/messaging/topics/' . $topic['$id'] . '/subscribers', \array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id'],
+ ], $this->getHeaders()), [
+ 'subscriberId' => $user['$id'],
+ 'targetId' => $target['$id'],
+ ]);
+
+ $this->assertEquals(201, $response['headers']['status-code']);
+ }
+ }
+
/**
* @depends testCreateSubscriber
*/
diff --git a/tests/e2e/Services/Users/UsersBase.php b/tests/e2e/Services/Users/UsersBase.php
index 5af4aa751a..c34227e4de 100644
--- a/tests/e2e/Services/Users/UsersBase.php
+++ b/tests/e2e/Services/Users/UsersBase.php
@@ -290,6 +290,28 @@ trait UsersBase
$this->assertArrayNotHasKey('secret', $token['body']);
}
+ /**
+ * @depends testCreateUser
+ */
+ public function testCreateSession(array $data): void
+ {
+ /**
+ * Test for SUCCESS
+ */
+ $response = $this->client->call(Client::METHOD_POST, '/users/' . $data['userId'] . '/sessions', array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id'],
+ ], $this->getHeaders()));
+
+ $this->assertEquals(201, $response['headers']['status-code']);
+
+ $session = $response['body'];
+ $this->assertEquals($data['userId'], $session['userId']);
+ $this->assertNotEmpty($session['secret']);
+ $this->assertNotEmpty($session['expire']);
+ $this->assertEquals('server', $session['provider']);
+ }
+
/**
* Tests all optional parameters of createUser (email, phone, anonymous..)