diff --git a/CHANGES.md b/CHANGES.md
index 488a4fe83..519107cc3 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,19 +1,15 @@
# Version 1.1.0
-
## Features
-- Added new property to projects configuration: `sessionDuration` which allows you to alter the duration of signed in sessions for your project. [#4618](https://github.com/appwrite/appwrite/pull/4618)
+- Added new property to projects configuration: `authDuration` which allows you to alter the duration of signed in sessions for your project. [#4618](https://github.com/appwrite/appwrite/pull/4618)
## Bugs
- Fix license detection for Flutter and Dart SDKs [#4435](https://github.com/appwrite/appwrite/pull/4435)
-- Fix missing status, buildStderr and buildStderr from get deployment response [#4611](https://github.com/appwrite/appwrite/pull/4611)
+- Fix missing `status`, `buildStderr` and `buildStderr` from get deployment response [#4611](https://github.com/appwrite/appwrite/pull/4611)
+- Fix project pagination in DB usage aggregation [#4517](https://github.com/appwrite/appwrite/pull/4517)
# Features
- Added Auth Duration API to allow users to set the duration of their sessions. [#4618](https://github.com/appwrite/appwrite/pull/4618)
-# Version 1.0.4
-
-- Fix project pagination in DB usage collector [#4517](https://github.com/appwrite/appwrite/pull/4517)
-
# Version 1.0.3
## Bugs
- Fix document audit deletion [#4429](https://github.com/appwrite/appwrite/pull/4429)
diff --git a/app/console b/app/console
new file mode 160000
index 000000000..0ed6e0c49
--- /dev/null
+++ b/app/console
@@ -0,0 +1 @@
+Subproject commit 0ed6e0c497931f16fcb0750fe351d1d3577a7d97
diff --git a/app/init.php b/app/init.php
index 96683c9c0..3a41a53ab 100644
--- a/app/init.php
+++ b/app/init.php
@@ -95,7 +95,7 @@ const APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT = 60; // Default maximum write rate pe
const APP_KEY_ACCCESS = 24 * 60 * 60; // 24 hours
const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours
const APP_CACHE_BUSTER = 501;
-const APP_VERSION_STABLE = '1.0.3';
+const APP_VERSION_STABLE = '1.1.0';
const APP_DATABASE_ATTRIBUTE_EMAIL = 'email';
const APP_DATABASE_ATTRIBUTE_ENUM = 'enum';
const APP_DATABASE_ATTRIBUTE_IP = 'ip';
diff --git a/app/realtime.php b/app/realtime.php
index 90c96de21..ac4e2d669 100644
--- a/app/realtime.php
+++ b/app/realtime.php
@@ -306,7 +306,7 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats,
if ($realtime->hasSubscriber($projectId, 'user:' . $userId)) {
$connection = array_key_first(reset($realtime->subscriptions[$projectId]['user:' . $userId]));
[$consoleDatabase, $returnConsoleDatabase] = getDatabase($register, '_console');
- $project = Authorization::skip(fn() => $consoleDatabase->getDocument('projects', $projectId));
+ $project = Authorization::skip(fn () => $consoleDatabase->getDocument('projects', $projectId));
[$database, $returnDatabase] = getDatabase($register, "_{$project->getInternalId()}");
$user = $database->getDocument('users', $userId);
@@ -484,6 +484,7 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server,
$server->onMessage(function (int $connection, string $message) use ($server, $register, $realtime, $containerId) {
try {
+ $app = new App('UTC');
$response = new Response(new SwooleResponse());
$db = $register->get('dbPool')->get();
$redis = $register->get('redisPool')->get();
@@ -493,12 +494,8 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re
$database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite'));
$database->setNamespace("_console");
$projectId = $realtime->connections[$connection]['projectId'];
-
- if ($projectId !== 'console') {
- $project = Authorization::skip(fn() => $database->getDocument('projects', $projectId));
- $database->setNamespace("_{$project->getInternalId()}");
- }
-
+ $project = $projectId === 'console' ? $app->getResource('console') : Authorization::skip(fn () => $database->getDocument('projects', $projectId));
+ $database->setNamespace("_{$project->getInternalId()}");
/*
* Abuse Check
*
diff --git a/app/tasks/sdks.php b/app/tasks/sdks.php
index 4ba6f9d02..3fe05c056 100644
--- a/app/tasks/sdks.php
+++ b/app/tasks/sdks.php
@@ -30,7 +30,7 @@ $cli
$production = ($git) ? (Console::confirm('Type "Appwrite" to push code to production git repos') == 'Appwrite') : false;
$message = ($git) ? Console::confirm('Please enter your commit message:') : '';
- if (!in_array($version, ['0.6.x', '0.7.x', '0.8.x', '0.9.x', '0.10.x', '0.11.x', '0.12.x', '0.13.x', '0.14.x', '0.15.x', '1.0.x', 'latest'])) {
+ if (!in_array($version, ['0.6.x', '0.7.x', '0.8.x', '0.9.x', '0.10.x', '0.11.x', '0.12.x', '0.13.x', '0.14.x', '0.15.x', '1.0.x', '1.1.x', 'latest'])) {
throw new Exception('Unknown version given');
}
diff --git a/phpcs.xml b/phpcs.xml
index cb31d549e..ccde5812b 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -7,6 +7,8 @@
./app/sdks
+
+ ./app/console
*
diff --git a/src/Appwrite/Migration/Migration.php b/src/Appwrite/Migration/Migration.php
index c87c907bf..9c6b03391 100644
--- a/src/Appwrite/Migration/Migration.php
+++ b/src/Appwrite/Migration/Migration.php
@@ -44,7 +44,8 @@ abstract class Migration
'1.0.0-RC1' => 'V15',
'1.0.0' => 'V15',
'1.0.1' => 'V15',
- '1.0.3' => 'V15'
+ '1.0.3' => 'V15',
+ '1.1.0' => 'V16',
];
/**
diff --git a/src/Appwrite/Migration/Version/V16.php b/src/Appwrite/Migration/Version/V16.php
new file mode 100644
index 000000000..311cbaff2
--- /dev/null
+++ b/src/Appwrite/Migration/Version/V16.php
@@ -0,0 +1,116 @@
+ null,
+ fn () => []
+ );
+ }
+
+ Console::log('Migrating Project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
+
+ Console::info('Migrating Collections');
+ $this->migrateCollections();
+
+ Console::info('Migrating Documents');
+ $this->forEachDocument([$this, 'fixDocument']);
+ }
+
+ /**
+ * Migrate all Collections.
+ *
+ * @return void
+ */
+ protected function migrateCollections(): void
+ {
+ foreach ($this->collections as $collection) {
+ $id = $collection['$id'];
+
+ Console::log("Migrating Collection \"{$id}\"");
+
+ $this->projectDB->setNamespace("_{$this->project->getInternalId()}");
+
+ switch ($id) {
+ case 'sessions':
+ try {
+ /**
+ * Create 'compression' attribute
+ */
+ $this->projectDB->deleteAttribute($id, 'expire');
+ } catch (\Throwable $th) {
+ Console::warning("'expire' from {$id}: {$th->getMessage()}");
+ }
+
+ break;
+
+ case 'projects':
+ try {
+ /**
+ * Create 'region' attribute
+ */
+ $this->createAttributeFromCollection($this->projectDB, $id, 'region');
+ } catch (\Throwable $th) {
+ Console::warning("'region' from {$id}: {$th->getMessage()}");
+ }
+
+ try {
+ /**
+ * Create '_key_team' index
+ */
+ $this->createIndexFromCollection($this->projectDB, $id, '_key_team');
+ } catch (\Throwable $th) {
+ Console::warning("'_key_team' from {$id}: {$th->getMessage()}");
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ usleep(50000);
+ }
+ }
+
+ /**
+ * Fix run on each document
+ *
+ * @param \Utopia\Database\Document $document
+ * @return \Utopia\Database\Document
+ */
+ protected function fixDocument(Document $document)
+ {
+ switch ($document->getCollection()) {
+ case 'projects':
+ /**
+ * Bump version number.
+ */
+ $document->setAttribute('version', '1.1.0');
+
+ /**
+ * Set default authDuration
+ */
+ $document->setAttribute('auths', array_merge($document->getAttribute('auths', []), [
+ 'duration' => Auth::TOKEN_EXPIRATION_LOGIN_LONG
+ ]));
+ break;
+ }
+
+ return $document;
+ }
+}
diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php
index 572bc4abf..e5f02837b 100644
--- a/tests/e2e/General/UsageTest.php
+++ b/tests/e2e/General/UsageTest.php
@@ -85,7 +85,7 @@ class UsageTest extends Scope
#[Retry(count: 1)]
public function testUsersStats(array $data): array
{
- sleep(10);
+ sleep(20);
$projectId = $data['projectId'];
$headers = $data['headers'];
@@ -256,7 +256,7 @@ class UsageTest extends Scope
$filesCreate = $data['filesCreate'];
$filesDelete = $data['filesDelete'];
- sleep(10);
+ sleep(20);
// console request
$headers = [
@@ -414,7 +414,7 @@ class UsageTest extends Scope
$this->assertEquals('name', $res['body']['key']);
$collectionsUpdate++;
$requestsCount++;
- sleep(10);
+ sleep(20);
for ($i = 0; $i < 10; $i++) {
$name = uniqid() . ' collection';
@@ -496,7 +496,7 @@ class UsageTest extends Scope
$documentsRead = $data['documentsRead'];
$documentsDelete = $data['documentsDelete'];
- sleep(10);
+ sleep(20);
// check datbase stats
$headers = [
@@ -704,7 +704,7 @@ class UsageTest extends Scope
$executions = $data['executions'];
$failures = $data['failures'];
- sleep(10);
+ sleep(20);
$response = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/usage', $headers, [
'range' => '30d'