1
0
Fork 0
mirror of synced 2024-04-27 01:22:26 +12:00

fix: replace internal and external database with project database

This commit is contained in:
Torsten Dittmann 2021-12-27 13:45:23 +01:00
parent 67e90fe27d
commit 693b8c7185
19 changed files with 743 additions and 809 deletions

2
.env
View file

@ -18,7 +18,7 @@ _APP_REDIS_PORT=6379
_APP_DB_HOST=mariadb
_APP_DB_PORT=3306
_APP_DB_SCHEMA=appwrite
_APP_DB_USER=root
_APP_DB_USER=user
_APP_DB_PASS=password
_APP_STORAGE_ANTIVIRUS=disabled
_APP_STORAGE_ANTIVIRUS_HOST=clamav

View file

@ -51,14 +51,14 @@ App::post('/v1/account')
->inject('request')
->inject('response')
->inject('project')
->inject('dbForInternal')
->inject('dbForProject')
->inject('audits')
->inject('usage')
->action(function ($userId, $email, $password, $name, $request, $response, $project, $dbForInternal, $audits, $usage) {
->action(function ($userId, $email, $password, $name, $request, $response, $project, $dbForProject, $audits, $usage) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
@ -79,7 +79,7 @@ App::post('/v1/account')
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
if ($limit !== 0) {
$sum = $dbForInternal->count('users', [
$sum = $dbForProject->count('users', [
new Query('deleted', Query::TYPE_EQUAL, [false]),
], APP_LIMIT_USERS);
@ -89,8 +89,8 @@ App::post('/v1/account')
}
try {
$userId = $userId == 'unique()' ? $dbForInternal->getId() : $userId;
$user = Authorization::skip(fn() => $dbForInternal->createDocument('users', new Document([
$userId = $userId == 'unique()' ? $dbForProject->getId() : $userId;
$user = Authorization::skip(fn() => $dbForProject->createDocument('users', new Document([
'$id' => $userId,
'$read' => ['role:all'],
'$write' => ['user:' . $userId],
@ -149,15 +149,15 @@ App::post('/v1/account/sessions')
->param('password', '', new Password(), 'User password. Must be at least 8 chars.')
->inject('request')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->inject('audits')
->inject('usage')
->action(function ($email, $password, $request, $response, $dbForInternal, $locale, $geodb, $audits, $usage) {
->action(function ($email, $password, $request, $response, $dbForProject, $locale, $geodb, $audits, $usage) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Locale\Locale $locale */
/** @var MaxMind\Db\Reader $geodb */
/** @var Appwrite\Event\Event $audits */
@ -166,7 +166,7 @@ App::post('/v1/account/sessions')
$email = \strtolower($email);
$protocol = $request->getProtocol();
$profile = $dbForInternal->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
$profile = $dbForProject->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
if (!$profile || !Auth::passwordVerify($password, $profile->getAttribute('password'))) {
$audits
@ -188,7 +188,7 @@ App::post('/v1/account/sessions')
$secret = Auth::tokenGenerator();
$session = new Document(array_merge(
[
'$id' => $dbForInternal->getId(),
'$id' => $dbForProject->getId(),
'userId' => $profile->getId(),
'provider' => Auth::SESSION_PROVIDER_EMAIL,
'providerUid' => $email,
@ -202,13 +202,13 @@ App::post('/v1/account/sessions')
Authorization::setRole('user:' . $profile->getId());
$session = $dbForInternal->createDocument('sessions', $session
$session = $dbForProject->createDocument('sessions', $session
->setAttribute('$read', ['user:' . $profile->getId()])
->setAttribute('$write', ['user:' . $profile->getId()])
);
$profile->setAttribute('sessions', $session, Document::SET_TYPE_APPEND);
$profile = $dbForInternal->updateDocument('users', $profile->getId(), $profile);
$profile = $dbForProject->updateDocument('users', $profile->getId(), $profile);
$audits
->setParam('userId', $profile->getId())
@ -376,17 +376,17 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
->inject('response')
->inject('project')
->inject('user')
->inject('dbForInternal')
->inject('dbForProject')
->inject('geodb')
->inject('audits')
->inject('events')
->inject('usage')
->action(function ($provider, $code, $state, $request, $response, $project, $user, $dbForInternal, $geodb, $audits, $events, $usage) use ($oauthDefaultSuccess) {
->action(function ($provider, $code, $state, $request, $response, $project, $user, $dbForProject, $geodb, $audits, $events, $usage) use ($oauthDefaultSuccess) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var MaxMind\Db\Reader $geodb */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
@ -458,13 +458,13 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
if ($current === $session['$id']) {
unset($sessions[$key]);
$dbForInternal->deleteDocument('sessions', $session->getId());
$dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', $sessions));
$dbForProject->deleteDocument('sessions', $session->getId());
$dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('sessions', $sessions));
}
}
}
$user = ($user->isEmpty()) ? $dbForInternal->findOne('sessions', [ // Get user by provider id
$user = ($user->isEmpty()) ? $dbForProject->findOne('sessions', [ // Get user by provider id
new Query('provider', QUERY::TYPE_EQUAL, [$provider]),
new Query('providerUid', QUERY::TYPE_EQUAL, [$oauth2ID]),
]) : $user;
@ -473,13 +473,13 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
$name = $oauth2->getUserName($accessToken);
$email = $oauth2->getUserEmail($accessToken);
$user = $dbForInternal->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
$user = $dbForProject->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
if ($user === false || $user->isEmpty()) { // Last option -> create the user, generate random password
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
if ($limit !== 0) {
$sum = $dbForInternal->count('users', [ new Query('deleted', Query::TYPE_EQUAL, [false]),], APP_LIMIT_COUNT);
$sum = $dbForProject->count('users', [ new Query('deleted', Query::TYPE_EQUAL, [false]),], APP_LIMIT_COUNT);
if ($sum >= $limit) {
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501);
@ -487,8 +487,8 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
}
try {
$userId = $dbForInternal->getId();
$user = Authorization::skip(fn() => $dbForInternal->createDocument('users', new Document([
$userId = $dbForProject->getId();
$user = Authorization::skip(fn() => $dbForProject->createDocument('users', new Document([
'$id' => $userId,
'$read' => ['role:all'],
'$write' => ['user:' . $userId],
@ -524,7 +524,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
$secret = Auth::tokenGenerator();
$expiry = \time() + Auth::TOKEN_EXPIRATION_LOGIN_LONG;
$session = new Document(array_merge([
'$id' => $dbForInternal->getId(),
'$id' => $dbForProject->getId(),
'userId' => $user->getId(),
'provider' => $provider,
'providerUid' => $oauth2ID,
@ -552,12 +552,12 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
Authorization::setRole('user:' . $user->getId());
$session = $dbForInternal->createDocument('sessions', $session
$session = $dbForProject->createDocument('sessions', $session
->setAttribute('$read', ['user:' . $user->getId()])
->setAttribute('$write', ['user:' . $user->getId()])
);
$user = $dbForInternal->updateDocument('users', $user->getId(), $user);
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
$audits
->setParam('userId', $user->getId())
@ -621,16 +621,16 @@ App::post('/v1/account/sessions/magic-url')
->inject('request')
->inject('response')
->inject('project')
->inject('dbForInternal')
->inject('dbForProject')
->inject('locale')
->inject('audits')
->inject('events')
->inject('mails')
->action(function ($userId, $email, $url, $request, $response, $project, $dbForInternal, $locale, $audits, $events, $mails) {
->action(function ($userId, $email, $url, $request, $response, $project, $dbForProject, $locale, $audits, $events, $mails) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Locale\Locale $locale */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $events */
@ -644,13 +644,13 @@ App::post('/v1/account/sessions/magic-url')
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
$isAppUser = Auth::isAppUser($roles);
$user = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]);
$user = $dbForProject->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]);
if (!$user) {
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
if ($limit !== 0) {
$sum = $dbForInternal->count('users', [
$sum = $dbForProject->count('users', [
new Query('deleted', Query::TYPE_EQUAL, [false]),
], APP_LIMIT_COUNT);
@ -659,9 +659,9 @@ App::post('/v1/account/sessions/magic-url')
}
}
$userId = $userId == 'unique()' ? $dbForInternal->getId() : $userId;
$userId = $userId == 'unique()' ? $dbForProject->getId() : $userId;
$user = Authorization::skip(fn () => $dbForInternal->createDocument('users', new Document([
$user = Authorization::skip(fn () => $dbForProject->createDocument('users', new Document([
'$id' => $userId,
'$read' => ['role:all'],
'$write' => ['user:' . $userId],
@ -689,7 +689,7 @@ App::post('/v1/account/sessions/magic-url')
$expire = \time() + Auth::TOKEN_EXPIRATION_CONFIRM;
$token = new Document([
'$id' => $dbForInternal->getId(),
'$id' => $dbForProject->getId(),
'userId' => $user->getId(),
'type' => Auth::TOKEN_TYPE_MAGIC_URL,
'secret' => Auth::hash($loginSecret), // One way hash encryption to protect DB leak
@ -702,7 +702,7 @@ App::post('/v1/account/sessions/magic-url')
$user->setAttribute('tokens', $token, Document::SET_TYPE_APPEND);
$user = $dbForInternal->updateDocument('users', $user->getId(), $user);
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
if (false === $user) {
throw new Exception('Failed to save user to DB', 500);
@ -766,21 +766,21 @@ App::put('/v1/account/sessions/magic-url')
->param('secret', '', new Text(256), 'Valid verification token.')
->inject('request')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->inject('audits')
->action(function ($userId, $secret, $request, $response, $dbForInternal, $locale, $geodb, $audits) {
->action(function ($userId, $secret, $request, $response, $dbForProject, $locale, $geodb, $audits) {
/** @var string $userId */
/** @var string $secret */
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Locale\Locale $locale */
/** @var MaxMind\Db\Reader $geodb */
/** @var Appwrite\Event\Event $audits */
$user = $dbForInternal->getDocument('users', $userId);
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty() || $user->getAttribute('deleted')) {
throw new Exception('User not found', 404);
@ -798,7 +798,7 @@ App::put('/v1/account/sessions/magic-url')
$expiry = \time() + Auth::TOKEN_EXPIRATION_LOGIN_LONG;
$session = new Document(array_merge(
[
'$id' => $dbForInternal->getId(),
'$id' => $dbForProject->getId(),
'userId' => $user->getId(),
'provider' => Auth::SESSION_PROVIDER_MAGIC_URL,
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
@ -814,7 +814,7 @@ App::put('/v1/account/sessions/magic-url')
Authorization::setRole('user:' . $user->getId());
$session = $dbForInternal->createDocument('sessions', $session
$session = $dbForProject->createDocument('sessions', $session
->setAttribute('$read', ['user:' . $user->getId()])
->setAttribute('$write', ['user:' . $user->getId()])
);
@ -836,7 +836,7 @@ App::put('/v1/account/sessions/magic-url')
->setAttribute('tokens', $tokens);
$user = $dbForInternal->updateDocument('users', $user->getId(), $user);
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
if (false === $user) {
throw new Exception('Failed saving user to DB', 500);
@ -894,17 +894,17 @@ App::post('/v1/account/sessions/anonymous')
->inject('locale')
->inject('user')
->inject('project')
->inject('dbForInternal')
->inject('dbForProject')
->inject('geodb')
->inject('audits')
->inject('usage')
->action(function ($request, $response, $locale, $user, $project, $dbForInternal, $geodb, $audits, $usage) {
->action(function ($request, $response, $locale, $user, $project, $dbForProject, $geodb, $audits, $usage) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Locale\Locale $locale */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var MaxMind\Db\Reader $geodb */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
@ -922,7 +922,7 @@ App::post('/v1/account/sessions/anonymous')
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
if ($limit !== 0) {
$sum = $dbForInternal->count('users', [
$sum = $dbForProject->count('users', [
new Query('deleted', Query::TYPE_EQUAL, [false]),
], APP_LIMIT_COUNT);
@ -931,8 +931,8 @@ App::post('/v1/account/sessions/anonymous')
}
}
$userId = $dbForInternal->getId();
$user = Authorization::skip(fn() => $dbForInternal->createDocument('users', new Document([
$userId = $dbForProject->getId();
$user = Authorization::skip(fn() => $dbForProject->createDocument('users', new Document([
'$id' => $userId,
'$read' => ['role:all'],
'$write' => ['user:' . $userId],
@ -960,7 +960,7 @@ App::post('/v1/account/sessions/anonymous')
$expiry = \time() + Auth::TOKEN_EXPIRATION_LOGIN_LONG;
$session = new Document(array_merge(
[
'$id' => $dbForInternal->getId(),
'$id' => $dbForProject->getId(),
'userId' => $user->getId(),
'provider' => Auth::SESSION_PROVIDER_ANONYMOUS,
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
@ -976,12 +976,12 @@ App::post('/v1/account/sessions/anonymous')
Authorization::setRole('user:' . $user->getId());
$session = $dbForInternal->createDocument('sessions', $session
$session = $dbForProject->createDocument('sessions', $session
->setAttribute('$read', ['user:' . $user->getId()])
->setAttribute('$write', ['user:' . $user->getId()])
);
$user = $dbForInternal->updateDocument('users', $user->getId(),
$user = $dbForProject->updateDocument('users', $user->getId(),
$user->setAttribute('sessions', $session, Document::SET_TYPE_APPEND));
$audits
@ -1178,18 +1178,18 @@ App::get('/v1/account/logs')
->inject('user')
->inject('locale')
->inject('geodb')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($limit, $offset, $response, $user, $locale, $geodb, $dbForInternal, $usage) {
->action(function ($limit, $offset, $response, $user, $locale, $geodb, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Locale\Locale $locale */
/** @var MaxMind\Db\Reader $geodb */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Stats\Stats $usage */
$audit = new Audit($dbForInternal);
$audit = new Audit($dbForProject);
$auditEvents = [
'account.create',
'account.delete',
@ -1262,13 +1262,13 @@ App::get('/v1/account/sessions/:sessionId')
->inject('response')
->inject('user')
->inject('locale')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($sessionId, $response, $user, $locale, $dbForInternal, $usage) {
->action(function ($sessionId, $response, $user, $locale, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Locale\Locale $locale */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Stats\Stats $usage */
$sessions = $user->getAttribute('sessions', []);
@ -1314,17 +1314,17 @@ App::patch('/v1/account/name')
->param('name', '', new Text(128), 'User name. Max length: 128 chars.')
->inject('response')
->inject('user')
->inject('dbForInternal')
->inject('dbForProject')
->inject('audits')
->inject('usage')
->action(function ($name, $response, $user, $dbForInternal, $audits, $usage) {
->action(function ($name, $response, $user, $dbForProject, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
$user = $dbForInternal->updateDocument('users', $user->getId(), $user
$user = $dbForProject->updateDocument('users', $user->getId(), $user
->setAttribute('name', $name)
->setAttribute('search', implode(' ', [$user->getId(), $name, $user->getAttribute('email')]))
);
@ -1358,13 +1358,13 @@ App::patch('/v1/account/password')
->param('oldPassword', '', new Password(), 'Current user password. Must be at least 8 chars.', true)
->inject('response')
->inject('user')
->inject('dbForInternal')
->inject('dbForProject')
->inject('audits')
->inject('usage')
->action(function ($password, $oldPassword, $response, $user, $dbForInternal, $audits, $usage) {
->action(function ($password, $oldPassword, $response, $user, $dbForProject, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
@ -1373,7 +1373,7 @@ App::patch('/v1/account/password')
throw new Exception('Invalid credentials', 401);
}
$user = $dbForInternal->updateDocument('users', $user->getId(), $user
$user = $dbForProject->updateDocument('users', $user->getId(), $user
->setAttribute('password', Auth::passwordHash($password))
->setAttribute('passwordUpdate', \time())
);
@ -1406,13 +1406,13 @@ App::patch('/v1/account/email')
->param('password', '', new Password(), 'User password. Must be at least 8 chars.')
->inject('response')
->inject('user')
->inject('dbForInternal')
->inject('dbForProject')
->inject('audits')
->inject('usage')
->action(function ($email, $password, $response, $user, $dbForInternal, $audits, $usage) {
->action(function ($email, $password, $response, $user, $dbForProject, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
@ -1426,14 +1426,14 @@ App::patch('/v1/account/email')
}
$email = \strtolower($email);
$profile = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
$profile = $dbForProject->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
if ($profile) {
throw new Exception('User already registered', 409);
}
try {
$user = $dbForInternal->updateDocument('users', $user->getId(), $user
$user = $dbForProject->updateDocument('users', $user->getId(), $user
->setAttribute('password', $isAnonymousUser ? Auth::passwordHash($password) : $user->getAttribute('password', ''))
->setAttribute('email', $email)
->setAttribute('emailVerification', false) // After this user needs to confirm mail again
@ -1470,17 +1470,17 @@ App::patch('/v1/account/prefs')
->param('prefs', [], new Assoc(), 'Prefs key-value JSON object.')
->inject('response')
->inject('user')
->inject('dbForInternal')
->inject('dbForProject')
->inject('audits')
->inject('usage')
->action(function ($prefs, $response, $user, $dbForInternal, $audits, $usage) {
->action(function ($prefs, $response, $user, $dbForProject, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
$user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('prefs', $prefs));
$user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('prefs', $prefs));
$audits
->setParam('event', 'account.update.prefs')
@ -1507,21 +1507,21 @@ App::delete('/v1/account')
->inject('request')
->inject('response')
->inject('user')
->inject('dbForInternal')
->inject('dbForProject')
->inject('audits')
->inject('events')
->inject('usage')
->action(function ($request, $response, $user, $dbForInternal, $audits, $events, $usage) {
->action(function ($request, $response, $user, $dbForProject, $audits, $events, $usage) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Stats\Stats $usage */
$protocol = $request->getProtocol();
$user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('status', false));
$user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('status', false));
// TODO Seems to be related to users.php/App::delete('/v1/users/:userId'). Can we share code between these two? Do todos below apply to users.php?
@ -1576,16 +1576,16 @@ App::delete('/v1/account/sessions/:sessionId')
->inject('request')
->inject('response')
->inject('user')
->inject('dbForInternal')
->inject('dbForProject')
->inject('locale')
->inject('audits')
->inject('events')
->inject('usage')
->action(function ($sessionId, $request, $response, $user, $dbForInternal, $locale, $audits, $events, $usage) {
->action(function ($sessionId, $request, $response, $user, $dbForProject, $locale, $audits, $events, $usage) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Locale\Locale $locale */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $events */
@ -1602,7 +1602,7 @@ App::delete('/v1/account/sessions/:sessionId')
if ($sessionId == $session->getId()) {
unset($sessions[$key]);
$dbForInternal->deleteDocument('sessions', $session->getId());
$dbForProject->deleteDocument('sessions', $session->getId());
$audits
->setParam('userId', $user->getId())
@ -1630,7 +1630,7 @@ App::delete('/v1/account/sessions/:sessionId')
;
}
$dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', $sessions));
$dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('sessions', $sessions));
$events
->setParam('eventData', $response->output($session, Response::MODEL_SESSION))
@ -1662,16 +1662,16 @@ App::delete('/v1/account/sessions')
->inject('request')
->inject('response')
->inject('user')
->inject('dbForInternal')
->inject('dbForProject')
->inject('locale')
->inject('audits')
->inject('events')
->inject('usage')
->action(function ($request, $response, $user, $dbForInternal, $locale, $audits, $events, $usage) {
->action(function ($request, $response, $user, $dbForProject, $locale, $audits, $events, $usage) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Locale\Locale $locale */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $events */
@ -1681,7 +1681,7 @@ App::delete('/v1/account/sessions')
$sessions = $user->getAttribute('sessions', []);
foreach ($sessions as $session) {/** @var Document $session */
$dbForInternal->deleteDocument('sessions', $session->getId());
$dbForProject->deleteDocument('sessions', $session->getId());
$audits
->setParam('userId', $user->getId())
@ -1709,7 +1709,7 @@ App::delete('/v1/account/sessions')
}
}
$dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', []));
$dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('sessions', []));
$numOfSessions = count($sessions);
@ -1745,17 +1745,17 @@ App::post('/v1/account/recovery')
->param('url', '', function ($clients) {return new Host($clients);}, 'URL to redirect the user back to your app from the recovery email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', false, ['clients'])
->inject('request')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('project')
->inject('locale')
->inject('mails')
->inject('audits')
->inject('events')
->inject('usage')
->action(function ($email, $url, $request, $response, $dbForInternal, $project, $locale, $mails, $audits, $events, $usage) {
->action(function ($email, $url, $request, $response, $dbForProject, $project, $locale, $mails, $audits, $events, $usage) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Locale\Locale $locale */
/** @var Appwrite\Event\Event $mails */
@ -1772,7 +1772,7 @@ App::post('/v1/account/recovery')
$isAppUser = Auth::isAppUser($roles);
$email = \strtolower($email);
$profile = $dbForInternal->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
$profile = $dbForProject->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
if (!$profile) {
throw new Exception('User not found', 404);
@ -1786,7 +1786,7 @@ App::post('/v1/account/recovery')
$secret = Auth::tokenGenerator();
$recovery = new Document([
'$id' => $dbForInternal->getId(),
'$id' => $dbForProject->getId(),
'userId' => $profile->getId(),
'type' => Auth::TOKEN_TYPE_RECOVERY,
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
@ -1799,7 +1799,7 @@ App::post('/v1/account/recovery')
$profile->setAttribute('tokens', $recovery, Document::SET_TYPE_APPEND);
$profile = $dbForInternal->updateDocument('users', $profile->getId(), $profile);
$profile = $dbForProject->updateDocument('users', $profile->getId(), $profile);
$url = Template::parseURL($url);
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['userId' => $profile->getId(), 'secret' => $secret, 'expire' => $expire]);
@ -1860,12 +1860,12 @@ App::put('/v1/account/recovery')
->param('password', '', new Password(), 'New user password. Must be at least 8 chars.')
->param('passwordAgain', '', new Password(), 'Repeat new user password. Must be at least 8 chars.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('audits')
->inject('usage')
->action(function ($userId, $secret, $password, $passwordAgain, $response, $dbForInternal, $audits, $usage) {
->action(function ($userId, $secret, $password, $passwordAgain, $response, $dbForProject, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
@ -1873,7 +1873,7 @@ App::put('/v1/account/recovery')
throw new Exception('Passwords must match', 400);
}
$profile = $dbForInternal->getDocument('users', $userId);
$profile = $dbForProject->getDocument('users', $userId);
if ($profile->isEmpty() || $profile->getAttribute('deleted')) {
throw new Exception('User not found', 404);
@ -1888,7 +1888,7 @@ App::put('/v1/account/recovery')
Authorization::setRole('user:' . $profile->getId());
$profile = $dbForInternal->updateDocument('users', $profile->getId(), $profile
$profile = $dbForProject->updateDocument('users', $profile->getId(), $profile
->setAttribute('password', Auth::passwordHash($password))
->setAttribute('passwordUpdate', \time())
->setAttribute('emailVerification', true)
@ -1905,7 +1905,7 @@ App::put('/v1/account/recovery')
}
}
$dbForInternal->updateDocument('users', $profile->getId(), $profile->setAttribute('tokens', $tokens));
$dbForProject->updateDocument('users', $profile->getId(), $profile->setAttribute('tokens', $tokens));
$audits
->setParam('userId', $profile->getId())
@ -1938,18 +1938,18 @@ App::post('/v1/account/verification')
->inject('response')
->inject('project')
->inject('user')
->inject('dbForInternal')
->inject('dbForProject')
->inject('locale')
->inject('audits')
->inject('events')
->inject('mails')
->inject('usage')
->action(function ($url, $request, $response, $project, $user, $dbForInternal, $locale, $audits, $events, $mails, $usage) {
->action(function ($url, $request, $response, $project, $user, $dbForProject, $locale, $audits, $events, $mails, $usage) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Locale\Locale $locale */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $events */
@ -1969,7 +1969,7 @@ App::post('/v1/account/verification')
$expire = \time() + Auth::TOKEN_EXPIRATION_CONFIRM;
$verification = new Document([
'$id' => $dbForInternal->getId(),
'$id' => $dbForProject->getId(),
'userId' => $user->getId(),
'type' => Auth::TOKEN_TYPE_VERIFICATION,
'secret' => Auth::hash($verificationSecret), // One way hash encryption to protect DB leak
@ -1982,7 +1982,7 @@ App::post('/v1/account/verification')
$user->setAttribute('tokens', $verification, Document::SET_TYPE_APPEND);
$user = $dbForInternal->updateDocument('users', $user->getId(), $user);
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
$url = Template::parseURL($url);
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['userId' => $user->getId(), 'secret' => $verificationSecret, 'expire' => $expire]);
@ -2042,17 +2042,17 @@ App::put('/v1/account/verification')
->param('secret', '', new Text(256), 'Valid verification token.')
->inject('response')
->inject('user')
->inject('dbForInternal')
->inject('dbForProject')
->inject('audits')
->inject('usage')
->action(function ($userId, $secret, $response, $user, $dbForInternal, $audits, $usage) {
->action(function ($userId, $secret, $response, $user, $dbForProject, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
$profile = $dbForInternal->getDocument('users', $userId);
$profile = $dbForProject->getDocument('users', $userId);
if ($profile->isEmpty()) {
throw new Exception('User not found', 404);
@ -2067,7 +2067,7 @@ App::put('/v1/account/verification')
Authorization::setRole('user:' . $profile->getId());
$profile = $dbForInternal->updateDocument('users', $profile->getId(), $profile->setAttribute('emailVerification', true));
$profile = $dbForProject->updateDocument('users', $profile->getId(), $profile->setAttribute('emailVerification', true));
/**
* We act like we're updating and validating
@ -2080,7 +2080,7 @@ App::put('/v1/account/verification')
}
}
$dbForInternal->updateDocument('users', $profile->getId(), $profile->setAttribute('tokens', $tokens));
$dbForProject->updateDocument('users', $profile->getId(), $profile->setAttribute('tokens', $tokens));
$audits
->setParam('userId', $profile->getId())

View file

@ -33,6 +33,8 @@ use Appwrite\Network\Validator\IP;
use Appwrite\Network\Validator\URL;
use Appwrite\Utopia\Response;
use Appwrite\Detector\Detector;
use Appwrite\Event\Event;
use Appwrite\Stats\Stats;
/**
* Create attribute of varying type
@ -40,15 +42,14 @@ use Appwrite\Detector\Detector;
* @param string $collectionId
* @param Utopia\Database\Document $attribute
* @param Appwrite\Utopia\Response $response
* @param Utopia\Database\Database $dbForInternal
* @param Utopia\Database\Database $dbForExternal
* @param Utopia\Database\Database $dbForProject
* @param Appwrite\Event\Event $database
* @param Appwrite\Event\Event $audits
* @param Appwrite\Stats\Stats $usage
*
* @return Document Newly created attribute document
*/
function createAttribute($collectionId, $attribute, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage): Document
function createAttribute(string $collectionId, Document $attribute, Response $response, Database $dbForProject, Event $database, Event $audits, Stats $usage): Document
{
$key = $attribute->getAttribute('key');
$type = $attribute->getAttribute('type', '');
@ -61,7 +62,7 @@ function createAttribute($collectionId, $attribute, $response, $dbForInternal, $
$filters = $attribute->getAttribute('filters', []); // filters are hidden from the endpoint
$default = $attribute->getAttribute('default');
$collection = $dbForInternal->getDocument('collections', $collectionId);
$collection = $dbForProject->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -73,7 +74,7 @@ function createAttribute($collectionId, $attribute, $response, $dbForInternal, $
}
}
// Must throw here since dbForExternal->createAttribute is performed by db worker
// Must throw here since dbForProject->createAttribute is performed by db worker
if ($required && $default) {
throw new Exception('Cannot set default value for required attribute', 400);
}
@ -99,8 +100,8 @@ function createAttribute($collectionId, $attribute, $response, $dbForInternal, $
'filters' => $filters,
]);
$dbForInternal->checkAttribute($collection, $attribute);
$attribute = $dbForInternal->createDocument('attributes', $attribute);
$dbForProject->checkAttribute($collection, $attribute);
$attribute = $dbForProject->createDocument('attributes', $attribute);
}
catch (DuplicateException $exception) {
throw new Exception('Attribute already exists', 409);
@ -109,8 +110,8 @@ function createAttribute($collectionId, $attribute, $response, $dbForInternal, $
throw new Exception('Attribute limit exceeded', 400);
}
$dbForInternal->deleteCachedDocument('collections', $collectionId);
$dbForExternal->deleteCachedCollection($collectionId);
$dbForProject->deleteCachedDocument('collections', $collectionId);
$dbForProject->deleteCachedCollection($collectionId);
// Pass clone of $attribute object to workers
// so we can later modify Document to fit response model
@ -153,22 +154,21 @@ App::post('/v1/database/collections')
->param('read', null, new Permissions(), 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.')
->param('write', null, new Permissions(), 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.')
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('dbForProject')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $name, $permission, $read, $write, $response, $dbForInternal, $dbForExternal, $audits, $usage) {
->action(function ($collectionId, $name, $permission, $read, $write, $response, $dbForProject, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal*/
/** @var Utopia\Database\Database $dbForProject*/
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
$collectionId = $collectionId == 'unique()' ? $dbForExternal->getId() : $collectionId;
$collectionId = $collectionId == 'unique()' ? $dbForProject->getId() : $collectionId;
try {
$dbForExternal->createCollection('collection_' . $collectionId);
$dbForProject->createCollection('collection_' . $collectionId);
$collection = $dbForInternal->createDocument('collections', new Document([
$collection = $dbForProject->createDocument('collections', new Document([
'$id' => $collectionId,
'$read' => $read ?? [], // Collection permissions for collection documents (based on permission model)
'$write' => $write ?? [], // Collection permissions for collection documents (based on permission model)
@ -213,14 +213,14 @@ App::get('/v1/database/collections')
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal, $usage) {
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
if (!empty($cursor)) {
$cursorCollection = $dbForInternal->getDocument('collections', $cursor);
$cursorCollection = $dbForProject->getDocument('collections', $cursor);
if ($cursorCollection->isEmpty()) {
throw new Exception("Collection '{$cursor}' for the 'cursor' value not found.", 400);
@ -236,8 +236,8 @@ App::get('/v1/database/collections')
$usage->setParam('database.collections.read', 1);
$response->dynamic(new Document([
'collections' => $dbForInternal->find('collections', $queries, $limit, $offset, [], [$orderType], $cursorCollection ?? null, $cursorDirection),
'sum' => $dbForInternal->count('collections', $queries, APP_LIMIT_COUNT),
'collections' => $dbForProject->find('collections', $queries, $limit, $offset, [], [$orderType], $cursorCollection ?? null, $cursorDirection),
'sum' => $dbForProject->count('collections', $queries, APP_LIMIT_COUNT),
]), Response::MODEL_COLLECTION_LIST);
});
@ -254,13 +254,13 @@ App::get('/v1/database/collections/:collectionId')
->label('sdk.response.model', Response::MODEL_COLLECTION)
->param('collectionId', '', new UID(), 'Collection ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($collectionId, $response, $dbForInternal, $usage) {
->action(function ($collectionId, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
$collection = $dbForInternal->getDocument('collections', $collectionId);
$collection = $dbForProject->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -283,11 +283,11 @@ App::get('/v1/database/usage')
->label('sdk.response.model', Response::MODEL_USAGE_DATABASE)
->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true)
->inject('response')
->inject('dbForInternal')
->action(function ($range, $response, $dbForInternal) {
->inject('dbForProject')
->action(function ($range, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForConsole */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Registry\Registry $register */
$usage = [];
@ -326,12 +326,12 @@ App::get('/v1/database/usage')
$stats = [];
Authorization::skip(function() use ($dbForInternal, $periods, $range, $metrics, &$stats) {
Authorization::skip(function() use ($dbForProject, $periods, $range, $metrics, &$stats) {
foreach ($metrics as $metric) {
$limit = $periods[$range]['limit'];
$period = $periods[$range]['period'];
$requestDocs = $dbForInternal->find('stats', [
$requestDocs = $dbForProject->find('stats', [
new Query('period', Query::TYPE_EQUAL, [$period]),
new Query('metric', Query::TYPE_EQUAL, [$metric]),
], $limit, 0, ['time'], [Database::ORDER_DESC]);
@ -394,15 +394,13 @@ App::get('/v1/database/:collectionId/usage')
->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true)
->param('collectionId', '', new UID(), 'Collection ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->action(function ($range, $collectionId, $response, $dbForInternal, $dbForExternal) {
->inject('dbForProject')
->action(function ($range, $collectionId, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForConsole */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Registry\Registry $register */
$collection = $dbForExternal->getCollection('collection_' . $collectionId);
$collection = $dbForProject->getCollection('collection_' . $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -439,12 +437,12 @@ App::get('/v1/database/:collectionId/usage')
$stats = [];
Authorization::skip(function() use ($dbForInternal, $periods, $range, $metrics, &$stats) {
Authorization::skip(function() use ($dbForProject, $periods, $range, $metrics, &$stats) {
foreach ($metrics as $metric) {
$limit = $periods[$range]['limit'];
$period = $periods[$range]['period'];
$requestDocs = $dbForInternal->find('stats', [
$requestDocs = $dbForProject->find('stats', [
new Query('period', Query::TYPE_EQUAL, [$period]),
new Query('metric', Query::TYPE_EQUAL, [$metric]),
], $limit, 0, ['time'], [Database::ORDER_DESC]);
@ -503,25 +501,23 @@ App::get('/v1/database/collections/:collectionId/logs')
->param('limit', 25, new Range(0, 100), 'Maximum number of logs to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->action(function ($collectionId, $limit, $offset, $response, $dbForInternal, $dbForExternal, $locale, $geodb) {
->action(function ($collectionId, $limit, $offset, $response, $dbForProject, $locale, $geodb) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Locale\Locale $locale */
/** @var MaxMind\Db\Reader $geodb */
$collection = $dbForExternal->getCollection('collection_' . $collectionId);
$collection = $dbForProject->getCollection('collection_' . $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
}
$audit = new Audit($dbForInternal);
$audit = new Audit($dbForProject);
$resource = 'collection/'.$collection->getId();
$logs = $audit->getLogsByResource($resource, $limit, $offset);
@ -595,16 +591,16 @@ App::put('/v1/database/collections/:collectionId')
->param('write', null, new Permissions(), 'An array of strings with write permissions. By default inherits the existing write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true)
->param('enabled', true, new Boolean(), 'Is collection enabled?', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $name, $permission, $read, $write, $enabled, $response, $dbForInternal, $audits, $usage) {
->action(function ($collectionId, $name, $permission, $read, $write, $enabled, $response, $dbForProject, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
$collection = $dbForInternal->getDocument('collections', $collectionId);
$collection = $dbForProject->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -615,7 +611,7 @@ App::put('/v1/database/collections/:collectionId')
$enabled ??= $collection->getAttribute('enabled', true);
try {
$collection = $dbForInternal->updateDocument('collections', $collection->getId(), $collection
$collection = $dbForProject->updateDocument('collections', $collection->getId(), $collection
->setAttribute('$write', $write)
->setAttribute('$read', $read)
->setAttribute('name', $name)
@ -656,31 +652,29 @@ App::delete('/v1/database/collections/:collectionId')
->label('sdk.response.model', Response::MODEL_NONE)
->param('collectionId', '', new UID(), 'Collection ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('dbForProject')
->inject('events')
->inject('audits')
->inject('deletes')
->inject('usage')
->action(function ($collectionId, $response, $dbForInternal, $dbForExternal, $events, $audits, $deletes, $usage) {
->action(function ($collectionId, $response, $dbForProject, $events, $audits, $deletes, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $audits */
$collection = $dbForInternal->getDocument('collections', $collectionId);
$collection = $dbForProject->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
}
if (!$dbForInternal->deleteDocument('collections', $collectionId)) {
if (!$dbForProject->deleteDocument('collections', $collectionId)) {
throw new Exception('Failed to remove collection from DB', 500);
}
$dbForExternal->deleteCachedCollection('collection_' . $collection->getId());
$dbForProject->deleteCachedCollection('collection_' . $collection->getId());
$deletes
->setParam('type', DELETE_TYPE_DOCUMENT)
@ -721,15 +715,13 @@ App::post('/v1/database/collections/:collectionId/attributes/string')
->param('default', null, new Text(0), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('dbForProject')
->inject('database')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $key, $size, $required, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage) {
->action(function ($collectionId, $key, $size, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal*/
/** @var Utopia\Database\Database $dbForExternal*/
/** @var Utopia\Database\Database $dbForProject*/
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
@ -747,7 +739,7 @@ App::post('/v1/database/collections/:collectionId/attributes/string')
'required' => $required,
'default' => $default,
'array' => $array,
]), $response, $dbForInternal, $dbForExternal, $database, $audits, $usage);
]), $response, $dbForProject, $database, $audits, $usage);
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE_STRING);
});
@ -770,15 +762,13 @@ App::post('/v1/database/collections/:collectionId/attributes/email')
->param('default', null, new Email(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('dbForProject')
->inject('database')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage) {
->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal*/
/** @var Utopia\Database\Database $dbForExternal*/
/** @var Utopia\Database\Database $dbForProject*/
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
@ -791,7 +781,7 @@ App::post('/v1/database/collections/:collectionId/attributes/email')
'default' => $default,
'array' => $array,
'format' => APP_DATABASE_ATTRIBUTE_EMAIL,
]), $response, $dbForInternal, $dbForExternal, $database, $audits, $usage);
]), $response, $dbForProject, $database, $audits, $usage);
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE_EMAIL);
});
@ -815,15 +805,13 @@ App::post('/v1/database/collections/:collectionId/attributes/enum')
->param('default', null, new Text(0), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('dbForProject')
->inject('database')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $key, $elements, $required, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage) {
->action(function ($collectionId, $key, $elements, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal*/
/** @var Utopia\Database\Database $dbForExternal*/
/** @var Utopia\Database\Database $dbForProject*/
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
@ -852,7 +840,7 @@ App::post('/v1/database/collections/:collectionId/attributes/enum')
'array' => $array,
'format' => APP_DATABASE_ATTRIBUTE_ENUM,
'formatOptions' => ['elements' => $elements],
]), $response, $dbForInternal, $dbForExternal, $database, $audits, $usage);
]), $response, $dbForProject, $database, $audits, $usage);
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE_ENUM);
});
@ -875,15 +863,13 @@ App::post('/v1/database/collections/:collectionId/attributes/ip')
->param('default', null, new IP(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('dbForProject')
->inject('database')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage) {
->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal*/
/** @var Utopia\Database\Database $dbForExternal*/
/** @var Utopia\Database\Database $dbForProject*/
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
@ -896,7 +882,7 @@ App::post('/v1/database/collections/:collectionId/attributes/ip')
'default' => $default,
'array' => $array,
'format' => APP_DATABASE_ATTRIBUTE_IP,
]), $response, $dbForInternal, $dbForExternal, $database, $audits, $usage);
]), $response, $dbForProject, $database, $audits, $usage);
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE_IP);
});
@ -919,14 +905,12 @@ App::post('/v1/database/collections/:collectionId/attributes/url')
->param('default', null, new URL(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('dbForProject')
->inject('database')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage) {
->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal*/
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
@ -939,7 +923,7 @@ App::post('/v1/database/collections/:collectionId/attributes/url')
'default' => $default,
'array' => $array,
'format' => APP_DATABASE_ATTRIBUTE_URL,
]), $response, $dbForInternal, $dbForExternal, $database, $audits, $usage);
]), $response, $dbForProject, $database, $audits, $usage);
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE_URL);
});
@ -964,15 +948,13 @@ App::post('/v1/database/collections/:collectionId/attributes/integer')
->param('default', null, new Integer(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('dbForProject')
->inject('database')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $key, $required, $min, $max, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage) {
->action(function ($collectionId, $key, $required, $min, $max, $default, $array, $response, $dbForProject, $database, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal*/
/** @var Utopia\Database\Database $dbForExternal*/
/** @var Utopia\Database\Database $dbForProject*/
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
@ -1003,7 +985,7 @@ App::post('/v1/database/collections/:collectionId/attributes/integer')
'min' => $min,
'max' => $max,
],
]), $response, $dbForInternal, $dbForExternal, $database, $audits, $usage);
]), $response, $dbForProject, $database, $audits, $usage);
$formatOptions = $attribute->getAttribute('formatOptions', []);
@ -1035,15 +1017,13 @@ App::post('/v1/database/collections/:collectionId/attributes/float')
->param('default', null, new FloatValidator(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('dbForProject')
->inject('database')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $key, $required, $min, $max, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage) {
->action(function ($collectionId, $key, $required, $min, $max, $default, $array, $response, $dbForProject, $database, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal*/
/** @var Utopia\Database\Database $dbForExternal*/
/** @var Utopia\Database\Database $dbForProject*/
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
@ -1079,7 +1059,7 @@ App::post('/v1/database/collections/:collectionId/attributes/float')
'min' => $min,
'max' => $max,
],
]), $response, $dbForInternal, $dbForExternal, $database, $audits, $usage);
]), $response, $dbForProject, $database, $audits, $usage);
$formatOptions = $attribute->getAttribute('formatOptions', []);
@ -1109,14 +1089,13 @@ App::post('/v1/database/collections/:collectionId/attributes/boolean')
->param('default', null, new Boolean(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('dbForProject')
->inject('database')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage) {
->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal*/
/** @var Utopia\Database\Database $dbForProject*/
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
@ -1128,7 +1107,7 @@ App::post('/v1/database/collections/:collectionId/attributes/boolean')
'required' => $required,
'default' => $default,
'array' => $array,
]), $response, $dbForInternal, $dbForExternal, $database, $audits, $usage);
]), $response, $dbForProject, $database, $audits, $usage);
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE_BOOLEAN);
});
@ -1146,13 +1125,13 @@ App::get('/v1/database/collections/:collectionId/attributes')
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_LIST)
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($collectionId, $response, $dbForInternal, $usage) {
->action(function ($collectionId, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
$collection = $dbForInternal->getDocument('collections', $collectionId);
$collection = $dbForProject->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -1190,13 +1169,13 @@ App::get('/v1/database/collections/:collectionId/attributes/:key')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('key', '', new Key(), 'Attribute Key.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($collectionId, $key, $response, $dbForInternal, $usage) {
->action(function ($collectionId, $key, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
$collection = $dbForInternal->getDocument('collections', $collectionId);
$collection = $dbForProject->getDocument('collections', $collectionId);
if (empty($collection)) {
throw new Exception('Collection not found', 404);
@ -1245,28 +1224,26 @@ App::delete('/v1/database/collections/:collectionId/attributes/:key')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('key', '', new Key(), 'Attribute Key.')
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('dbForProject')
->inject('database')
->inject('events')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $key, $response, $dbForInternal, $dbForExternal, $database, $events, $audits, $usage) {
->action(function ($collectionId, $key, $response, $dbForProject, $database, $events, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
$collection = $dbForInternal->getDocument('collections', $collectionId);
$collection = $dbForProject->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
}
$attribute = $dbForInternal->getDocument('attributes', $collectionId.'_'.$key);
$attribute = $dbForProject->getDocument('attributes', $collectionId.'_'.$key);
if (empty($attribute->getId())) {
throw new Exception('Attribute not found', 404);
@ -1274,11 +1251,11 @@ App::delete('/v1/database/collections/:collectionId/attributes/:key')
// Only update status if removing available attribute
if ($attribute->getAttribute('status' === 'available')) {
$attribute = $dbForInternal->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'deleting'));
$attribute = $dbForProject->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'deleting'));
}
$dbForInternal->deleteCachedDocument('collections', $collectionId);
$dbForExternal->deleteCachedCollection($collection->getId());
$dbForProject->deleteCachedDocument('collections', $collectionId);
$dbForProject->deleteCachedCollection($collection->getId());
$database
->setParam('type', DATABASE_TYPE_DELETE_ATTRIBUTE)
@ -1337,24 +1314,24 @@ App::post('/v1/database/collections/:collectionId/indexes')
->param('attributes', null, new ArrayList(new Key()), 'Array of attributes to index.')
->param('orders', [], new ArrayList(new WhiteList(['ASC', 'DESC'], false, Database::VAR_STRING)), 'Array of index orders.', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('database')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $key, $type, $attributes, $orders, $response, $dbForInternal, $database, $audits, $usage) {
->action(function ($collectionId, $key, $type, $attributes, $orders, $response, $dbForProject, $database, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $audits */
$collection = $dbForInternal->getDocument('collections', $collectionId);
$collection = $dbForProject->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
}
$count = $dbForInternal->count('indexes', [
$count = $dbForProject->count('indexes', [
new Query('collectionId', Query::TYPE_EQUAL, [$collectionId])
], 61);
@ -1365,9 +1342,7 @@ App::post('/v1/database/collections/:collectionId/indexes')
}
// Convert Document[] to array of attribute metadata
$oldAttributes = \array_map(function ($a) {
return $a->getArrayCopy();
}, $collection->getAttribute('attributes'));
$oldAttributes = \array_map(fn ($a) => $a->getArrayCopy(), $collection->getAttribute('attributes'));
// lengths hidden by default
$lengths = [];
@ -1394,7 +1369,7 @@ App::post('/v1/database/collections/:collectionId/indexes')
}
try {
$index = $dbForInternal->createDocument('indexes', new Document([
$index = $dbForProject->createDocument('indexes', new Document([
'$id' => $collectionId.'_'.$key,
'key' => $key,
'status' => 'processing', // processing, available, failed, deleting, stuck
@ -1408,7 +1383,7 @@ App::post('/v1/database/collections/:collectionId/indexes')
throw new Exception('Index already exists', 409);
}
$dbForInternal->deleteCachedDocument('collections', $collectionId);
$dbForProject->deleteCachedDocument('collections', $collectionId);
$database
->setParam('type', DATABASE_TYPE_CREATE_INDEX)
@ -1441,13 +1416,13 @@ App::get('/v1/database/collections/:collectionId/indexes')
->label('sdk.response.model', Response::MODEL_INDEX_LIST)
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($collectionId, $response, $dbForInternal, $usage) {
->action(function ($collectionId, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
$collection = $dbForInternal->getDocument('collections', $collectionId);
$collection = $dbForProject->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -1477,13 +1452,13 @@ App::get('/v1/database/collections/:collectionId/indexes/:key')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('key', null, new Key(), 'Index Key.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($collectionId, $key, $response, $dbForInternal, $usage) {
->action(function ($collectionId, $key, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
$collection = $dbForInternal->getDocument('collections', $collectionId);
$collection = $dbForProject->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -1521,26 +1496,26 @@ App::delete('/v1/database/collections/:collectionId/indexes/:key')
->param('collectionId', null, new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('key', '', new Key(), 'Index Key.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('database')
->inject('events')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $key, $response, $dbForInternal, $database, $events, $audits, $usage) {
->action(function ($collectionId, $key, $response, $dbForProject, $database, $events, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
$collection = $dbForInternal->getDocument('collections', $collectionId);
$collection = $dbForProject->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
}
$index = $dbForInternal->getDocument('indexes', $collectionId.'_'.$key);
$index = $dbForProject->getDocument('indexes', $collectionId.'_'.$key);
if (empty($index->getId())) {
throw new Exception('Index not found', 404);
@ -1548,10 +1523,10 @@ App::delete('/v1/database/collections/:collectionId/indexes/:key')
// Only update status if removing available index
if ($index->getAttribute('status') === 'available') {
$index = $dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'deleting'));
$index = $dbForProject->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'deleting'));
}
$dbForInternal->deleteCachedDocument('collections', $collectionId);
$dbForProject->deleteCachedDocument('collections', $collectionId);
$database
->setParam('type', DATABASE_TYPE_DELETE_INDEX)
@ -1592,17 +1567,15 @@ App::post('/v1/database/collections/:collectionId/documents')
->param('read', null, new Permissions(), 'An array of strings with read permissions. By default only the current user is granted with read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true)
->param('write', null, new Permissions(), 'An array of strings with write permissions. By default only the current user is granted with write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('dbForProject')
->inject('user')
->inject('audits')
->inject('usage')
->inject('events')
->inject('mode')
->action(function ($documentId, $collectionId, $data, $read, $write, $response, $dbForInternal, $dbForExternal, $user, $audits, $usage, $events, $mode) {
->action(function ($documentId, $collectionId, $data, $read, $write, $response, $dbForProject, $user, $audits, $usage, $events, $mode) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Database\Document $user */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
@ -1624,7 +1597,7 @@ App::post('/v1/database/collections/:collectionId/documents')
*
* @var Document $collection
*/
$collection = Authorization::skip(fn() => $dbForInternal->getDocument('collections', $collectionId));
$collection = Authorization::skip(fn() => $dbForProject->getDocument('collections', $collectionId));
if ($collection->isEmpty() || !$collection->getAttribute('enabled')) {
if (!($mode === APP_MODE_ADMIN && Auth::isPrivilegedUser(Authorization::getRoles()))) {
@ -1641,7 +1614,7 @@ App::post('/v1/database/collections/:collectionId/documents')
}
$data['$collection'] = $collection->getId(); // Adding this param to make API easier for developers
$data['$id'] = $documentId == 'unique()' ? $dbForExternal->getId() : $documentId;
$data['$id'] = $documentId == 'unique()' ? $dbForProject->getId() : $documentId;
$data['$read'] = (is_null($read) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $read ?? []; // By default set read permissions for user
$data['$write'] = (is_null($write) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $write ?? []; // By default set write permissions for user
@ -1664,9 +1637,9 @@ App::post('/v1/database/collections/:collectionId/documents')
try {
if ($collection->getAttribute('permission') === 'collection') {
/** @var Document $document */
$document = Authorization::skip(fn() => $dbForExternal->createDocument('collection_' . $collectionId, new Document($data)));
$document = Authorization::skip(fn() => $dbForProject->createDocument('collection_' . $collectionId, new Document($data)));
} else {
$document = $dbForExternal->createDocument('collection_' . $collectionId, new Document($data));
$document = $dbForProject->createDocument('collection_' . $collectionId, new Document($data));
}
$document->setAttribute('$collection', $collectionId);
}
@ -1714,17 +1687,13 @@ App::get('/v1/database/collections/:collectionId/documents')
->param('orderAttributes', [], new ArrayList(new Text(128)), 'Array of attributes used to sort results.', true)
->param('orderTypes', [], new ArrayList(new WhiteList(['DESC', 'ASC'], true)), 'Array of order directions for sorting attribtues. Possible values are DESC for descending order, or ASC for ascending order.', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('user')
->inject('dbForProject')
->inject('usage')
->inject('mode')
->action(function ($collectionId, $queries, $limit, $offset, $cursor, $cursorDirection, $orderAttributes, $orderTypes, $response, $dbForInternal, $dbForExternal, $user, $usage, $mode) {
->action(function ($collectionId, $queries, $limit, $offset, $cursor, $cursorDirection, $orderAttributes, $orderTypes, $response, $dbForProject, $usage, $mode) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Stats\Stats $usage */
/** @var Utopia\Database\Document $user */
/** @var string $mode */
/**
@ -1732,7 +1701,7 @@ App::get('/v1/database/collections/:collectionId/documents')
*
* @var Utopia\Database\Document $collection
*/
$collection = Authorization::skip(fn() => $dbForInternal->getDocument('collections', $collectionId));
$collection = Authorization::skip(fn() => $dbForProject->getDocument('collections', $collectionId));
if ($collection->isEmpty() || !$collection->getAttribute('enabled')) {
if (!($mode === APP_MODE_ADMIN && Auth::isPrivilegedUser(Authorization::getRoles()))) {
@ -1748,9 +1717,7 @@ App::get('/v1/database/collections/:collectionId/documents')
}
}
$queries = \array_map(function ($query) {
return Query::parse($query);
}, $queries);
$queries = \array_map(fn ($query) => Query::parse($query), $queries);
if (!empty($queries)) {
$validator = new QueriesValidator(new QueryValidator($collection->getAttribute('attributes', [])), $collection->getAttribute('indexes', []), true);
@ -1761,7 +1728,7 @@ App::get('/v1/database/collections/:collectionId/documents')
$cursorDocument = null;
if (!empty($cursor)) {
$cursorDocument = $dbForExternal->getDocument('collection_' . $collectionId, $cursor);
$cursorDocument = $dbForProject->getDocument('collection_' . $collectionId, $cursor);
if ($cursorDocument->isEmpty()) {
throw new Exception("Document '{$cursor}' for the 'cursor' value not found.", 400);
@ -1770,11 +1737,11 @@ App::get('/v1/database/collections/:collectionId/documents')
if ($collection->getAttribute('permission') === 'collection') {
/** @var Document[] $documents */
$documents = Authorization::skip(fn() => $dbForExternal->find('collection_' . $collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $cursorDocument ?? null, $cursorDirection));
$sum = Authorization::skip(fn() => $dbForExternal->count('collection_' . $collectionId, $queries, APP_LIMIT_COUNT));
$documents = Authorization::skip(fn() => $dbForProject->find('collection_' . $collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $cursorDocument ?? null, $cursorDirection));
$sum = Authorization::skip(fn() => $dbForProject->count('collection_' . $collectionId, $queries, APP_LIMIT_COUNT));
} else {
$documents = $dbForExternal->find('collection_' . $collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $cursorDocument ?? null, $cursorDirection);
$sum = $dbForExternal->count('collection_' . $collectionId, $queries, APP_LIMIT_COUNT);
$documents = $dbForProject->find('collection_' . $collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $cursorDocument ?? null, $cursorDirection);
$sum = $dbForProject->count('collection_' . $collectionId, $queries, APP_LIMIT_COUNT);
}
/**
@ -1807,20 +1774,18 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId')
->param('collectionId', null, new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('documentId', null, new UID(), 'Document ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('dbForProject')
->inject('usage')
->inject('mode')
->action(function ($collectionId, $documentId, $response, $dbForInternal, $dbForExternal, $usage, $mode) {
->action(function ($collectionId, $documentId, $response, $dbForProject, $usage, $mode) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $$dbForInternal */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var string $mode */
/**
* Skip Authorization to get the collection. Needed in case of empty permissions for document level permissions.
*/
$collection = Authorization::skip(fn() => $dbForInternal->getDocument('collections', $collectionId));
$collection = Authorization::skip(fn() => $dbForProject->getDocument('collections', $collectionId));
if ($collection->isEmpty() || !$collection->getAttribute('enabled')) {
if (!($mode === APP_MODE_ADMIN && Auth::isPrivilegedUser(Authorization::getRoles()))) {
@ -1838,9 +1803,9 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId')
if ($collection->getAttribute('permission') === 'collection') {
/** @var Document $document */
$document = Authorization::skip(fn() => $dbForExternal->getDocument('collection_' . $collectionId, $documentId));
$document = Authorization::skip(fn() => $dbForProject->getDocument('collection_' . $collectionId, $documentId));
} else {
$document = $dbForExternal->getDocument('collection_' . $collectionId, $documentId);
$document = $dbForProject->getDocument('collection_' . $collectionId, $documentId);
}
/**
@ -1876,31 +1841,29 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId/logs')
->param('limit', 25, new Range(0, 100), 'Maximum number of logs to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->action(function ($collectionId, $documentId, $limit, $offset, $response, $dbForInternal, $dbForExternal, $locale, $geodb) {
->action(function ($collectionId, $documentId, $limit, $offset, $response, $dbForProject, $locale, $geodb) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Locale\Locale $locale */
/** @var MaxMind\Db\Reader $geodb */
$collection = $dbForInternal->getDocument('collections', $collectionId);
$collection = $dbForProject->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
}
$document = $dbForExternal->getDocument('collection_' . $collectionId, $documentId);
$document = $dbForProject->getDocument('collection_' . $collectionId, $documentId);
if ($document->isEmpty()) {
throw new Exception('No document found', 404);
}
$audit = new Audit($dbForInternal);
$audit = new Audit($dbForProject);
$resource = 'document/'.$document->getId();
$logs = $audit->getLogsByResource($resource, $limit, $offset);
@ -1972,16 +1935,14 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
->param('read', null, new Permissions(), 'An array of strings with read permissions. By default inherits the existing read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true)
->param('write', null, new Permissions(), 'An array of strings with write permissions. By default inherits the existing write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('dbForProject')
->inject('audits')
->inject('usage')
->inject('events')
->inject('mode')
->action(function ($collectionId, $documentId, $data, $read, $write, $response, $dbForInternal, $dbForExternal, $audits, $usage, $events, $mode) {
->action(function ($collectionId, $documentId, $data, $read, $write, $response, $dbForProject, $audits, $usage, $events, $mode) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
/** @var Appwrite\Event\Event $events */
@ -1990,7 +1951,7 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
/**
* Skip Authorization to get the collection. Needed in case of empty permissions for document level permissions.
*/
$collection = Authorization::skip(fn() => $dbForInternal->getDocument('collections', $collectionId));
$collection = Authorization::skip(fn() => $dbForProject->getDocument('collections', $collectionId));
if ($collection->isEmpty() || !$collection->getAttribute('enabled')) {
if (!($mode === APP_MODE_ADMIN && Auth::isPrivilegedUser(Authorization::getRoles()))) {
@ -2005,9 +1966,9 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
throw new Exception('Unauthorized permissions', 401);
}
$document = Authorization::skip(fn() => $dbForExternal->getDocument('collection_' . $collectionId, $documentId));
$document = Authorization::skip(fn() => $dbForProject->getDocument('collection_' . $collectionId, $documentId));
} else {
$document = $dbForExternal->getDocument('collection_' . $collectionId, $documentId);
$document = $dbForProject->getDocument('collection_' . $collectionId, $documentId);
}
@ -2051,9 +2012,9 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
try {
if ($collection->getAttribute('permission') === 'collection') {
/** @var Document $document */
$document = Authorization::skip(fn() => $dbForExternal->updateDocument('collection_' . $collection->getId(), $document->getId(), new Document($data)));
$document = Authorization::skip(fn() => $dbForProject->updateDocument('collection_' . $collection->getId(), $document->getId(), new Document($data)));
} else {
$document = $dbForExternal->updateDocument('collection_' . $collection->getId(), $document->getId(), new Document($data));
$document = $dbForProject->updateDocument('collection_' . $collection->getId(), $document->getId(), new Document($data));
}
/**
* Reset $collection attribute to remove prefix.
@ -2100,15 +2061,14 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId')
->param('collectionId', null, new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('documentId', null, new UID(), 'Document ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('dbForProject')
->inject('events')
->inject('audits')
->inject('usage')
->inject('mode')
->action(function ($collectionId, $documentId, $response, $dbForInternal, $dbForExternal, $events, $audits, $usage, $mode) {
->action(function ($collectionId, $documentId, $response, $dbForProject, $events, $audits, $usage, $mode) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
@ -2117,7 +2077,7 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId')
/**
* Skip Authorization to get the collection. Needed in case of empty permissions for document level permissions.
*/
$collection = Authorization::skip(fn() => $dbForInternal->getDocument('collections', $collectionId));
$collection = Authorization::skip(fn() => $dbForProject->getDocument('collections', $collectionId));
if ($collection->isEmpty() || !$collection->getAttribute('enabled')) {
if (!($mode === APP_MODE_ADMIN && Auth::isPrivilegedUser(Authorization::getRoles()))) {
@ -2135,9 +2095,9 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId')
if ($collection->getAttribute('permission') === 'collection') {
/** @var Document $document */
$document = Authorization::skip(fn() => $dbForExternal->getDocument('collection_' . $collectionId, $documentId));
$document = Authorization::skip(fn() => $dbForProject->getDocument('collection_' . $collectionId, $documentId));
} else {
$document = $dbForExternal->getDocument('collection_' . $collectionId, $documentId);
$document = $dbForProject->getDocument('collection_' . $collectionId, $documentId);
}
if ($document->isEmpty()) {
@ -2145,12 +2105,12 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId')
}
if ($collection->getAttribute('permission') === 'collection') {
Authorization::skip(fn() => $dbForExternal->deleteDocument('collection_' . $collectionId, $documentId));
Authorization::skip(fn() => $dbForProject->deleteDocument('collection_' . $collectionId, $documentId));
} else {
$dbForExternal->deleteDocument('collection_' . $collectionId, $documentId);
$dbForProject->deleteDocument('collection_' . $collectionId, $documentId);
}
$dbForExternal->deleteCachedDocument('collection_' . $collectionId, $documentId);
$dbForProject->deleteCachedDocument('collection_' . $collectionId, $documentId);
/**
* Reset $collection attribute to remove prefix.

View file

@ -48,13 +48,13 @@ App::post('/v1/functions')
->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true)
->param('timeout', 15, new Range(1, 900), 'Function maximum execution time in seconds.', true)
->inject('response')
->inject('dbForInternal')
->action(function ($functionId, $name, $execute, $runtime, $vars, $events, $schedule, $timeout, $response, $dbForInternal) {
->inject('dbForProject')
->action(function ($functionId, $name, $execute, $runtime, $vars, $events, $schedule, $timeout, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
$functionId = ($functionId == 'unique()') ? $dbForInternal->getId() : $functionId;
$function = $dbForInternal->createDocument('functions', new Document([
$functionId = ($functionId == 'unique()') ? $dbForProject->getId() : $functionId;
$function = $dbForProject->createDocument('functions', new Document([
'$id' => $functionId,
'execute' => $execute,
'dateCreated' => time(),
@ -94,13 +94,13 @@ App::get('/v1/functions')
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
->inject('response')
->inject('dbForInternal')
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal) {
->inject('dbForProject')
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
if (!empty($cursor)) {
$cursorFunction = $dbForInternal->getDocument('functions', $cursor);
$cursorFunction = $dbForProject->getDocument('functions', $cursor);
if ($cursorFunction->isEmpty()) {
throw new Exception("Function '{$cursor}' for the 'cursor' value not found.", 400);
@ -114,8 +114,8 @@ App::get('/v1/functions')
}
$response->dynamic(new Document([
'functions' => $dbForInternal->find('functions', $queries, $limit, $offset, [], [$orderType], $cursorFunction ?? null, $cursorDirection),
'sum' => $dbForInternal->count('functions', $queries, APP_LIMIT_COUNT),
'functions' => $dbForProject->find('functions', $queries, $limit, $offset, [], [$orderType], $cursorFunction ?? null, $cursorDirection),
'sum' => $dbForProject->count('functions', $queries, APP_LIMIT_COUNT),
]), Response::MODEL_FUNCTION_LIST);
});
@ -160,12 +160,12 @@ App::get('/v1/functions/:functionId')
->label('sdk.response.model', Response::MODEL_FUNCTION)
->param('functionId', '', new UID(), 'Function ID.')
->inject('response')
->inject('dbForInternal')
->action(function ($functionId, $response, $dbForInternal) {
->inject('dbForProject')
->action(function ($functionId, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
$function = $dbForInternal->getDocument('functions', $functionId);
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404);
@ -187,16 +187,14 @@ App::get('/v1/functions/:functionId/usage')
->param('functionId', '', new UID(), 'Function ID.')
->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d']), 'Date range.', true)
->inject('response')
->inject('project')
->inject('dbForInternal')
->inject('register')
->action(function ($functionId, $range, $response, $project, $dbForInternal, $register) {
->inject('dbForProject')
->action(function ($functionId, $range, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Registry\Registry $register */
$function = $dbForInternal->getDocument('functions', $functionId);
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404);
@ -231,12 +229,12 @@ App::get('/v1/functions/:functionId/usage')
$stats = [];
Authorization::skip(function() use ($dbForInternal, $periods, $range, $metrics, &$stats) {
Authorization::skip(function() use ($dbForProject, $periods, $range, $metrics, &$stats) {
foreach ($metrics as $metric) {
$limit = $periods[$range]['limit'];
$period = $periods[$range]['period'];
$requestDocs = $dbForInternal->find('stats', [
$requestDocs = $dbForProject->find('stats', [
new Query('period', Query::TYPE_EQUAL, [$period]),
new Query('metric', Query::TYPE_EQUAL, [$metric]),
], $limit, 0, ['time'], [Database::ORDER_DESC]);
@ -298,14 +296,14 @@ App::put('/v1/functions/:functionId')
->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true)
->param('timeout', 15, new Range(1, 900), 'Maximum execution time in seconds.', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('project')
->action(function ($functionId, $name, $execute, $vars, $events, $schedule, $timeout, $response, $dbForInternal, $project) {
->action(function ($functionId, $name, $execute, $vars, $events, $schedule, $timeout, $response, $dbForProject, $project) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Database\Document $project */
$function = $dbForInternal->getDocument('functions', $functionId);
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404);
@ -315,7 +313,7 @@ App::put('/v1/functions/:functionId')
$cron = (!empty($function->getAttribute('tag', null)) && !empty($schedule)) ? new CronExpression($schedule) : null;
$next = (!empty($function->getAttribute('tag', null)) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : 0;
$function = $dbForInternal->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
$function = $dbForProject->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
'execute' => $execute,
'dateUpdated' => time(),
'name' => $name,
@ -355,15 +353,15 @@ App::patch('/v1/functions/:functionId/tag')
->param('functionId', '', new UID(), 'Function ID.')
->param('tag', '', new UID(), 'Tag ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('project')
->action(function ($functionId, $tag, $response, $dbForInternal, $project) {
->action(function ($functionId, $tag, $response, $dbForProject, $project) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Database\Document $project */
$function = $dbForInternal->getDocument('functions', $functionId);
$tag = $dbForInternal->getDocument('tags', $tag);
$function = $dbForProject->getDocument('functions', $functionId);
$tag = $dbForProject->getDocument('tags', $tag);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404);
@ -377,7 +375,7 @@ App::patch('/v1/functions/:functionId/tag')
$cron = (empty($function->getAttribute('tag')) && !empty($schedule)) ? new CronExpression($schedule) : null;
$next = (empty($function->getAttribute('tag')) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : 0;
$function = $dbForInternal->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
$function = $dbForProject->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
'tag' => $tag->getId(),
'scheduleNext' => (int)$next,
])));
@ -408,20 +406,20 @@ App::delete('/v1/functions/:functionId')
->label('sdk.response.model', Response::MODEL_NONE)
->param('functionId', '', new UID(), 'Function ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('deletes')
->action(function ($functionId, $response, $dbForInternal, $deletes) {
->action(function ($functionId, $response, $dbForProject, $deletes) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $deletes */
$function = $dbForInternal->getDocument('functions', $functionId);
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404);
}
if (!$dbForInternal->deleteDocument('functions', $function->getId())) {
if (!$dbForProject->deleteDocument('functions', $function->getId())) {
throw new Exception('Failed to remove function from DB', 500);
}
@ -452,15 +450,15 @@ App::post('/v1/functions/:functionId/tags')
->param('code', [], new File(), 'Gzip file with your code package. When used with the Appwrite CLI, pass the path to your code directory, and the CLI will automatically package your code. Use a path that is within the current directory.', false)
->inject('request')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($functionId, $command, $file, $request, $response, $dbForInternal, $usage) {
->action(function ($functionId, $command, $file, $request, $response, $dbForProject, $usage) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $usage */
$function = $dbForInternal->getDocument('functions', $functionId);
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404);
@ -501,8 +499,8 @@ App::post('/v1/functions/:functionId/tags')
throw new Exception('Failed moving file', 500);
}
$tagId = $dbForInternal->getId();
$tag = $dbForInternal->createDocument('tags', new Document([
$tagId = $dbForProject->getId();
$tag = $dbForProject->createDocument('tags', new Document([
'$id' => $tagId,
'$read' => [],
'$write' => [],
@ -541,19 +539,19 @@ App::get('/v1/functions/:functionId/tags')
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
->inject('response')
->inject('dbForInternal')
->action(function ($functionId, $search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal) {
->inject('dbForProject')
->action(function ($functionId, $search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
$function = $dbForInternal->getDocument('functions', $functionId);
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404);
}
if (!empty($cursor)) {
$cursorTag = $dbForInternal->getDocument('tags', $cursor);
$cursorTag = $dbForProject->getDocument('tags', $cursor);
if ($cursorTag->isEmpty()) {
throw new Exception("Tag '{$cursor}' for the 'cursor' value not found.", 400);
@ -568,8 +566,8 @@ App::get('/v1/functions/:functionId/tags')
$queries[] = new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]);
$results = $dbForInternal->find('tags', $queries, $limit, $offset, [], [$orderType], $cursorTag ?? null, $cursorDirection);
$sum = $dbForInternal->count('tags', $queries, APP_LIMIT_COUNT);
$results = $dbForProject->find('tags', $queries, $limit, $offset, [], [$orderType], $cursorTag ?? null, $cursorDirection);
$sum = $dbForProject->count('tags', $queries, APP_LIMIT_COUNT);
$response->dynamic(new Document([
'tags' => $results,
@ -591,18 +589,18 @@ App::get('/v1/functions/:functionId/tags/:tagId')
->param('functionId', '', new UID(), 'Function ID.')
->param('tagId', '', new UID(), 'Tag ID.')
->inject('response')
->inject('dbForInternal')
->action(function ($functionId, $tagId, $response, $dbForInternal) {
->inject('dbForProject')
->action(function ($functionId, $tagId, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
$function = $dbForInternal->getDocument('functions', $functionId);
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404);
}
$tag = $dbForInternal->getDocument('tags', $tagId);
$tag = $dbForProject->getDocument('tags', $tagId);
if ($tag->getAttribute('functionId') !== $function->getId()) {
throw new Exception('Tag not found', 404);
@ -629,20 +627,20 @@ App::delete('/v1/functions/:functionId/tags/:tagId')
->param('functionId', '', new UID(), 'Function ID.')
->param('tagId', '', new UID(), 'Tag ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($functionId, $tagId, $response, $dbForInternal, $usage) {
->action(function ($functionId, $tagId, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $usage */
$function = $dbForInternal->getDocument('functions', $functionId);
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404);
}
$tag = $dbForInternal->getDocument('tags', $tagId);
$tag = $dbForProject->getDocument('tags', $tagId);
if ($tag->getAttribute('functionId') !== $function->getId()) {
throw new Exception('Tag not found', 404);
@ -655,13 +653,13 @@ App::delete('/v1/functions/:functionId/tags/:tagId')
$device = Storage::getDevice('functions');
if ($device->delete($tag->getAttribute('path', ''))) {
if (!$dbForInternal->deleteDocument('tags', $tag->getId())) {
if (!$dbForProject->deleteDocument('tags', $tag->getId())) {
throw new Exception('Failed to remove tag from DB', 500);
}
}
if($function->getAttribute('tag') === $tag->getId()) { // Reset function tag
$function = $dbForInternal->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
$function = $dbForProject->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
'tag' => '',
])));
}
@ -692,21 +690,21 @@ App::post('/v1/functions/:functionId/executions')
// ->param('async', 1, new Range(0, 1), 'Execute code asynchronously. Pass 1 for true, 0 for false. Default value is 1.', true)
->inject('response')
->inject('project')
->inject('dbForInternal')
->inject('dbForProject')
->inject('user')
->action(function ($functionId, $data, /*$async,*/ $response, $project, $dbForInternal, $user) {
->action(function ($functionId, $data, /*$async,*/ $response, $project, $dbForProject, $user) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Database\Document $user */
$function = Authorization::skip(fn() => $dbForInternal->getDocument('functions', $functionId));
$function = Authorization::skip(fn() => $dbForProject->getDocument('functions', $functionId));
if ($function->isEmpty()) {
throw new Exception('Function not found', 404);
}
$tag = Authorization::skip(fn() => $dbForInternal->getDocument('tags', $function->getAttribute('tag')));
$tag = Authorization::skip(fn() => $dbForProject->getDocument('tags', $function->getAttribute('tag')));
if ($tag->getAttribute('functionId') !== $function->getId()) {
throw new Exception('Tag not found. Deploy tag before trying to execute a function', 404);
@ -722,9 +720,9 @@ App::post('/v1/functions/:functionId/executions')
throw new Exception($validator->getDescription(), 401);
}
$executionId = $dbForInternal->getId();
$executionId = $dbForProject->getId();
$execution = Authorization::skip(fn() => $dbForInternal->createDocument('executions', new Document([
$execution = Authorization::skip(fn() => $dbForProject->createDocument('executions', new Document([
'$id' => $executionId,
'$read' => (!$user->isEmpty()) ? ['user:' . $user->getId()] : [],
'$write' => [],
@ -794,19 +792,19 @@ App::get('/v1/functions/:functionId/executions')
->param('cursor', '', new UID(), 'ID of the execution used as the starting point for the query, excluding the execution itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
->inject('response')
->inject('dbForInternal')
->action(function ($functionId, $limit, $offset, $search, $cursor, $cursorDirection, $response, $dbForInternal) {
->inject('dbForProject')
->action(function ($functionId, $limit, $offset, $search, $cursor, $cursorDirection, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
$function = Authorization::skip(fn() => $dbForInternal->getDocument('functions', $functionId));
$function = Authorization::skip(fn() => $dbForProject->getDocument('functions', $functionId));
if ($function->isEmpty()) {
throw new Exception('Function not found', 404);
}
if (!empty($cursor)) {
$cursorExecution = $dbForInternal->getDocument('executions', $cursor);
$cursorExecution = $dbForProject->getDocument('executions', $cursor);
if ($cursorExecution->isEmpty()) {
throw new Exception("Execution '{$cursor}' for the 'cursor' value not found.", 400);
@ -821,8 +819,8 @@ App::get('/v1/functions/:functionId/executions')
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
}
$results = $dbForInternal->find('executions', $queries, $limit, $offset, [], [Database::ORDER_DESC], $cursorExecution ?? null, $cursorDirection);
$sum = $dbForInternal->count('executions', $queries, APP_LIMIT_COUNT);
$results = $dbForProject->find('executions', $queries, $limit, $offset, [], [Database::ORDER_DESC], $cursorExecution ?? null, $cursorDirection);
$sum = $dbForProject->count('executions', $queries, APP_LIMIT_COUNT);
$response->dynamic(new Document([
'executions' => $results,
@ -844,18 +842,18 @@ App::get('/v1/functions/:functionId/executions/:executionId')
->param('functionId', '', new UID(), 'Function ID.')
->param('executionId', '', new UID(), 'Execution ID.')
->inject('response')
->inject('dbForInternal')
->action(function ($functionId, $executionId, $response, $dbForInternal) {
->inject('dbForProject')
->action(function ($functionId, $executionId, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
$function = Authorization::skip(fn() => $dbForInternal->getDocument('functions', $functionId));
$function = Authorization::skip(fn() => $dbForProject->getDocument('functions', $functionId));
if ($function->isEmpty()) {
throw new Exception('Function not found', 404);
}
$execution = $dbForInternal->getDocument('executions', $executionId);
$execution = $dbForProject->getDocument('executions', $executionId);
if ($execution->getAttribute('functionId') !== $function->getId()) {
throw new Exception('Execution not found', 404);

View file

@ -224,9 +224,7 @@ App::get('/v1/locale/currencies')
$list = Config::getParam('locale-currencies');
$list = array_map(function($node) {
return new Document($node);
}, $list);
$list = array_map(fn($node) => new Document($node), $list);
$response->dynamic(new Document(['currencies' => $list, 'sum' => \count($list)]), Response::MODEL_CURRENCY_LIST);
});
@ -249,9 +247,7 @@ App::get('/v1/locale/languages')
$list = Config::getParam('locale-languages');
$list = array_map(function($node) {
return new Document($node);
}, $list);
$list = array_map(fn ($node) => new Document($node), $list);
$response->dynamic(new Document(['languages' => $list, 'sum' => \count($list)]), Response::MODEL_LANGUAGE_LIST);
});

View file

@ -57,13 +57,11 @@ App::post('/v1/projects')
->param('legalTaxId', '', new Text(256), 'Project legal Tax ID. Max length: 256 chars.', true)
->inject('response')
->inject('dbForConsole')
->inject('dbForInternal')
->inject('dbForExternal')
->action(function ($projectId, $name, $teamId, $description, $logo, $url, $legalName, $legalCountry, $legalState, $legalCity, $legalAddress, $legalTaxId, $response, $dbForConsole, $dbForInternal, $dbForExternal) {
->inject('dbForProject')
->action(function ($projectId, $name, $teamId, $description, $logo, $url, $legalName, $legalCountry, $legalState, $legalCity, $legalAddress, $legalTaxId, $response, $dbForConsole, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForConsole */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Utopia\Database\Database $dbForProject */
$team = $dbForConsole->getDocument('teams', $teamId);
@ -106,14 +104,13 @@ App::post('/v1/projects')
$collections = Config::getParam('collections', []); /** @var array $collections */
$dbForInternal->setNamespace('_project_' . $project->getId());
$dbForExternal->setNamespace('_project_' . $project->getId());
$dbForExternal->create('appwrite');
$dbForProject->setNamespace('_project_' . $project->getId());
$dbForProject->create('appwrite');
$audit = new Audit($dbForInternal);
$audit = new Audit($dbForProject);
$audit->setup();
$adapter = new TimeLimit('', 0, 1, $dbForInternal);
$adapter = new TimeLimit('', 0, 1, $dbForProject);
$adapter->setup();
foreach ($collections as $key => $collection) {
@ -142,7 +139,7 @@ App::post('/v1/projects')
]);
}
$dbForInternal->createCollection($key, $attributes, $indexes);
$dbForProject->createCollection($key, $attributes, $indexes);
}
$response->setStatusCode(Response::STATUS_CODE_CREATED);
@ -234,12 +231,12 @@ App::get('/v1/projects/:projectId/usage')
->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true)
->inject('response')
->inject('dbForConsole')
->inject('dbForInternal')
->inject('dbForProject')
->inject('register')
->action(function ($projectId, $range, $response, $dbForConsole, $dbForInternal, $register) {
->action(function ($projectId, $range, $response, $dbForConsole, $dbForProject, $register) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForConsole */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Registry\Registry $register */
$project = $dbForConsole->getDocument('projects', $projectId);
@ -269,11 +266,11 @@ App::get('/v1/projects/:projectId/usage')
],
];
$dbForInternal->setNamespace('project_' . $projectId . '_internal');
$dbForProject->setNamespace('_project_' . $projectId);
$metrics = [
'requests',
'network',
'requests',
'network',
'executions',
'users.count',
'database.documents.count',
@ -283,12 +280,12 @@ App::get('/v1/projects/:projectId/usage')
$stats = [];
Authorization::skip(function() use ($dbForInternal, $periods, $range, $metrics, &$stats) {
Authorization::skip(function() use ($dbForProject, $periods, $range, $metrics, &$stats) {
foreach ($metrics as $metric) {
$limit = $periods[$range]['limit'];
$period = $periods[$range]['period'];
$requestDocs = $dbForInternal->find('stats', [
$requestDocs = $dbForProject->find('stats', [
new Query('period', Query::TYPE_EQUAL, [$period]),
new Query('metric', Query::TYPE_EQUAL, [$metric]),
], $limit, 0, ['time'], [Database::ORDER_DESC]);

View file

@ -47,14 +47,14 @@ App::post('/v1/storage/files')
->param('write', null, new ArrayList(new Text(64)), 'An array of strings with write permissions. By default only the current user is granted with write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true)
->inject('request')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('user')
->inject('audits')
->inject('usage')
->action(function ($fileId, $file, $read, $write, $request, $response, $dbForInternal, $user, $audits, $usage) {
->action(function ($fileId, $file, $read, $write, $request, $response, $dbForProject, $user, $audits, $usage) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Database\Document $user */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
@ -146,8 +146,8 @@ App::post('/v1/storage/files')
$sizeActual = $device->getFileSize($path);
$fileId = ($fileId == 'unique()') ? $dbForInternal->getId() : $fileId;
$file = $dbForInternal->createDocument('files', new Document([
$fileId = ($fileId == 'unique()') ? $dbForProject->getId() : $fileId;
$file = $dbForProject->createDocument('files', new Document([
'$id' => $fileId,
'$read' => (is_null($read) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $read ?? [], // By default set read permissions for user
'$write' => (is_null($write) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $write ?? [], // By default set write permissions for user
@ -202,15 +202,15 @@ App::get('/v1/storage/files')
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal, $usage) {
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Stats\Stats $usage */
if (!empty($cursor)) {
$cursorFile = $dbForInternal->getDocument('files', $cursor);
$cursorFile = $dbForProject->getDocument('files', $cursor);
if ($cursorFile->isEmpty()) {
throw new Exception("File '{$cursor}' for the 'cursor' value not found.", 400);
@ -229,8 +229,8 @@ App::get('/v1/storage/files')
;
$response->dynamic(new Document([
'files' => $dbForInternal->find('files', $queries, $limit, $offset, [], [$orderType], $cursorFile ?? null, $cursorDirection),
'sum' => $dbForInternal->count('files', $queries, APP_LIMIT_COUNT),
'files' => $dbForProject->find('files', $queries, $limit, $offset, [], [$orderType], $cursorFile ?? null, $cursorDirection),
'sum' => $dbForProject->count('files', $queries, APP_LIMIT_COUNT),
]), Response::MODEL_FILE_LIST);
});
@ -247,14 +247,14 @@ App::get('/v1/storage/files/:fileId')
->label('sdk.response.model', Response::MODEL_FILE)
->param('fileId', '', new UID(), 'File ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($fileId, $response, $dbForInternal, $usage) {
->action(function ($fileId, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Stats\Stats $usage */
$file = $dbForInternal->getDocument('files', $fileId);
$file = $dbForProject->getDocument('files', $fileId);
if (empty($file->getId())) {
throw new Exception('File not found', 404);
@ -292,13 +292,13 @@ App::get('/v1/storage/files/:fileId/preview')
->inject('request')
->inject('response')
->inject('project')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($fileId, $width, $height, $gravity, $quality, $borderWidth, $borderColor, $borderRadius, $opacity, $rotation, $background, $output, $request, $response, $project, $dbForInternal, $usage) {
->action(function ($fileId, $width, $height, $gravity, $quality, $borderWidth, $borderColor, $borderRadius, $opacity, $rotation, $background, $output, $request, $response, $project, $dbForProject, $usage) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Stats\Stats $stats */
$storage = 'files';
@ -322,7 +322,7 @@ App::get('/v1/storage/files/:fileId/preview')
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache
$key = \md5($fileId.$width.$height.$gravity.$quality.$borderWidth.$borderColor.$borderRadius.$opacity.$rotation.$background.$storage.$output);
$file = $dbForInternal->getDocument('files', $fileId);
$file = $dbForProject->getDocument('files', $fileId);
if (empty($file->getId())) {
throw new Exception('File not found', 404);
@ -440,14 +440,14 @@ App::get('/v1/storage/files/:fileId/download')
->label('sdk.methodType', 'location')
->param('fileId', '', new UID(), 'File ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($fileId, $response, $dbForInternal, $usage) {
->action(function ($fileId, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Stats\Stats $usage */
$file = $dbForInternal->getDocument('files', $fileId);
$file = $dbForProject->getDocument('files', $fileId);
if (empty($file->getId())) {
throw new Exception('File not found', 404);
@ -505,14 +505,14 @@ App::get('/v1/storage/files/:fileId/view')
->label('sdk.methodType', 'location')
->param('fileId', '', new UID(), 'File ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($fileId, $response, $dbForInternal, $usage) {
->action(function ($fileId, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Stats\Stats $usage */
$file = $dbForInternal->getDocument('files', $fileId);
$file = $dbForProject->getDocument('files', $fileId);
$mimes = Config::getParam('storage-mimes');
if (empty($file->getId())) {
@ -583,13 +583,13 @@ App::put('/v1/storage/files/:fileId')
->param('read', [], new ArrayList(new Text(64)), 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.')
->param('write', [], new ArrayList(new Text(64)), 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('user')
->inject('audits')
->inject('usage')
->action(function ($fileId, $read, $write, $response, $dbForInternal, $user, $audits, $usage) {
->action(function ($fileId, $read, $write, $response, $dbForProject, $user, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Database\Document $user */
/** @var Appwrite\Event\Event $audits */
@ -612,13 +612,13 @@ App::put('/v1/storage/files/:fileId')
}
}
$file = $dbForInternal->getDocument('files', $fileId);
$file = $dbForProject->getDocument('files', $fileId);
if (empty($file->getId())) {
throw new Exception('File not found', 404);
}
$file = $dbForInternal->updateDocument('files', $fileId, new Document(\array_merge($file->getArrayCopy(), [
$file = $dbForProject->updateDocument('files', $fileId, new Document(\array_merge($file->getArrayCopy(), [
'$read' => $read,
'$write' => $write,
'bucketId' => '',
@ -650,18 +650,18 @@ App::delete('/v1/storage/files/:fileId')
->label('sdk.response.model', Response::MODEL_NONE)
->param('fileId', '', new UID(), 'File ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('events')
->inject('audits')
->inject('usage')
->action(function ($fileId, $response, $dbForInternal, $events, $audits, $usage) {
->action(function ($fileId, $response, $dbForProject, $events, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
$file = $dbForInternal->getDocument('files', $fileId);
$file = $dbForProject->getDocument('files', $fileId);
if (empty($file->getId())) {
throw new Exception('File not found', 404);
@ -670,7 +670,7 @@ App::delete('/v1/storage/files/:fileId')
$device = Storage::getDevice('files');
if ($device->delete($file->getAttribute('path', ''))) {
if (!$dbForInternal->deleteDocument('files', $fileId)) {
if (!$dbForProject->deleteDocument('files', $fileId)) {
throw new Exception('Failed to remove file from DB', 500);
}
}
@ -705,10 +705,10 @@ App::get('/v1/storage/usage')
->label('sdk.response.model', Response::MODEL_USAGE_STORAGE)
->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true)
->inject('response')
->inject('dbForInternal')
->action(function ($range, $response, $dbForInternal) {
->inject('dbForProject')
->action(function ($range, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
$usage = [];
if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') {
@ -738,12 +738,12 @@ App::get('/v1/storage/usage')
$stats = [];
Authorization::skip(function() use ($dbForInternal, $periods, $range, $metrics, &$stats) {
Authorization::skip(function() use ($dbForProject, $periods, $range, $metrics, &$stats) {
foreach ($metrics as $metric) {
$limit = $periods[$range]['limit'];
$period = $periods[$range]['period'];
$requestDocs = $dbForInternal->find('stats', [
$requestDocs = $dbForProject->find('stats', [
new Query('period', Query::TYPE_EQUAL, [$period]),
new Query('metric', Query::TYPE_EQUAL, [$metric]),
], $limit, 0, ['time'], [Database::ORDER_DESC]);
@ -797,10 +797,10 @@ App::get('/v1/storage/:bucketId/usage')
->param('bucketId', '', new UID(), 'Bucket ID.')
->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true)
->inject('response')
->inject('dbForInternal')
->action(function ($bucketId, $range, $response, $dbForInternal) {
->inject('dbForProject')
->action(function ($bucketId, $range, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
// TODO: Check if the storage bucket exists else throw 404
@ -835,12 +835,12 @@ App::get('/v1/storage/:bucketId/usage')
$stats = [];
Authorization::skip(function() use ($dbForInternal, $periods, $range, $metrics, &$stats) {
Authorization::skip(function() use ($dbForProject, $periods, $range, $metrics, &$stats) {
foreach ($metrics as $metric) {
$limit = $periods[$range]['limit'];
$period = $periods[$range]['period'];
$requestDocs = $dbForInternal->find('stats', [
$requestDocs = $dbForProject->find('stats', [
new Query('period', Query::TYPE_EQUAL, [$period]),
new Query('metric', Query::TYPE_EQUAL, [$metric]),
], $limit, 0, ['time'], [Database::ORDER_DESC]);

View file

@ -39,19 +39,19 @@ App::post('/v1/teams')
->param('roles', ['owner'], new ArrayList(new Key()), 'Array of strings. Use this param to set the roles in the team for the user who created it. The default role is **owner**. A role can be any string. Learn more about [roles and permissions](/docs/permissions). Max length for each role is 32 chars.', true)
->inject('response')
->inject('user')
->inject('dbForInternal')
->inject('dbForProject')
->inject('events')
->action(function ($teamId, $name, $roles, $response, $user, $dbForInternal, $events) {
->action(function ($teamId, $name, $roles, $response, $user, $dbForProject, $events) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $events */
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
$isAppUser = Auth::isAppUser(Authorization::getRoles());
$teamId = $teamId == 'unique()' ? $dbForInternal->getId() : $teamId;
$team = Authorization::skip(fn() => $dbForInternal->createDocument('teams', new Document([
$teamId = $teamId == 'unique()' ? $dbForProject->getId() : $teamId;
$team = Authorization::skip(fn() => $dbForProject->createDocument('teams', new Document([
'$id' => $teamId ,
'$read' => ['team:'.$teamId],
'$write' => ['team:'.$teamId .'/owner'],
@ -74,11 +74,11 @@ App::post('/v1/teams')
'secret' => '',
]);
$membership = $dbForInternal->createDocument('memberships', $membership);
$membership = $dbForProject->createDocument('memberships', $membership);
// Attach user to team
$user->setAttribute('memberships', $membership, Document::SET_TYPE_APPEND);
$user = $dbForInternal->updateDocument('users', $user->getId(), $user);
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
}
if (!empty($user->getId())) {
@ -107,13 +107,13 @@ App::get('/v1/teams')
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
->inject('response')
->inject('dbForInternal')
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal) {
->inject('dbForProject')
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
if (!empty($cursor)) {
$cursorTeam = $dbForInternal->getDocument('teams', $cursor);
$cursorTeam = $dbForProject->getDocument('teams', $cursor);
if ($cursorTeam->isEmpty()) {
throw new Exception("Team '{$cursor}' for the 'cursor' value not found.", 400);
@ -126,8 +126,8 @@ App::get('/v1/teams')
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
}
$results = $dbForInternal->find('teams', $queries, $limit, $offset, [], [$orderType], $cursorTeam ?? null, $cursorDirection);
$sum = $dbForInternal->count('teams', $queries, APP_LIMIT_COUNT);
$results = $dbForProject->find('teams', $queries, $limit, $offset, [], [$orderType], $cursorTeam ?? null, $cursorDirection);
$sum = $dbForProject->count('teams', $queries, APP_LIMIT_COUNT);
$response->dynamic(new Document([
'teams' => $results,
@ -148,12 +148,12 @@ App::get('/v1/teams/:teamId')
->label('sdk.response.model', Response::MODEL_TEAM)
->param('teamId', '', new UID(), 'Team ID.')
->inject('response')
->inject('dbForInternal')
->action(function ($teamId, $response, $dbForInternal) {
->inject('dbForProject')
->action(function ($teamId, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
$team = $dbForInternal->getDocument('teams', $teamId);
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404);
@ -177,18 +177,18 @@ App::put('/v1/teams/:teamId')
->param('teamId', '', new UID(), 'Team ID.')
->param('name', null, new Text(128), 'New team name. Max length: 128 chars.')
->inject('response')
->inject('dbForInternal')
->action(function ($teamId, $name, $response, $dbForInternal) {
->inject('dbForProject')
->action(function ($teamId, $name, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
$team = $dbForInternal->getDocument('teams', $teamId);
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404);
}
$team = $dbForInternal->updateDocument('teams', $team->getId(),$team
$team = $dbForProject->updateDocument('teams', $team->getId(),$team
->setAttribute('name', $name)
->setAttribute('search', implode(' ', [$teamId, $name]))
);
@ -209,33 +209,33 @@ App::delete('/v1/teams/:teamId')
->label('sdk.response.model', Response::MODEL_NONE)
->param('teamId', '', new UID(), 'Team ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('events')
->inject('deletes')
->action(function ($teamId, $response, $dbForInternal, $events, $deletes) {
->action(function ($teamId, $response, $dbForProject, $events, $deletes) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Event\Event $deletes */
$team = $dbForInternal->getDocument('teams', $teamId);
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404);
}
$memberships = $dbForInternal->find('memberships', [
$memberships = $dbForProject->find('memberships', [
new Query('teamId', Query::TYPE_EQUAL, [$teamId]),
], 2000, 0); // TODO fix members limit
// TODO delete all members individually from the user object
foreach ($memberships as $membership) {
if (!$dbForInternal->deleteDocument('memberships', $membership->getId())) {
if (!$dbForProject->deleteDocument('memberships', $membership->getId())) {
throw new Exception('Failed to remove membership for team from DB', 500);
}
}
if (!$dbForInternal->deleteDocument('teams', $teamId)) {
if (!$dbForProject->deleteDocument('teams', $teamId)) {
throw new Exception('Failed to remove team from DB', 500);
}
@ -273,15 +273,15 @@ App::post('/v1/teams/:teamId/memberships')
->inject('response')
->inject('project')
->inject('user')
->inject('dbForInternal')
->inject('dbForProject')
->inject('locale')
->inject('audits')
->inject('mails')
->action(function ($teamId, $email, $roles, $url, $name, $response, $project, $user, $dbForInternal, $locale, $audits, $mails) {
->action(function ($teamId, $email, $roles, $url, $name, $response, $project, $user, $dbForProject, $locale, $audits, $mails) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $mails */
@ -294,20 +294,20 @@ App::post('/v1/teams/:teamId/memberships')
$email = \strtolower($email);
$name = (empty($name)) ? $email : $name;
$team = $dbForInternal->getDocument('teams', $teamId);
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404);
}
$invitee = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
$invitee = $dbForProject->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
if (empty($invitee)) { // Create new user if no user with same email found
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
if ($limit !== 0 && $project->getId() !== 'console') { // check users limit, console invites are allways allowed.
$sum = $dbForInternal->count('users', [], APP_LIMIT_USERS);
$sum = $dbForProject->count('users', [], APP_LIMIT_USERS);
if($sum >= $limit) {
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501);
@ -315,8 +315,8 @@ App::post('/v1/teams/:teamId/memberships')
}
try {
$userId = $dbForInternal->getId();
$invitee = Authorization::skip(fn() => $dbForInternal->createDocument('users', new Document([
$userId = $dbForProject->getId();
$invitee = Authorization::skip(fn() => $dbForProject->createDocument('users', new Document([
'$id' => $userId,
'$read' => ['user:'.$userId, 'role:all'],
'$write' => ['user:'.$userId],
@ -353,7 +353,7 @@ App::post('/v1/teams/:teamId/memberships')
$secret = Auth::tokenGenerator();
$membership = new Document([
'$id' => $dbForInternal->getId(),
'$id' => $dbForProject->getId(),
'$read' => ['role:all'],
'$write' => ['user:'.$invitee->getId(), 'team:'.$team->getId().'/owner'],
'userId' => $invitee->getId(),
@ -367,20 +367,20 @@ App::post('/v1/teams/:teamId/memberships')
if ($isPrivilegedUser || $isAppUser) { // Allow admin to create membership
try {
$membership = Authorization::skip(fn() => $dbForInternal->createDocument('memberships', $membership));
$membership = Authorization::skip(fn() => $dbForProject->createDocument('memberships', $membership));
} catch (Duplicate $th) {
throw new Exception('User has already been invited or is already a member of this team', 409);
}
$team->setAttribute('sum', $team->getAttribute('sum', 0) + 1);
$team = Authorization::skip(fn() => $dbForInternal->updateDocument('teams', $team->getId(), $team));
$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() => $dbForInternal->updateDocument('users', $invitee->getId(), $invitee));
$invitee = Authorization::skip(fn() => $dbForProject->updateDocument('users', $invitee->getId(), $invitee));
} else {
try {
$membership = $dbForInternal->createDocument('memberships', $membership);
$membership = $dbForProject->createDocument('memberships', $membership);
} catch (Duplicate $th) {
throw new Exception('User has already been invited or is already a member of this team', 409);
}
@ -438,32 +438,32 @@ App::get('/v1/teams/:teamId/memberships')
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
->inject('response')
->inject('dbForInternal')
->action(function ($teamId, $search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal) {
->inject('dbForProject')
->action(function ($teamId, $search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
$team = $dbForInternal->getDocument('teams', $teamId);
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404);
}
if (!empty($cursor)) {
$cursorMembership = $dbForInternal->getDocument('memberships', $cursor);
$cursorMembership = $dbForProject->getDocument('memberships', $cursor);
if ($cursorMembership->isEmpty()) {
throw new Exception("Membership '{$cursor}' for the 'cursor' value not found.", 400);
}
}
$memberships = $dbForInternal->find('memberships', [new Query('teamId', Query::TYPE_EQUAL, [$teamId])], $limit, $offset, [], [$orderType], $cursorMembership ?? null, $cursorDirection);
$sum = $dbForInternal->count('memberships', [new Query('teamId', Query::TYPE_EQUAL, [$teamId])], APP_LIMIT_COUNT);
$memberships = $dbForProject->find('memberships', [new Query('teamId', Query::TYPE_EQUAL, [$teamId])], $limit, $offset, [], [$orderType], $cursorMembership ?? null, $cursorDirection);
$sum = $dbForProject->count('memberships', [new Query('teamId', Query::TYPE_EQUAL, [$teamId])], APP_LIMIT_COUNT);
$memberships = array_filter($memberships, fn(Document $membership) => !empty($membership->getAttribute('userId')));
$memberships = array_map(function($membership) use ($dbForInternal) {
$user = $dbForInternal->getDocument('users', $membership->getAttribute('userId'));
$memberships = array_map(function($membership) use ($dbForProject) {
$user = $dbForProject->getDocument('users', $membership->getAttribute('userId'));
$membership
->setAttribute('name', $user->getAttribute('name'))
@ -493,24 +493,24 @@ App::get('/v1/teams/:teamId/memberships/:membershipId')
->param('teamId', '', new UID(), 'Team ID.')
->param('membershipId', '', new UID(), 'Membership ID.')
->inject('response')
->inject('dbForInternal')
->action(function ($teamId, $membershipId, $response, $dbForInternal) {
->inject('dbForProject')
->action(function ($teamId, $membershipId, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
$team = $dbForInternal->getDocument('teams', $teamId);
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404);
}
$membership = $dbForInternal->getDocument('memberships', $membershipId);
$membership = $dbForProject->getDocument('memberships', $membershipId);
if($membership->isEmpty() || empty($membership->getAttribute('userId'))) {
throw new Exception('Membership not found', 404);
}
$user = $dbForInternal->getDocument('users', $membership->getAttribute('userId'));
$user = $dbForProject->getDocument('users', $membership->getAttribute('userId'));
$membership
->setAttribute('name', $user->getAttribute('name'))
@ -538,26 +538,26 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
->inject('request')
->inject('response')
->inject('user')
->inject('dbForInternal')
->inject('dbForProject')
->inject('audits')
->action(function ($teamId, $membershipId, $roles, $request, $response, $user, $dbForInternal, $audits) {
->action(function ($teamId, $membershipId, $roles, $request, $response, $user, $dbForProject, $audits) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $audits */
$team = $dbForInternal->getDocument('teams', $teamId);
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404);
}
$membership = $dbForInternal->getDocument('memberships', $membershipId);
$membership = $dbForProject->getDocument('memberships', $membershipId);
if ($membership->isEmpty()) {
throw new Exception('Membership not found', 404);
}
$profile = $dbForInternal->getDocument('users', $membership->getAttribute('userId'));
$profile = $dbForProject->getDocument('users', $membership->getAttribute('userId'));
if ($profile->isEmpty()) {
throw new Exception('User not found', 404);
}
@ -572,7 +572,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
// Update the roles
$membership->setAttribute('roles', $roles);
$membership = $dbForInternal->updateDocument('memberships', $membership->getId(), $membership);
$membership = $dbForProject->updateDocument('memberships', $membership->getId(), $membership);
// TODO sync updated membership in the user $profile object using TYPE_REPLACE
@ -604,20 +604,20 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
->inject('request')
->inject('response')
->inject('user')
->inject('dbForInternal')
->inject('dbForProject')
->inject('geodb')
->inject('audits')
->action(function ($teamId, $membershipId, $userId, $secret, $request, $response, $user, $dbForInternal, $geodb, $audits) {
->action(function ($teamId, $membershipId, $userId, $secret, $request, $response, $user, $dbForProject, $geodb, $audits) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var MaxMind\Db\Reader $geodb */
/** @var Appwrite\Event\Event $audits */
$protocol = $request->getProtocol();
$membership = $dbForInternal->getDocument('memberships', $membershipId);
$membership = $dbForProject->getDocument('memberships', $membershipId);
if ($membership->isEmpty()) {
throw new Exception('Membership not found', 404);
@ -627,7 +627,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
throw new Exception('Team IDs don\'t match', 404);
}
$team = Authorization::skip(fn() => $dbForInternal->getDocument('teams', $teamId));
$team = Authorization::skip(fn() => $dbForProject->getDocument('teams', $teamId));
if ($team->isEmpty()) {
throw new Exception('Team not found', 404);
@ -642,7 +642,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
}
if ($user->isEmpty()) {
$user = $dbForInternal->getDocument('users', $userId); // Get user
$user = $dbForProject->getDocument('users', $userId); // Get user
}
if ($membership->getAttribute('userId') !== $user->getId()) {
@ -668,7 +668,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
$expiry = \time() + Auth::TOKEN_EXPIRATION_LOGIN_LONG;
$secret = Auth::tokenGenerator();
$session = new Document(array_merge([
'$id' => $dbForInternal->getId(),
'$id' => $dbForProject->getId(),
'userId' => $user->getId(),
'provider' => Auth::SESSION_PROVIDER_EMAIL,
'providerUid' => $user->getAttribute('email'),
@ -679,7 +679,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--',
], $detector->getOS(), $detector->getClient(), $detector->getDevice()));
$session = $dbForInternal->createDocument('sessions', $session
$session = $dbForProject->createDocument('sessions', $session
->setAttribute('$read', ['user:'.$user->getId()])
->setAttribute('$write', ['user:'.$user->getId()])
);
@ -688,10 +688,10 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
Authorization::setRole('user:'.$userId);
$user = $dbForInternal->updateDocument('users', $user->getId(), $user);
$membership = $dbForInternal->updateDocument('memberships', $membership->getId(), $membership);
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
$membership = $dbForProject->updateDocument('memberships', $membership->getId(), $membership);
$team = Authorization::skip(fn() => $dbForInternal->updateDocument('teams', $team->getId(), $team->setAttribute('sum', $team->getAttribute('sum', 0) + 1)));
$team = Authorization::skip(fn() => $dbForProject->updateDocument('teams', $team->getId(), $team->setAttribute('sum', $team->getAttribute('sum', 0) + 1)));
$audits
->setParam('userId', $user->getId())
@ -730,16 +730,16 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
->param('teamId', '', new UID(), 'Team ID.')
->param('membershipId', '', new UID(), 'Membership ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('audits')
->inject('events')
->action(function ($teamId, $membershipId, $response, $dbForInternal, $audits, $events) {
->action(function ($teamId, $membershipId, $response, $dbForProject, $audits, $events) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $events */
$membership = $dbForInternal->getDocument('memberships', $membershipId);
$membership = $dbForProject->getDocument('memberships', $membershipId);
if ($membership->isEmpty()) {
throw new Exception('Invite not found', 404);
@ -749,19 +749,19 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
throw new Exception('Team IDs don\'t match', 404);
}
$user = $dbForInternal->getDocument('users', $membership->getAttribute('userId'));
$user = $dbForProject->getDocument('users', $membership->getAttribute('userId'));
if ($user->isEmpty()) {
throw new Exception('User not found', 404);
}
$team = $dbForInternal->getDocument('teams', $teamId);
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404);
}
if (!$dbForInternal->deleteDocument('memberships', $membership->getId())) {
if (!$dbForProject->deleteDocument('memberships', $membership->getId())) {
throw new Exception('Failed to remove membership from DB', 500);
}
@ -778,11 +778,11 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
$user->setAttribute('memberships', $memberships);
Authorization::skip(fn() => $dbForInternal->updateDocument('users', $user->getId(), $user));
Authorization::skip(fn() => $dbForProject->updateDocument('users', $user->getId(), $user));
if ($membership->getAttribute('confirm')) { // Count only confirmed members
$team->setAttribute('sum', \max($team->getAttribute('sum', 0) - 1, 0));
$team = $dbForInternal->updateDocument('teams', $team->getId(), $team);
$team = $dbForProject->updateDocument('teams', $team->getId(), $team);
}
$audits

View file

@ -39,18 +39,18 @@ App::post('/v1/users')
->param('password', '', new Password(), 'User password. Must be at least 8 chars.')
->param('name', '', new Text(128), 'User name. Max length: 128 chars.', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($userId, $email, $password, $name, $response, $dbForInternal, $usage) {
->action(function ($userId, $email, $password, $name, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Stats\Stats $usage */
$email = \strtolower($email);
try {
$userId = $userId == 'unique()' ? $dbForInternal->getId() : $userId;
$user = $dbForInternal->createDocument('users', new Document([
$userId = $userId == 'unique()' ? $dbForProject->getId() : $userId;
$user = $dbForProject->createDocument('users', new Document([
'$id' => $userId,
'$read' => ['role:all'],
'$write' => ['user:'.$userId],
@ -99,15 +99,15 @@ App::get('/v1/users')
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal, $usage) {
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Stats\Stats $usage */
if (!empty($cursor)) {
$cursorUser = $dbForInternal->getDocument('users', $cursor);
$cursorUser = $dbForProject->getDocument('users', $cursor);
if ($cursorUser->isEmpty()) {
throw new Exception("User '{$cursor}' for the 'cursor' value not found.", 400);
@ -127,8 +127,8 @@ App::get('/v1/users')
;
$response->dynamic(new Document([
'users' => $dbForInternal->find('users', $queries, $limit, $offset, [], [$orderType], $cursorUser ?? null, $cursorDirection),
'sum' => $dbForInternal->count('users', $queries, APP_LIMIT_COUNT),
'users' => $dbForProject->find('users', $queries, $limit, $offset, [], [$orderType], $cursorUser ?? null, $cursorDirection),
'sum' => $dbForProject->count('users', $queries, APP_LIMIT_COUNT),
]), Response::MODEL_USER_LIST);
});
@ -145,14 +145,14 @@ App::get('/v1/users/:userId')
->label('sdk.response.model', Response::MODEL_USER)
->param('userId', '', new UID(), 'User ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($userId, $response, $dbForInternal, $usage) {
->action(function ($userId, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Stats\Stats $usage */
$user = $dbForInternal->getDocument('users', $userId);
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty() || $user->getAttribute('deleted')) {
throw new Exception('User not found', 404);
@ -177,14 +177,14 @@ App::get('/v1/users/:userId/prefs')
->label('sdk.response.model', Response::MODEL_PREFERENCES)
->param('userId', '', new UID(), 'User ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($userId, $response, $dbForInternal, $usage) {
->action(function ($userId, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Stats\Stats $usage */
$user = $dbForInternal->getDocument('users', $userId);
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty() || $user->getAttribute('deleted')) {
throw new Exception('User not found', 404);
@ -211,16 +211,16 @@ App::get('/v1/users/:userId/sessions')
->label('sdk.response.model', Response::MODEL_SESSION_LIST)
->param('userId', '', new UID(), 'User ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('locale')
->inject('usage')
->action(function ($userId, $response, $dbForInternal, $locale, $usage) {
->action(function ($userId, $response, $dbForProject, $locale, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Locale\Locale $locale */
/** @var Appwrite\Stats\Stats $usage */
$user = $dbForInternal->getDocument('users', $userId);
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty() || $user->getAttribute('deleted')) {
throw new Exception('User not found', 404);
@ -245,7 +245,7 @@ App::get('/v1/users/:userId/sessions')
'sessions' => $sessions,
'sum' => count($sessions),
]), Response::MODEL_SESSION_LIST);
}, ['response', 'dbForInternal', 'locale']);
});
App::get('/v1/users/:userId/logs')
->desc('Get User Logs')
@ -262,25 +262,25 @@ App::get('/v1/users/:userId/logs')
->param('limit', 25, new Range(0, 100), 'Maximum number of logs to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->inject('usage')
->action(function ($userId, $limit, $offset, $response, $dbForInternal, $locale, $geodb, $usage) {
->action(function ($userId, $limit, $offset, $response, $dbForProject, $locale, $geodb, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Locale\Locale $locale */
/** @var MaxMind\Db\Reader $geodb */
/** @var Appwrite\Stats\Stats $usage */
$user = $dbForInternal->getDocument('users', $userId);
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty() || $user->getAttribute('deleted')) {
throw new Exception('User not found', 404);
}
$audit = new Audit($dbForInternal);
$audit = new Audit($dbForProject);
$auditEvents = [
'account.create',
'account.delete',
@ -367,20 +367,20 @@ App::patch('/v1/users/:userId/status')
->param('userId', '', new UID(), 'User ID.')
->param('status', null, new Boolean(true), 'User Status. To activate the user pass `true` and to block the user pass `false`.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($userId, $status, $response, $dbForInternal, $usage) {
->action(function ($userId, $status, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Stats\Stats $usage */
$user = $dbForInternal->getDocument('users', $userId);
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty() || $user->getAttribute('deleted')) {
throw new Exception('User not found', 404);
}
$user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('status', (bool) $status));
$user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('status', (bool) $status));
$usage
->setParam('users.update', 1)
@ -403,20 +403,20 @@ App::patch('/v1/users/:userId/verification')
->param('userId', '', new UID(), 'User ID.')
->param('emailVerification', false, new Boolean(), 'User email verification status.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($userId, $emailVerification, $response, $dbForInternal, $usage) {
->action(function ($userId, $emailVerification, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Stats\Stats $usage */
$user = $dbForInternal->getDocument('users', $userId);
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty() || $user->getAttribute('deleted')) {
throw new Exception('User not found', 404);
}
$user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('emailVerification', $emailVerification));
$user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('emailVerification', $emailVerification));
$usage
->setParam('users.update', 1)
@ -439,20 +439,20 @@ App::patch('/v1/users/:userId/name')
->param('userId', '', new UID(), 'User ID.')
->param('name', '', new Text(128), 'User name. Max length: 128 chars.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('audits')
->action(function ($userId, $name, $response, $dbForInternal, $audits) {
->action(function ($userId, $name, $response, $dbForProject, $audits) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $audits */
$user = $dbForInternal->getDocument('users', $userId);
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty() || $user->getAttribute('deleted')) {
throw new Exception('User not found', 404);
}
$user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('name', $name));
$user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('name', $name));
$audits
->setParam('userId', $user->getId())
@ -478,14 +478,14 @@ App::patch('/v1/users/:userId/password')
->param('userId', '', new UID(), 'User ID.')
->param('password', '', new Password(), 'New user password. Must be at least 8 chars.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('audits')
->action(function ($userId, $password, $response, $dbForInternal, $audits) {
->action(function ($userId, $password, $response, $dbForProject, $audits) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $audits */
$user = $dbForInternal->getDocument('users', $userId);
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty() || $user->getAttribute('deleted')) {
throw new Exception('User not found', 404);
@ -495,7 +495,7 @@ App::patch('/v1/users/:userId/password')
->setAttribute('password', Auth::passwordHash($password))
->setAttribute('passwordUpdate', \time());
$user = $dbForInternal->updateDocument('users', $user->getId(), $user);
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
$audits
->setParam('userId', $user->getId())
@ -521,14 +521,14 @@ App::patch('/v1/users/:userId/email')
->param('userId', '', new UID(), 'User ID.')
->param('email', '', new Email(), 'User email.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('audits')
->action(function ($userId, $email, $response, $dbForInternal, $audits) {
->action(function ($userId, $email, $response, $dbForProject, $audits) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $audits */
$user = $dbForInternal->getDocument('users', $userId);
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty() || $user->getAttribute('deleted')) {
throw new Exception('User not found', 404);
@ -542,7 +542,7 @@ App::patch('/v1/users/:userId/email')
$email = \strtolower($email);
try {
$user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('email', $email));
$user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('email', $email));
} catch(Duplicate $th) {
throw new Exception('Email already exists', 409);
}
@ -571,20 +571,20 @@ App::patch('/v1/users/:userId/prefs')
->param('userId', '', new UID(), 'User ID.')
->param('prefs', '', new Assoc(), 'Prefs key-value JSON object.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('usage')
->action(function ($userId, $prefs, $response, $dbForInternal, $usage) {
->action(function ($userId, $prefs, $response, $dbForProject, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Stats\Stats $usage */
$user = $dbForInternal->getDocument('users', $userId);
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty() || $user->getAttribute('deleted')) {
throw new Exception('User not found', 404);
}
$user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('prefs', $prefs));
$user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('prefs', $prefs));
$usage
->setParam('users.update', 1)
@ -606,16 +606,16 @@ App::delete('/v1/users/:userId/sessions/:sessionId')
->param('userId', '', new UID(), 'User ID.')
->param('sessionId', null, new UID(), 'Session ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('events')
->inject('usage')
->action(function ($userId, $sessionId, $response, $dbForInternal, $events, $usage) {
->action(function ($userId, $sessionId, $response, $dbForProject, $events, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Stats\Stats $usage */
$user = $dbForInternal->getDocument('users', $userId);
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty() || $user->getAttribute('deleted')) {
throw new Exception('User not found', 404);
@ -628,7 +628,7 @@ App::delete('/v1/users/:userId/sessions/:sessionId')
if ($sessionId == $session->getId()) {
unset($sessions[$key]);
$dbForInternal->deleteDocument('sessions', $session->getId());
$dbForProject->deleteDocument('sessions', $session->getId());
$user->setAttribute('sessions', $sessions);
@ -636,7 +636,7 @@ App::delete('/v1/users/:userId/sessions/:sessionId')
->setParam('eventData', $response->output($user, Response::MODEL_USER))
;
$dbForInternal->updateDocument('users', $user->getId(), $user);
$dbForProject->updateDocument('users', $user->getId(), $user);
}
}
@ -661,16 +661,16 @@ App::delete('/v1/users/:userId/sessions')
->label('sdk.response.model', Response::MODEL_NONE)
->param('userId', '', new UID(), 'User ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('events')
->inject('usage')
->action(function ($userId, $response, $dbForInternal, $events, $usage) {
->action(function ($userId, $response, $dbForProject, $events, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Stats\Stats $usage */
$user = $dbForInternal->getDocument('users', $userId);
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty() || $user->getAttribute('deleted')) {
throw new Exception('User not found', 404);
@ -679,10 +679,10 @@ App::delete('/v1/users/:userId/sessions')
$sessions = $user->getAttribute('sessions', []);
foreach ($sessions as $key => $session) { /** @var Document $session */
$dbForInternal->deleteDocument('sessions', $session->getId());
$dbForProject->deleteDocument('sessions', $session->getId());
}
$dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', []));
$dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('sessions', []));
$events
->setParam('eventData', $response->output($user, Response::MODEL_USER))
@ -708,18 +708,18 @@ App::delete('/v1/users/:userId')
->label('sdk.response.model', Response::MODEL_NONE)
->param('userId', '', function () {return new UID();}, 'User ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('events')
->inject('deletes')
->inject('usage')
->action(function ($userId, $response, $dbForInternal, $events, $deletes, $usage) {
->action(function ($userId, $response, $dbForProject, $events, $deletes, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Event\Event $deletes */
/** @var Appwrite\Stats\Stats $usage */
$user = $dbForInternal->getDocument('users', $userId);
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty() || $user->getAttribute('deleted')) {
throw new Exception('User not found', 404);
@ -735,7 +735,7 @@ App::delete('/v1/users/:userId')
->setAttribute("deleted", true)
;
$dbForInternal->updateDocument('users', $userId, $user);
$dbForProject->updateDocument('users', $userId, $user);
$deletes
->setParam('type', DELETE_TYPE_DOCUMENT)
@ -764,13 +764,13 @@ App::get('/v1/users/usage')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_USAGE_USERS)
->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true)
->param('provider', '', new WhiteList(\array_merge(['email', 'anonymous'], \array_map(function($value) { return "oauth-".$value; }, \array_keys(Config::getParam('providers', [])))), true), 'Provider Name.', true)
->param('provider', '', new WhiteList(\array_merge(['email', 'anonymous'], \array_map(fn($value) => "oauth-".$value, \array_keys(Config::getParam('providers', [])))), true), 'Provider Name.', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForProject')
->inject('register')
->action(function ($range, $provider, $response, $dbForInternal) {
->action(function ($range, $provider, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
$usage = [];
if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') {
@ -806,12 +806,12 @@ App::get('/v1/users/usage')
$stats = [];
Authorization::skip(function() use ($dbForInternal, $periods, $range, $metrics, &$stats) {
Authorization::skip(function() use ($dbForProject, $periods, $range, $metrics, &$stats) {
foreach ($metrics as $metric) {
$limit = $periods[$range]['limit'];
$period = $periods[$range]['period'];
$requestDocs = $dbForInternal->find('stats', [
$requestDocs = $dbForProject->find('stats', [
new Query('period', Query::TYPE_EQUAL, [$period]),
new Query('metric', Query::TYPE_EQUAL, [$metric]),
], $limit, 0, ['time'], [Database::ORDER_DESC]);

View file

@ -11,7 +11,7 @@ use Utopia\Database\Document;
use Utopia\Storage\Device\Local;
use Utopia\Storage\Storage;
App::init(function ($utopia, $request, $response, $project, $user, $events, $audits, $usage, $deletes, $database, $dbForInternal, $mode) {
App::init(function ($utopia, $request, $response, $project, $user, $events, $audits, $usage, $deletes, $database, $dbForProject, $mode) {
/** @var Utopia\App $utopia */
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
@ -24,7 +24,7 @@ App::init(function ($utopia, $request, $response, $project, $user, $events, $aud
/** @var Appwrite\Event\Event $deletes */
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $functions */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
Storage::setDevice('files', new Local(APP_STORAGE_UPLOADS.'/app-'.$project->getId()));
Storage::setDevice('functions', new Local(APP_STORAGE_FUNCTIONS.'/app-'.$project->getId()));
@ -38,7 +38,7 @@ App::init(function ($utopia, $request, $response, $project, $user, $events, $aud
/*
* Abuse Check
*/
$timeLimit = new TimeLimit($route->getLabel('abuse-key', 'url:{url},ip:{ip}'), $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), $dbForInternal);
$timeLimit = new TimeLimit($route->getLabel('abuse-key', 'url:{url},ip:{ip}'), $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), $dbForProject);
$timeLimit
->setParam('{userId}', $user->getId())
->setParam('{userAgent}', $request->getUserAgent(''))
@ -120,7 +120,7 @@ App::init(function ($utopia, $request, $response, $project, $user, $events, $aud
$database
->setParam('projectId', $project->getId())
;
}, ['utopia', 'request', 'response', 'project', 'user', 'events', 'audits', 'usage', 'deletes', 'database', 'dbForInternal', 'mode'], 'api');
}, ['utopia', 'request', 'response', 'project', 'user', 'events', 'audits', 'usage', 'deletes', 'database', 'dbForProject', 'mode'], 'api');
App::init(function ($utopia, $request, $project) {
/** @var Utopia\App $utopia */

View file

@ -78,54 +78,70 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) {
$dbForConsole = $app->getResource('dbForConsole'); /** @var Utopia\Database\Database $dbForConsole */
// if(!$dbForConsole->exists('appwrite')) {
Console::success('[Setup] - Server database init started...');
$collections = Config::getParam('collections', []); /** @var array $collections */
Console::success('[Setup] - Server database init started...');
$collections = Config::getParam('collections', []); /** @var array $collections */
if(!$dbForConsole->exists('appwrite')) {
$redis->flushAll();
$dbForConsole->create('appwrite');
Console::success('[Setup] - Creating database: appwrite...');
$dbForConsole->create('appwrite');
}
try {
Console::success('[Setup] - Creating metadata table: appwrite...');
$dbForConsole->createMetadata();
} catch (\Throwable $th) {
Console::success('[Setup] - Skip: metadata table already exists');
}
if($dbForConsole->getCollection(Audit::COLLECTION)->isEmpty()) {
$audit = new Audit($dbForConsole);
$audit->setup();
}
if ($dbForConsole->getCollection(TimeLimit::COLLECTION)->isEmpty()) {
$adapter = new TimeLimit("", 0, 1, $dbForConsole);
$adapter->setup();
}
foreach ($collections as $key => $collection) {
Console::success('[Setup] - Creating collection: ' . $collection['$id'] . '...');
$attributes = [];
$indexes = [];
foreach ($collection['attributes'] as $attribute) {
$attributes[] = new Document([
'$id' => $attribute['$id'],
'type' => $attribute['type'],
'size' => $attribute['size'],
'required' => $attribute['required'],
'signed' => $attribute['signed'],
'array' => $attribute['array'],
'filters' => $attribute['filters'],
]);
}
foreach ($collection['indexes'] as $index) {
$indexes[] = new Document([
'$id' => $index['$id'],
'type' => $index['type'],
'attributes' => $index['attributes'],
'lengths' => $index['lengths'],
'orders' => $index['orders'],
]);
}
$dbForConsole->createCollection($key, $attributes, $indexes);
foreach ($collections as $key => $collection) {
if(!$dbForConsole->getCollection($key)->isEmpty()) {
continue;
}
Console::success('[Setup] - Server database init completed...');
// }
Console::success('[Setup] - Creating collection: ' . $collection['$id'] . '...');
$attributes = [];
$indexes = [];
foreach ($collection['attributes'] as $attribute) {
$attributes[] = new Document([
'$id' => $attribute['$id'],
'type' => $attribute['type'],
'size' => $attribute['size'],
'required' => $attribute['required'],
'signed' => $attribute['signed'],
'array' => $attribute['array'],
'filters' => $attribute['filters'],
]);
}
foreach ($collection['indexes'] as $index) {
$indexes[] = new Document([
'$id' => $index['$id'],
'type' => $index['type'],
'attributes' => $index['attributes'],
'lengths' => $index['lengths'],
'orders' => $index['orders'],
]);
}
$dbForConsole->createCollection($key, $attributes, $indexes);
}
Console::success('[Setup] - Server database init completed...');
});
Console::success('Server started successfully (max payload is '.number_format($payloadSize).' bytes)');

View file

@ -602,7 +602,7 @@ App::setResource('usage', function($register) {
return new Stats($register->get('statsd'));
}, ['register']);
App::setResource('clients', function($request, $console, $project) {
App::setResource('clients', function ($request, $console, $project) {
$console->setAttribute('platforms', [ // Always allow current host
'$collection' => 'platforms',
'name' => 'Current Host',
@ -614,34 +614,35 @@ App::setResource('clients', function($request, $console, $project) {
* Get All verified client URLs for both console and current projects
* + Filter for duplicated entries
*/
$clientsConsole = \array_map(function ($node) {
return $node['hostname'];
}, \array_filter($console->getAttribute('platforms', []), function ($node) {
if (isset($node['type']) && $node['type'] === 'web' && isset($node['hostname']) && !empty($node['hostname'])) {
return true;
}
$clientsConsole = \array_map(
fn ($node) => $node['hostname'],
\array_filter(
$console->getAttribute('platforms', []),
fn ($node) => (isset($node['type']) && $node['type'] === 'web' && isset($node['hostname']) && !empty($node['hostname']))
)
);
return false;
}));
$clients = \array_unique(\array_merge($clientsConsole, \array_map(function ($node) {
return $node['hostname'];
}, \array_filter($project->getAttribute('platforms', []), function ($node) {
if (isset($node['type']) && $node['type'] === 'web' && isset($node['hostname']) && !empty($node['hostname'])) {
return true;
}
return false;
}))));
$clients = \array_unique(
\array_merge(
$clientsConsole,
\array_map(
fn ($node) => $node['hostname'],
\array_filter(
$project->getAttribute('platforms', []),
fn ($node) => (isset($node['type']) && $node['type'] === 'web' && isset($node['hostname']) && !empty($node['hostname']))
)
)
)
);
return $clients;
}, ['request', 'console', 'project']);
App::setResource('user', function($mode, $project, $console, $request, $response, $dbForInternal, $dbForConsole) {
App::setResource('user', function($mode, $project, $console, $request, $response, $dbForProject, $dbForConsole) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Database\Database $dbForConsole */
/** @var string $mode */
@ -675,7 +676,7 @@ App::setResource('user', function($mode, $project, $console, $request, $response
$user = new Document(['$id' => '', '$collection' => 'users']);
}
else {
$user = $dbForInternal->getDocument('users', Auth::$unique);
$user = $dbForProject->getDocument('users', Auth::$unique);
}
}
else {
@ -710,7 +711,7 @@ App::setResource('user', function($mode, $project, $console, $request, $response
$jwtSessionId = $payload['sessionId'] ?? '';
if($jwtUserId && $jwtSessionId) {
$user = $dbForInternal->getDocument('users', $jwtUserId);
$user = $dbForProject->getDocument('users', $jwtUserId);
}
if (empty($user->find('$id', $jwtSessionId, 'sessions'))) { // Match JWT to active token
@ -719,7 +720,7 @@ App::setResource('user', function($mode, $project, $console, $request, $response
}
return $user;
}, ['mode', 'project', 'console', 'request', 'response', 'dbForInternal', 'dbForConsole']);
}, ['mode', 'project', 'console', 'request', 'response', 'dbForProject', 'dbForConsole']);
App::setResource('project', function($dbForConsole, $request, $console) {
/** @var Utopia\Swoole\Request $request */
@ -781,17 +782,7 @@ App::setResource('console', function() {
]);
}, []);
App::setResource('dbForInternal', function($db, $cache, $project) {
$cache = new Cache(new RedisCache($cache));
$database = new Database(new MariaDB($db), $cache);
$database->setDefaultDatabase('appwrite');
$database->setNamespace('_project_'.$project->getId());
return $database;
}, ['db', 'cache', 'project']);
App::setResource('dbForExternal', function($db, $cache, $project) {
App::setResource('dbForProject', function($db, $cache, $project) {
$cache = new Cache(new RedisCache($cache));
$database = new Database(new MariaDB($db), $cache);

View file

@ -223,7 +223,9 @@ $cli
$cacheAdapter = new Cache(new Redis($redis));
$dbForProject = new Database(new MariaDB($db), $cacheAdapter);
$dbForConsole = new Database(new MariaDB($db), $cacheAdapter);
$dbForConsole->setNamespace('project_console_internal');
$dbForProject->setDefaultDatabase('appwrite');
$dbForConsole->setDefaultDatabase('appwrite');
$dbForConsole->setNamespace('_project_console');
$latestTime = [];
@ -276,9 +278,7 @@ $cli
$filters = $options['filters'] ?? []; // Some metrics might have additional filters, like function's status
if (!empty($filters)) {
$filters = ' AND ' . implode(' AND ', array_map(function ($filter, $value) {
return "\"{$filter}\"='{$value}'";
}, array_keys($filters), array_values($filters)));
$filters = ' AND ' . implode(' AND ', array_map(fn ($filter, $value) => "\"{$filter}\"='{$value}'", array_keys($filters), array_values($filters)));
} else {
$filters = '';
}
@ -291,7 +291,7 @@ $cli
$projectId = $point['projectId'];
if (!empty($projectId) && $projectId !== 'console') {
$dbForProject->setNamespace('project_' . $projectId . '_internal');
$dbForProject->setNamespace('_project_' . $projectId);
$metricUpdated = $metric;
if (!empty($groupBy)) {
@ -371,7 +371,7 @@ $cli
$projectId = $project->getId();
// Get total storage
$dbForProject->setNamespace('project_' . $projectId . '_internal');
$dbForProject->setNamespace('_project_' . $projectId);
$storageTotal = $dbForProject->sum('files', 'sizeOriginal') + $dbForProject->sum('tags', 'size');
$time = (int) (floor(time() / 1800) * 1800); // Time rounded to nearest 30 minutes
@ -435,9 +435,8 @@ $cli
foreach ($collections as $collection => $options) {
try {
$dbForProject->setNamespace("project_{$projectId}_{$options['namespace']}");
$dbForProject->setNamespace("_project_{$projectId}");
$count = $dbForProject->count($collection);
$dbForProject->setNamespace("project_{$projectId}_internal");
$metricPrefix = $options['metricPrefix'] ?? '';
$metric = empty($metricPrefix) ? "{$collection}.count" : "{$metricPrefix}.{$collection}.count";
@ -491,7 +490,7 @@ $cli
$subCollectionCounts = []; //total project level count of sub collections
do { // Loop over all the parent collection document for each sub collection
$dbForProject->setNamespace("project_{$projectId}_{$options['namespace']}");
$dbForProject->setNamespace("_project_{$projectId}");
$parents = $dbForProject->find($collection, [], 100, cursor: $latestParent); // Get all the parents for the sub collections for example for documents, this will get all the collections
if (empty($parents)) {
@ -502,12 +501,12 @@ $cli
foreach ($parents as $parent) {
foreach ($subCollections as $subCollection => $subOptions) { // Sub collection counts, like database.collections.collectionId.documents.count
$dbForProject->setNamespace("project_{$projectId}_{$subOptions['namespace']}");
$dbForProject->setNamespace("_project_{$projectId}");
$count = $dbForProject->count($parent->getId());
$subCollectionCounts[$subCollection] = ($subCollectionCounts[$subCollection] ?? 0) + $count; // Project level counts for sub collections like database.documents.count
$dbForProject->setNamespace("project_{$projectId}_internal");
$dbForProject->setNamespace("_project_{$projectId}");
$metric = empty($metricPrefix) ? "{$collection}.{$parent->getId()}.{$subCollection}.count" : "{$metricPrefix}.{$collection}.{$parent->getId()}.{$subCollection}.count";
$time = (int) (floor(time() / 1800) * 1800); // Time rounded to nearest 30 minutes
@ -557,7 +556,7 @@ $cli
* Inserting project level counts for sub collections like database.documents.count
*/
foreach ($subCollectionCounts as $subCollection => $count) {
$dbForProject->setNamespace("project_{$projectId}_internal");
$dbForProject->setNamespace("_project_{$projectId}");
$metric = empty($metricPrefix) ? "{$subCollection}.count" : "{$metricPrefix}.{$subCollection}.count";

View file

@ -28,8 +28,8 @@ class AuditsV1 extends Worker
$ip = $this->args['ip'];
$data = $this->args['data'];
$dbForInternal = $this->getInternalDB($projectId);
$audit = new Audit($dbForInternal);
$dbForProject = $this->getProjectDB($projectId);
$audit = new Audit($dbForProject);
$audit->log($userId, $event, $resource, $userAgent, $ip, '', [
'userName' => $userName,

View file

@ -69,8 +69,7 @@ class DatabaseV1 extends Worker
protected function createAttribute(Document $collection, Document $attribute, string $projectId): void
{
$dbForConsole = $this->getConsoleDB();
$dbForInternal = $this->getInternalDB($projectId);
$dbForExternal = $this->getExternalDB($projectId);
$dbForProject = $this->getProjectDB($projectId);
$event = 'database.attributes.update';
$collectionId = $collection->getId();
@ -87,13 +86,13 @@ class DatabaseV1 extends Worker
$project = $dbForConsole->getDocument('projects', $projectId);
try {
if(!$dbForExternal->createAttribute('collection_' . $collectionId, $key, $type, $size, $required, $default, $signed, $array, $format, $formatOptions, $filters)) {
if(!$dbForProject->createAttribute('collection_' . $collectionId, $key, $type, $size, $required, $default, $signed, $array, $format, $formatOptions, $filters)) {
throw new Exception('Failed to create Attribute');
}
$dbForInternal->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'available'));
$dbForProject->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'available'));
} catch (\Throwable $th) {
Console::error($th->getMessage());
$dbForInternal->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'failed'));
$dbForProject->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'failed'));
} finally {
$target = Realtime::fromPayload($event, $attribute, $project);
@ -110,7 +109,7 @@ class DatabaseV1 extends Worker
);
}
$dbForInternal->deleteCachedDocument('collections', $collectionId);
$dbForProject->deleteCachedDocument('collections', $collectionId);
}
/**
@ -121,8 +120,7 @@ class DatabaseV1 extends Worker
protected function deleteAttribute(Document $collection, Document $attribute, string $projectId): void
{
$dbForConsole = $this->getConsoleDB();
$dbForInternal = $this->getInternalDB($projectId);
$dbForExternal = $this->getExternalDB($projectId);
$dbForProject = $this->getProjectDB($projectId);
$event = 'database.attributes.delete';
$collectionId = $collection->getId();
@ -137,13 +135,13 @@ class DatabaseV1 extends Worker
// - failed: attribute was never created
// - stuck: attribute was available but cannot be removed
try {
if($status !== 'failed' && !$dbForExternal->deleteAttribute('collection_' . $collectionId, $key)) {
if($status !== 'failed' && !$dbForProject->deleteAttribute('collection_' . $collectionId, $key)) {
throw new Exception('Failed to delete Attribute');
}
$dbForInternal->deleteDocument('attributes', $attribute->getId());
$dbForProject->deleteDocument('attributes', $attribute->getId());
} catch (\Throwable $th) {
Console::error($th->getMessage());
$dbForInternal->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'stuck'));
$dbForProject->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'stuck'));
} finally {
$target = Realtime::fromPayload($event, $attribute, $project);
@ -182,7 +180,7 @@ class DatabaseV1 extends Worker
$orders = \array_values(\array_diff($orders, [$orders[$found]]));
if (empty($attributes)) {
$dbForInternal->deleteDocument('indexes', $index->getId());
$dbForProject->deleteDocument('indexes', $index->getId());
} else {
$index
->setAttribute('attributes', $attributes, Document::SET_TYPE_ASSIGN)
@ -205,13 +203,13 @@ class DatabaseV1 extends Worker
if ($exists) { // Delete the duplicate if created, else update in db
$this->deleteIndex($collection, $index, $projectId);
} else {
$dbForInternal->updateDocument('indexes', $index->getId(), $index);
$dbForProject->updateDocument('indexes', $index->getId(), $index);
}
}
}
}
$dbForInternal->deleteCachedDocument('collections', $collectionId);
$dbForProject->deleteCachedDocument('collections', $collectionId);
}
/**
@ -222,8 +220,7 @@ class DatabaseV1 extends Worker
protected function createIndex(Document $collection, Document $index, string $projectId): void
{
$dbForConsole = $this->getConsoleDB();
$dbForInternal = $this->getInternalDB($projectId);
$dbForExternal = $this->getExternalDB($projectId);
$dbForProject = $this->getProjectDB($projectId);
$event = 'database.indexes.update';
$collectionId = $collection->getId();
@ -235,13 +232,13 @@ class DatabaseV1 extends Worker
$project = $dbForConsole->getDocument('projects', $projectId);
try {
if(!$dbForExternal->createIndex('collection_' . $collectionId, $key, $type, $attributes, $lengths, $orders)) {
if(!$dbForProject->createIndex('collection_' . $collectionId, $key, $type, $attributes, $lengths, $orders)) {
throw new Exception('Failed to create Index');
}
$dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'available'));
$dbForProject->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'available'));
} catch (\Throwable $th) {
Console::error($th->getMessage());
$dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'failed'));
$dbForProject->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'failed'));
} finally {
$target = Realtime::fromPayload($event, $index, $project);
@ -258,7 +255,7 @@ class DatabaseV1 extends Worker
);
}
$dbForInternal->deleteCachedDocument('collections', $collectionId);
$dbForProject->deleteCachedDocument('collections', $collectionId);
}
/**
@ -269,8 +266,7 @@ class DatabaseV1 extends Worker
protected function deleteIndex(Document $collection, Document $index, string $projectId): void
{
$dbForConsole = $this->getConsoleDB();
$dbForInternal = $this->getInternalDB($projectId);
$dbForExternal = $this->getExternalDB($projectId);
$dbForProject = $this->getProjectDB($projectId);
$collectionId = $collection->getId();
$key = $index->getAttribute('key');
@ -279,13 +275,13 @@ class DatabaseV1 extends Worker
$project = $dbForConsole->getDocument('projects', $projectId);
try {
if($status !== 'failed' && !$dbForExternal->deleteIndex('collection_' . $collectionId, $key)) {
if($status !== 'failed' && !$dbForProject->deleteIndex('collection_' . $collectionId, $key)) {
throw new Exception('Failed to delete index');
}
$dbForInternal->deleteDocument('indexes', $index->getId());
$dbForProject->deleteDocument('indexes', $index->getId());
} catch (\Throwable $th) {
Console::error($th->getMessage());
$dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'stuck'));
$dbForProject->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'stuck'));
} finally {
$target = Realtime::fromPayload($event, $index, $project);
@ -302,6 +298,6 @@ class DatabaseV1 extends Worker
);
}
$dbForInternal->deleteCachedDocument('collections', $collectionId);
$dbForProject->deleteCachedDocument('collections', $collectionId);
}
}

View file

@ -100,18 +100,17 @@ class DeletesV1 extends Worker
{
$collectionId = $document->getId();
$dbForInternal = $this->getInternalDB($projectId);
$dbForExternal = $this->getExternalDB($projectId);
$dbForProject = $this->getProjectDB($projectId);
$dbForExternal->deleteCollection($collectionId);
$dbForProject->deleteCollection($collectionId);
$this->deleteByGroup('attributes', [
new Query('collectionId', Query::TYPE_EQUAL, [$collectionId])
], $dbForInternal);
], $dbForProject);
$this->deleteByGroup('indexes', [
new Query('collectionId', Query::TYPE_EQUAL, [$collectionId])
], $dbForInternal);
], $dbForProject);
}
/**
@ -121,17 +120,17 @@ class DeletesV1 extends Worker
protected function deleteUsageStats(int $timestamp1d, int $timestamp30m)
{
$this->deleteForProjectIds(function (string $projectId) use ($timestamp1d, $timestamp30m) {
$dbForInternal = $this->getInternalDB($projectId);
$dbForProject = $this->getProjectDB($projectId);
// Delete Usage stats
$this->deleteByGroup('stats', [
new Query('time', Query::TYPE_LESSER, [$timestamp1d]),
new Query('period', Query::TYPE_EQUAL, ['1d']),
], $dbForInternal);
], $dbForProject);
$this->deleteByGroup('stats', [
new Query('time', Query::TYPE_LESSER, [$timestamp30m]),
new Query('period', Query::TYPE_EQUAL, ['30m']),
], $dbForInternal);
], $dbForProject);
});
}
@ -146,7 +145,7 @@ class DeletesV1 extends Worker
// Delete Memberships
$this->deleteByGroup('memberships', [
new Query('teamId', Query::TYPE_EQUAL, [$teamId])
], $this->getInternalDB($projectId));
], $this->getProjectDB($projectId));
}
/**
@ -157,8 +156,7 @@ class DeletesV1 extends Worker
$projectId = $document->getId();
// Delete all DBs
$this->getExternalDB($projectId)->delete();
$this->getInternalDB($projectId)->delete();
$this->getProjectDB($projectId)->delete($projectId);
// Delete all storage directories
$uploads = new Local(APP_STORAGE_UPLOADS . '/app-' . $document->getId());
@ -180,13 +178,13 @@ class DeletesV1 extends Worker
// Delete Memberships and decrement team membership counts
$this->deleteByGroup('memberships', [
new Query('userId', Query::TYPE_EQUAL, [$userId])
], $this->getInternalDB($projectId), function (Document $document) use ($projectId) {
], $this->getProjectDB($projectId), function (Document $document) use ($projectId) {
if ($document->getAttribute('confirm')) { // Count only confirmed members
$teamId = $document->getAttribute('teamId');
$team = $this->getInternalDB($projectId)->getDocument('teams', $teamId);
$team = $this->getProjectDB($projectId)->getDocument('teams', $teamId);
if (!$team->isEmpty()) {
$team = $this->getInternalDB($projectId)->updateDocument('teams', $teamId, new Document(\array_merge($team->getArrayCopy(), [
$team = $this->getProjectDB($projectId)->updateDocument('teams', $teamId, new Document(\array_merge($team->getArrayCopy(), [
'sum' => \max($team->getAttribute('sum', 0) - 1, 0), // Ensure that sum >= 0
])));
}
@ -200,11 +198,11 @@ class DeletesV1 extends Worker
protected function deleteExecutionLogs(int $timestamp): void
{
$this->deleteForProjectIds(function (string $projectId) use ($timestamp) {
$dbForInternal = $this->getInternalDB($projectId);
$dbForProject = $this->getProjectDB($projectId);
// Delete Executions
$this->deleteByGroup('executions', [
new Query('dateCreated', Query::TYPE_LESSER, [$timestamp])
], $dbForInternal);
], $dbForProject);
});
}
@ -214,11 +212,11 @@ class DeletesV1 extends Worker
protected function deleteRealtimeUsage(int $timestamp): void
{
$this->deleteForProjectIds(function (string $projectId) use ($timestamp) {
$dbForInternal = $this->getInternalDB($projectId);
$dbForProject = $this->getProjectDB($projectId);
// Delete Dead Realtime Logs
$this->deleteByGroup('realtime', [
new Query('timestamp', Query::TYPE_LESSER, [$timestamp])
], $dbForInternal);
], $dbForProject);
});
}
@ -232,8 +230,8 @@ class DeletesV1 extends Worker
}
$this->deleteForProjectIds(function (string $projectId) use ($timestamp) {
$dbForInternal = $this->getInternalDB($projectId);
$timeLimit = new TimeLimit("", 0, 1, $dbForInternal);
$dbForProject = $this->getProjectDB($projectId);
$timeLimit = new TimeLimit("", 0, 1, $dbForProject);
$abuse = new Abuse($timeLimit);
$status = $abuse->cleanup($timestamp);
@ -252,8 +250,8 @@ class DeletesV1 extends Worker
throw new Exception('Failed to delete audit logs. No timestamp provided');
}
$this->deleteForProjectIds(function (string $projectId) use ($timestamp) {
$dbForInternal = $this->getInternalDB($projectId);
$audit = new Audit($dbForInternal);
$dbForProject = $this->getProjectDB($projectId);
$audit = new Audit($dbForProject);
$status = $audit->cleanup($timestamp);
if (!$status) {
throw new Exception('Failed to delete Audit logs for project' . $projectId);
@ -267,13 +265,13 @@ class DeletesV1 extends Worker
*/
protected function deleteFunction(Document $document, string $projectId): void
{
$dbForInternal = $this->getInternalDB($projectId);
$dbForProject = $this->getProjectDB($projectId);
$device = new Local(APP_STORAGE_FUNCTIONS . '/app-' . $projectId);
// Delete Tags
$this->deleteByGroup('tags', [
new Query('functionId', Query::TYPE_EQUAL, [$document->getId()])
], $dbForInternal, function (Document $document) use ($device) {
], $dbForProject, function (Document $document) use ($device) {
if ($device->delete($document->getAttribute('path', ''))) {
Console::success('Delete code tag: ' . $document->getAttribute('path', ''));
@ -285,7 +283,7 @@ class DeletesV1 extends Worker
// Delete Executions
$this->deleteByGroup('executions', [
new Query('functionId', Query::TYPE_EQUAL, [$document->getId()])
], $dbForInternal);
], $dbForProject);
}

View file

@ -118,7 +118,7 @@ class FunctionsV1 extends Worker
$userId = $this->args['userId'] ?? '';
$jwt = $this->args['jwt'] ?? '';
$database = $this->getInternalDB($projectId);
$database = $this->getProjectDB($projectId);
switch ($trigger) {
case 'event':

8
composer.lock generated
View file

@ -2142,12 +2142,12 @@
"source": {
"type": "git",
"url": "https://github.com/utopia-php/database.git",
"reference": "414178de818ce50832d26b4f4826f10fef64c740"
"reference": "a041dd2e7e947d29123ba5a32d6bbecf769e9a4d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/414178de818ce50832d26b4f4826f10fef64c740",
"reference": "414178de818ce50832d26b4f4826f10fef64c740",
"url": "https://api.github.com/repos/utopia-php/database/zipball/a041dd2e7e947d29123ba5a32d6bbecf769e9a4d",
"reference": "a041dd2e7e947d29123ba5a32d6bbecf769e9a4d",
"shasum": ""
},
"require": {
@ -2197,7 +2197,7 @@
"issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/feat-database-and-namespace"
},
"time": "2021-12-23T22:38:30+00:00"
"time": "2021-12-27T11:08:47+00:00"
},
{
"name": "utopia-php/domains",

View file

@ -21,8 +21,7 @@ abstract class Worker
const MAX_ATTEMPTS = 10;
const SLEEP_TIME = 2;
const DATABASE_INTERNAL = 'internal';
const DATABASE_EXTERNAL = 'external';
const DATABASE_PROJECT = 'project';
const DATABASE_CONSOLE = 'console';
public function setUp(): void
@ -44,19 +43,9 @@ abstract class Worker
* @param string $projectId
* @return Database
*/
protected function getInternalDB(string $projectId): Database
protected function getProjectDB(string $projectId): Database
{
return $this->getDB(self::DATABASE_INTERNAL, $projectId);
}
/**
* Get external project database
* @param string $projectId
* @return Database
*/
protected function getExternalDB(string $projectId): Database
{
return $this->getDB(self::DATABASE_EXTERNAL, $projectId);
return $this->getDB(self::DATABASE_PROJECT, $projectId);
}
/**
@ -82,13 +71,7 @@ abstract class Worker
$sleep = self::SLEEP_TIME; // overwritten when necessary
switch ($type) {
case self::DATABASE_INTERNAL:
if (!$projectId) {
throw new \Exception('ProjectID not provided - cannot get database');
}
$namespace = "_project_{$projectId}";
break;
case self::DATABASE_EXTERNAL:
case self::DATABASE_PROJECT:
if (!$projectId) {
throw new \Exception('ProjectID not provided - cannot get database');
}