diff --git a/app/config/collections.php b/app/config/collections.php index 3e3de4c7bd..dbff598476 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -1077,8 +1077,8 @@ $collections = [ 'signed' => true, 'required' => false, 'default' => [], - 'array' => true, - 'filters' => ['json'], + 'array' => false, + 'filters' => ['subQueryMemberships'], ], [ '$id' => 'search', diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 200b845987..31bf7bf421 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -106,7 +106,7 @@ App::post('/v1/account') 'prefs' => new \stdClass(), 'sessions' => [], 'tokens' => [], - 'memberships' => [], + 'memberships' => null, 'search' => implode(' ', [$userId, $email, $name]), 'deleted' => false ]))); @@ -507,7 +507,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') 'prefs' => new \stdClass(), 'sessions' => [], 'tokens' => [], - 'memberships' => [], + 'memberships' => null, 'search' => implode(' ', [$userId, $email, $name]), 'deleted' => false ]))); @@ -681,7 +681,7 @@ App::post('/v1/account/sessions/magic-url') 'prefs' => new \stdClass(), 'sessions' => [], 'tokens' => [], - 'memberships' => [], + 'memberships' => null, 'search' => implode(' ', [$userId, $email]), 'deleted' => false ]))); @@ -953,7 +953,7 @@ App::post('/v1/account/sessions/anonymous') 'prefs' => new \stdClass(), 'sessions' => [], 'tokens' => [], - 'memberships' => [], + 'memberships' => null, 'search' => $userId, 'deleted' => false ]))); diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index f956d7e2ef..6e2eabeac6 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -79,10 +79,7 @@ App::post('/v1/teams') ]); $membership = $dbForProject->createDocument('memberships', $membership); - - // Attach user to team - $user->setAttribute('memberships', $membership, Document::SET_TYPE_APPEND); - $user = $dbForProject->updateDocument('users', $user->getId(), $user); + $dbForProject->deleteCachedDocument('users', $user->getId()); } if (!empty($user->getId())) { @@ -324,7 +321,7 @@ App::post('/v1/teams/:teamId/memberships') 'prefs' => new \stdClass(), 'sessions' => [], 'tokens' => [], - 'memberships' => [], + 'memberships' => null, 'search' => implode(' ', [$userId, $email, $name]), ]))); } catch (Duplicate $th) { @@ -364,10 +361,7 @@ App::post('/v1/teams/:teamId/memberships') $team->setAttribute('total', $team->getAttribute('total', 0) + 1); $team = Authorization::skip(fn() => $dbForProject->updateDocument('teams', $team->getId(), $team)); - // Attach user to team - $invitee->setAttribute('memberships', $membership, Document::SET_TYPE_APPEND); - - $invitee = Authorization::skip(fn() => $dbForProject->updateDocument('users', $invitee->getId(), $invitee)); + $dbForProject->deleteCachedDocument('users', $invitee->getId()); } else { try { $membership = $dbForProject->createDocument('memberships', $membership); @@ -579,13 +573,8 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId') /** * Replace membership on profile */ - $memberships = array_filter($profile->getAttribute('memberships'), fn (Document $m) => $m->getId() !== $membership->getId()); - - $profile - ->setAttribute('memberships', $memberships) - ->setAttribute('memberships', $membership, Document::SET_TYPE_APPEND); - - Authorization::skip(fn () => $dbForProject->updateDocument('users', $profile->getId(), $profile)); + + $dbForProject->deleteCachedDocument('users', $profile->getId()); $audits ->setParam('userId', $user->getId()) @@ -669,7 +658,6 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status') $user ->setAttribute('emailVerification', true) - ->setAttribute('memberships', $membership, Document::SET_TYPE_APPEND) ; // Log user in @@ -703,6 +691,8 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status') $user = $dbForProject->updateDocument('users', $user->getId(), $user); $membership = $dbForProject->updateDocument('memberships', $membership->getId(), $membership); + + $dbForProject->deleteCachedDocument('users', $user->getId()); $team = Authorization::skip(fn() => $dbForProject->updateDocument('teams', $team->getId(), $team->setAttribute('total', $team->getAttribute('total', 0) + 1))); @@ -778,20 +768,7 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId') throw new Exception('Failed to remove membership from DB', 500, Exception::GENERAL_SERVER_ERROR); } - $memberships = $user->getAttribute('memberships', []); - - foreach ($memberships as $key => $child) { - /** @var Document $child */ - - if ($membershipId == $child->getId()) { - unset($memberships[$key]); - break; - } - } - - $user->setAttribute('memberships', $memberships); - - Authorization::skip(fn() => $dbForProject->updateDocument('users', $user->getId(), $user)); + $dbForProject->deleteCachedDocument('users', $user->getId()); if ($membership->getAttribute('confirm')) { // Count only confirmed members $team->setAttribute('total', \max($team->getAttribute('total', 0) - 1, 0)); diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 6bb14c5003..bfb7d4d17a 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -65,7 +65,7 @@ App::post('/v1/users') 'prefs' => new \stdClass(), 'sessions' => [], 'tokens' => [], - 'memberships' => [], + 'memberships' => null, 'search' => implode(' ', [$userId, $email, $name]), 'deleted' => false ])); diff --git a/app/init.php b/app/init.php index fd509297f6..cac7a9701b 100644 --- a/app/init.php +++ b/app/init.php @@ -301,6 +301,18 @@ Database::addFilter('subQueryWebhooks', } ); +Database::addFilter('subQueryMemberships', + function($value) { + return null; + }, + function($value, Document $document, Database $database) { + return Authorization::skip(fn() => $database + ->find('memberships', [ + new Query('userId', Query::TYPE_EQUAL, [$document->getId()]) + ], $database->getIndexLimit(), 0, [])); + } +); + Database::addFilter('encrypt', function($value) { $key = App::getEnv('_APP_OPENSSL_KEY_V1'); diff --git a/app/workers/deletes.php b/app/workers/deletes.php index b8a44ebb82..6ec1acc7cd 100644 --- a/app/workers/deletes.php +++ b/app/workers/deletes.php @@ -19,6 +19,7 @@ use Utopia\Audit\Audit; require_once __DIR__ . '/../init.php'; Authorization::disable(); +Authorization::setDefaultStatus(false); Console::title('Deletes V1 Worker'); Console::success(APP_NAME . ' deletes worker v1 has started' . "\n"); @@ -214,9 +215,6 @@ class DeletesV1 extends Worker new Query('userId', Query::TYPE_EQUAL, [$userId]) ], $this->getProjectDB($projectId)); - $user->setAttribute('sessions', []); - $updated = $this->getProjectDB($projectId)->updateDocument('users', $userId, $user); - // Delete Memberships and decrement team membership counts $this->deleteByGroup('memberships', [ new Query('userId', Query::TYPE_EQUAL, [$userId])