diff --git a/CHANGES.md b/CHANGES.md index 94b56bc7a0..ca647e7489 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,11 @@ +# Version 0.9.2 + +## Bugs + +- Fixed JWT session validation (#1408) +- Fixed passing valid JWT session to Cloud Functions (#1421) +- Fixed race condition when uploading and extracting bigger Cloud Functions (#1419) + # Version 0.9.1 ## Bugs diff --git a/app/config/collections2.php b/app/config/collections2.php index e92bc4b145..b066407c7c 100644 --- a/app/config/collections2.php +++ b/app/config/collections2.php @@ -609,13 +609,13 @@ $collections = [ ], ], 'indexes' => [ - // [ - // '$id' => '_key_provider_providerUid', - // 'type' => Database::INDEX_KEY, - // 'attributes' => ['provider', 'providerUid'], - // 'lengths' => [100, 100], - // 'orders' => [Database::ORDER_ASC, Database::ORDER_ASC], - // ] + [ + '$id' => '_key_provider_providerUid', + 'type' => Database::INDEX_KEY, + 'attributes' => ['provider', 'providerUid'], + 'lengths' => [100, 100], + 'orders' => [Database::ORDER_ASC, Database::ORDER_ASC], + ] ], ], diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 044664d655..27d9f82006 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -53,7 +53,7 @@ App::post('/v1/account') ->action(function ($email, $password, $name, $request, $response, $project, $dbForInternal, $audits) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ - /** @var Appwrite\Database\Document $project */ + /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Database $dbForInternal */ /** @var Appwrite\Event\Event $audits */ @@ -119,7 +119,7 @@ App::post('/v1/account') ; $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($user, Response::MODEL_USER); + $response->dynamic($user, Response::MODEL_USER); }); App::post('/v1/account/sessions') @@ -229,7 +229,7 @@ App::post('/v1/account/sessions') ->setAttribute('countryName', $countryName) ; - $response->dynamic2($session, Response::MODEL_SESSION); + $response->dynamic($session, Response::MODEL_SESSION); }); App::get('/v1/account/sessions/oauth2/:provider') @@ -256,7 +256,7 @@ App::get('/v1/account/sessions/oauth2/:provider') ->action(function ($provider, $success, $failure, $scopes, $request, $response, $project) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ - /** @var Appwrite\Database\Document $project */ + /** @var Utopia\Database\Document $project */ $protocol = $request->getProtocol(); $callback = $protocol.'://'.$request->getHostname().'/v1/account/sessions/oauth2/callback/'.$provider.'/'.$project->getId(); @@ -362,7 +362,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') ->action(function ($provider, $code, $state, $request, $response, $project, $user, $dbForInternal, $geodb, $audits, $events) use ($oauthDefaultSuccess) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ - /** @var Appwrite\Database\Document $project */ + /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Database $dbForInternal */ /** @var MaxMind\Db\Reader $geodb */ @@ -546,7 +546,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') ->setParam('data', ['provider' => $provider]) ; - $events->setParam('eventData', $response->output2($session, Response::MODEL_SESSION)); + $events->setParam('eventData', $response->output($session, Response::MODEL_SESSION)); if (!Config::getParam('domainVerification')) { $response @@ -603,7 +603,7 @@ App::post('/v1/account/sessions/anonymous') /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Locale\Locale $locale */ /** @var Utopia\Database\Document $user */ - /** @var Appwrite\Database\Document $project */ + /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Database $dbForInternal */ /** @var MaxMind\Db\Reader $geodb */ /** @var Appwrite\Event\Event $audits */ @@ -710,7 +710,7 @@ App::post('/v1/account/sessions/anonymous') ->setAttribute('countryName', $countryName) ; - $response->dynamic2($session, Response::MODEL_SESSION); + $response->dynamic($session, Response::MODEL_SESSION); }); App::post('/v1/account/jwt') @@ -737,7 +737,7 @@ App::post('/v1/account/jwt') $current = new Document(); foreach ($sessions as $session) { - /** @var Appwrite\Database\Document $session */ + /** @var Utopia\Database\Document $session */ if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too $current = $session; @@ -751,7 +751,7 @@ App::post('/v1/account/jwt') $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 900, 10); // Instantiate with key, algo, maxAge and leeway. $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2(new Document(['jwt' => $jwt->encode([ + $response->dynamic(new Document(['jwt' => $jwt->encode([ // 'uid' => 1, // 'aud' => 'http://site.com', // 'scopes' => ['user'], @@ -778,7 +778,7 @@ App::get('/v1/account') /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ - $response->dynamic2($user, Response::MODEL_USER); + $response->dynamic($user, Response::MODEL_USER); }); App::get('/v1/account/prefs') @@ -800,7 +800,7 @@ App::get('/v1/account/prefs') $prefs = $user->getAttribute('prefs', new \stdClass()); - $response->dynamic2(new Document($prefs), Response::MODEL_PREFERENCES); + $response->dynamic(new Document($prefs), Response::MODEL_PREFERENCES); }); App::get('/v1/account/sessions') @@ -837,7 +837,7 @@ App::get('/v1/account/sessions') $sessions[$key] = $session; } - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'sessions' => $sessions, 'sum' => count($sessions), ]), Response::MODEL_SESSION_LIST); @@ -861,7 +861,7 @@ App::get('/v1/account/logs') ->inject('dbForInternal') ->action(function ($response, $user, $locale, $geodb, $dbForInternal) { /** @var Appwrite\Utopia\Response $response */ - /** @var Appwrite\Database\Document $project */ + /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Document $user */ /** @var Utopia\Locale\Locale $locale */ /** @var MaxMind\Db\Reader $geodb */ @@ -914,7 +914,7 @@ App::get('/v1/account/logs') } - $response->dynamic2(new Document(['logs' => $output]), Response::MODEL_LOG_LIST); + $response->dynamic(new Document(['logs' => $output]), Response::MODEL_LOG_LIST); }); App::get('/v1/account/sessions/:sessionId') @@ -935,7 +935,7 @@ App::get('/v1/account/sessions/:sessionId') ->inject('dbForInternal') ->action(function ($sessionId, $response, $user, $locale, $dbForInternal) { /** @var Appwrite\Utopia\Response $response */ - /** @var Appwrite\Database\Document $user */ + /** @var Utopia\Database\Document $user */ /** @var Utopia\Locale\Locale $locale */ /** @var Utopia\Database\Database $dbForInternal */ @@ -956,7 +956,7 @@ App::get('/v1/account/sessions/:sessionId') ->setAttribute('countryName', $countryName) ; - return $response->dynamic2($session, Response::MODEL_SESSION); + return $response->dynamic($session, Response::MODEL_SESSION); } } @@ -994,7 +994,7 @@ App::patch('/v1/account/name') ->setParam('resource', 'users/'.$user->getId()) ; - $response->dynamic2($user, Response::MODEL_USER); + $response->dynamic($user, Response::MODEL_USER); }); App::patch('/v1/account/password') @@ -1037,7 +1037,7 @@ App::patch('/v1/account/password') ->setParam('resource', 'users/'.$user->getId()) ; - $response->dynamic2($user, Response::MODEL_USER); + $response->dynamic($user, Response::MODEL_USER); }); App::patch('/v1/account/email') @@ -1092,7 +1092,7 @@ App::patch('/v1/account/email') ->setParam('resource', 'users/'.$user->getId()) ; - $response->dynamic2($user, Response::MODEL_USER); + $response->dynamic($user, Response::MODEL_USER); }); App::patch('/v1/account/prefs') @@ -1125,7 +1125,7 @@ App::patch('/v1/account/prefs') ->setParam('resource', 'users/'.$user->getId()) ; - $response->dynamic2($user, Response::MODEL_USER); + $response->dynamic($user, Response::MODEL_USER); }); App::delete('/v1/account') @@ -1172,7 +1172,7 @@ App::delete('/v1/account') ; $events - ->setParam('eventData', $response->output2($user, Response::MODEL_USER)) + ->setParam('eventData', $response->output($user, Response::MODEL_USER)) ; if (!Config::getParam('domainVerification')) { @@ -1259,7 +1259,7 @@ App::delete('/v1/account/sessions/:sessionId') $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', $sessions)); $events - ->setParam('eventData', $response->output2($session, Response::MODEL_SESSION)) + ->setParam('eventData', $response->output($session, Response::MODEL_SESSION)) ; return $response->noContent(); @@ -1332,7 +1332,7 @@ App::delete('/v1/account/sessions') $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', [])); $events - ->setParam('eventData', $response->output2(new Document([ + ->setParam('eventData', $response->output(new Document([ 'sessions' => $sessions, 'sum' => count($sessions), ]), Response::MODEL_SESSION_LIST)) @@ -1369,7 +1369,7 @@ App::post('/v1/account/recovery') /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ - /** @var Appwrite\Database\Document $project */ + /** @var Utopia\Database\Document $project */ /** @var Utopia\Locale\Locale $locale */ /** @var Appwrite\Event\Event $mails */ /** @var Appwrite\Event\Event $audits */ @@ -1443,7 +1443,7 @@ App::post('/v1/account/recovery') $events ->setParam('eventData', - $response->output2($recovery->setAttribute('secret', $secret), + $response->output($recovery->setAttribute('secret', $secret), Response::MODEL_TOKEN )) ; @@ -1459,7 +1459,7 @@ App::post('/v1/account/recovery') ; $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($recovery, Response::MODEL_TOKEN); + $response->dynamic($recovery, Response::MODEL_TOKEN); }); App::put('/v1/account/recovery') @@ -1533,7 +1533,7 @@ App::put('/v1/account/recovery') ->setParam('resource', 'users/'.$profile->getId()) ; - $response->dynamic2($recovery, Response::MODEL_TOKEN); + $response->dynamic($recovery, Response::MODEL_TOKEN); }); App::post('/v1/account/verification') @@ -1563,7 +1563,7 @@ App::post('/v1/account/verification') ->action(function ($url, $request, $response, $project, $user, $dbForInternal, $locale, $audits, $events, $mails) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ - /** @var Appwrite\Database\Document $project */ + /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Locale\Locale $locale */ @@ -1629,7 +1629,7 @@ App::post('/v1/account/verification') $events ->setParam('eventData', - $response->output2($verification->setAttribute('secret', $verificationSecret), + $response->output($verification->setAttribute('secret', $verificationSecret), Response::MODEL_TOKEN )) ; @@ -1645,7 +1645,7 @@ App::post('/v1/account/verification') ; $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($verification, Response::MODEL_TOKEN); + $response->dynamic($verification, Response::MODEL_TOKEN); }); App::put('/v1/account/verification') @@ -1710,5 +1710,5 @@ App::put('/v1/account/verification') ->setParam('resource', 'users/'.$user->getId()) ; - $response->dynamic2($verification, Response::MODEL_TOKEN); + $response->dynamic($verification, Response::MODEL_TOKEN); }); diff --git a/app/controllers/api/avatars.php b/app/controllers/api/avatars.php index 2b6951295e..13f335f4f4 100644 --- a/app/controllers/api/avatars.php +++ b/app/controllers/api/avatars.php @@ -424,7 +424,7 @@ App::get('/v1/avatars/initials') ->inject('user') ->action(function ($name, $width, $height, $color, $background, $response, $user) { /** @var Appwrite\Utopia\Response $response */ - /** @var Appwrite\Database\Document $user */ + /** @var Utopia\Database\Document $user */ $themes = [ ['color' => '#27005e', 'background' => '#e1d2f6'], // VIOLET diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 92a4f802f7..4fcf64ee1f 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -67,7 +67,7 @@ App::post('/v1/database/collections') ; $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($collection, Response::MODEL_COLLECTION); + $response->dynamic($collection, Response::MODEL_COLLECTION); }); App::get('/v1/database/collections') @@ -93,7 +93,7 @@ App::get('/v1/database/collections') $queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, [$search])] : []; - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'collections' => $dbForExternal->find(Database::COLLECTIONS, $queries, $limit, $offset, ['_id'], [$orderType]), 'sum' => $dbForExternal->count(Database::COLLECTIONS, $queries, APP_LIMIT_COUNT), ]), Response::MODEL_COLLECTION_LIST); @@ -123,7 +123,7 @@ App::get('/v1/database/collections/:collectionId') throw new Exception('Collection not found', 404); } - $response->dynamic2($collection, Response::MODEL_COLLECTION); + $response->dynamic($collection, Response::MODEL_COLLECTION); }); App::put('/v1/database/collections/:collectionId') @@ -177,7 +177,7 @@ App::put('/v1/database/collections/:collectionId') ->setParam('data', $collection->getArrayCopy()) ; - $response->dynamic2($collection, Response::MODEL_COLLECTION); + $response->dynamic($collection, Response::MODEL_COLLECTION); }); App::delete('/v1/database/collections/:collectionId') @@ -212,7 +212,7 @@ App::delete('/v1/database/collections/:collectionId') $dbForExternal->deleteCollection($collectionId); $events - ->setParam('eventData', $response->output2($collection, Response::MODEL_COLLECTION)) + ->setParam('eventData', $response->output($collection, Response::MODEL_COLLECTION)) ; $audits @@ -296,7 +296,7 @@ App::post('/v1/database/collections/:collectionId/attributes') ; $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($attribute, Response::MODEL_ATTRIBUTE); + $response->dynamic($attribute, Response::MODEL_ATTRIBUTE); }); App::get('/v1/database/collections/:collectionId/attributes') @@ -331,7 +331,7 @@ App::get('/v1/database/collections/:collectionId/attributes') ])]); }, $attributes); - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'sum' => \count($attributes), 'attributes' => $attributes ]), Response::MODEL_ATTRIBUTE_LIST); @@ -375,7 +375,7 @@ App::get('/v1/database/collections/:collectionId/attributes/:attributeId') 'collectionId' => $collectionId, ])]); - $response->dynamic2($attribute, Response::MODEL_ATTRIBUTE); + $response->dynamic($attribute, Response::MODEL_ATTRIBUTE); }); App::delete('/v1/database/collections/:collectionId/attributes/:attributeId') @@ -428,7 +428,7 @@ App::delete('/v1/database/collections/:collectionId/attributes/:attributeId') ; $events - ->setParam('payload', $response->output2($attribute, Response::MODEL_ATTRIBUTE)) + ->setParam('payload', $response->output($attribute, Response::MODEL_ATTRIBUTE)) ; $audits @@ -526,7 +526,7 @@ App::post('/v1/database/collections/:collectionId/indexes') ; $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($index, Response::MODEL_INDEX); + $response->dynamic($index, Response::MODEL_INDEX); }); @@ -562,7 +562,7 @@ App::get('/v1/database/collections/:collectionId/indexes') ])]); }, $indexes); - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'sum' => \count($indexes), 'attributes' => $indexes, ]), Response::MODEL_INDEX_LIST); @@ -606,7 +606,7 @@ App::get('/v1/database/collections/:collectionId/indexes/:indexId') 'collectionId' => $collectionId, ])]); - $response->dynamic2($index, Response::MODEL_INDEX); + $response->dynamic($index, Response::MODEL_INDEX); }); App::delete('/v1/database/collections/:collectionId/indexes/:indexId') @@ -659,7 +659,7 @@ App::delete('/v1/database/collections/:collectionId/indexes/:indexId') ; $events - ->setParam('payload', $response->output2($index, Response::MODEL_INDEX)) + ->setParam('payload', $response->output($index, Response::MODEL_INDEX)) ; $audits @@ -731,7 +731,7 @@ App::post('/v1/database/collections/:collectionId/documents') ; $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($document, Response::MODEL_DOCUMENT); + $response->dynamic($document, Response::MODEL_DOCUMENT); }); App::get('/v1/database/collections/:collectionId/documents') @@ -782,7 +782,7 @@ App::get('/v1/database/collections/:collectionId/documents') $documents = $dbForExternal->find($collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes); - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'sum' => \count($documents), 'documents' => $documents, ]), Response::MODEL_DOCUMENT_LIST); @@ -819,7 +819,7 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId') throw new Exception('No document found', 404); } - $response->dynamic2($document, Response::MODEL_DOCUMENT); + $response->dynamic($document, Response::MODEL_DOCUMENT); }); App::patch('/v1/database/collections/:collectionId/documents/:documentId') @@ -890,7 +890,7 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId') ->setParam('data', $document->getArrayCopy()) ; - $response->dynamic2($document, Response::MODEL_DOCUMENT); + $response->dynamic($document, Response::MODEL_DOCUMENT); }); App::delete('/v1/database/collections/:collectionId/documents/:documentId') @@ -931,7 +931,7 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId') $success = $dbForExternal->deleteDocument($collectionId, $documentId); $events - ->setParam('eventData', $response->output2($document, Response::MODEL_DOCUMENT)) + ->setParam('eventData', $response->output($document, Response::MODEL_DOCUMENT)) ; $audits diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index fe2fc39127..8d2f28a87a 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -2,7 +2,7 @@ use Ahc\Jwt\JWT; use Appwrite\Auth\Auth; -use Appwrite\Database\Validator\UID; +use Utopia\Database\Validator\UID; use Utopia\Storage\Storage; use Utopia\Storage\Validator\File; use Utopia\Storage\Validator\FileExt; @@ -68,7 +68,7 @@ App::post('/v1/functions') ])); $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($function, Response::MODEL_FUNCTION); + $response->dynamic($function, Response::MODEL_FUNCTION); }); App::get('/v1/functions') @@ -94,7 +94,7 @@ App::get('/v1/functions') $queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, [$search])] : []; - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'functions' => $dbForInternal->find('functions', $queries, $limit, $offset, ['_id'], [$orderType]), 'sum' => $dbForInternal->count('functions', $queries, APP_LIMIT_COUNT), ]), Response::MODEL_FUNCTION_LIST); @@ -124,7 +124,7 @@ App::get('/v1/functions/:functionId') throw new Exception('Function not found', 404); } - $response->dynamic2($function, Response::MODEL_FUNCTION); + $response->dynamic($function, Response::MODEL_FUNCTION); }); App::get('/v1/functions/:functionId/usage') @@ -142,7 +142,7 @@ App::get('/v1/functions/:functionId/usage') ->inject('register') ->action(function ($functionId, $range, $response, $project, $dbForInternal, $register) { /** @var Appwrite\Utopia\Response $response */ - /** @var Appwrite\Database\Document $project */ + /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Registry\Registry $register */ @@ -272,7 +272,7 @@ App::put('/v1/functions/:functionId') ->action(function ($functionId, $name, $execute, $vars, $events, $schedule, $timeout, $response, $dbForInternal, $project) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ - /** @var Appwrite\Database\Document $project */ + /** @var Utopia\Database\Document $project */ $function = $dbForInternal->getDocument('functions', $functionId); @@ -305,7 +305,7 @@ App::put('/v1/functions/:functionId') ]); // Async task rescheduale } - $response->dynamic2($function, Response::MODEL_FUNCTION); + $response->dynamic($function, Response::MODEL_FUNCTION); }); App::patch('/v1/functions/:functionId/tag') @@ -328,7 +328,7 @@ App::patch('/v1/functions/:functionId/tag') ->action(function ($functionId, $tag, $response, $dbForInternal, $project) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ - /** @var Appwrite\Database\Document $project */ + /** @var Utopia\Database\Document $project */ $function = $dbForInternal->getDocument('functions', $functionId); $tag = $dbForInternal->getDocument('tags', $tag); @@ -360,7 +360,7 @@ App::patch('/v1/functions/:functionId/tag') ]); // Async task rescheduale } - $response->dynamic2($function, Response::MODEL_FUNCTION); + $response->dynamic($function, Response::MODEL_FUNCTION); }); App::delete('/v1/functions/:functionId') @@ -484,7 +484,7 @@ App::post('/v1/functions/:functionId/tags') ; $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($tag, Response::MODEL_TAG); + $response->dynamic($tag, Response::MODEL_TAG); }); App::get('/v1/functions/:functionId/tags') @@ -520,7 +520,7 @@ App::get('/v1/functions/:functionId/tags') $results = $dbForInternal->find('tags', $queries, $limit, $offset, ['_id'], [$orderType]); $sum = $dbForInternal->count('tags', $queries, APP_LIMIT_COUNT); - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'tags' => $results, 'sum' => $sum, ]), Response::MODEL_TAG_LIST); @@ -561,7 +561,7 @@ App::get('/v1/functions/:functionId/tags/:tagId') throw new Exception('Tag not found', 404); } - $response->dynamic2($tag, Response::MODEL_TAG); + $response->dynamic($tag, Response::MODEL_TAG); }); App::delete('/v1/functions/:functionId/tags/:tagId') @@ -645,9 +645,9 @@ App::post('/v1/functions/:functionId/executions') ->inject('user') ->action(function ($functionId, $data, /*$async,*/ $response, $project, $dbForInternal, $user) { /** @var Appwrite\Utopia\Response $response */ - /** @var Appwrite\Database\Document $project */ + /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Database $dbForInternal */ - /** @var Appwrite\Database\Document $user */ + /** @var Utopia\Database\Document $user */ Authorization::disable(); @@ -696,20 +696,20 @@ App::post('/v1/functions/:functionId/executions') $jwt = ''; // initialize if (!$user->isEmpty()) { // If userId exists, generate a JWT for function - $tokens = $user->getAttribute('tokens', []); - $session = new Document(); + $sessions = $user->getAttribute('sessions', []); + $current = new Document(); - foreach ($tokens as $token) { /** @var Appwrite\Database\Document $token */ - if ($token->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too - $session = $token; + foreach ($sessions as $session) { /** @var Utopia\Database\Document $session */ + if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too + $current = $session; } } - if(!$session->isEmpty()) { + if(!$current->isEmpty()) { $jwtObj = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 900, 10); // Instantiate with key, algo, maxAge and leeway. $jwt = $jwtObj->encode([ 'userId' => $user->getId(), - 'sessionId' => $session->getId(), + 'sessionId' => $current->getId(), ]); } } @@ -726,7 +726,7 @@ App::post('/v1/functions/:functionId/executions') ]); $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($execution, Response::MODEL_EXECUTION); + $response->dynamic($execution, Response::MODEL_EXECUTION); }); App::get('/v1/functions/:functionId/executions') @@ -765,7 +765,7 @@ App::get('/v1/functions/:functionId/executions') new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]), ], APP_LIMIT_COUNT); - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'executions' => $results, 'sum' => $sum, ]), Response::MODEL_EXECUTION_LIST); @@ -808,5 +808,5 @@ App::get('/v1/functions/:functionId/executions/:executionId') throw new Exception('Execution not found', 404); } - $response->dynamic2($execution, Response::MODEL_EXECUTION); + $response->dynamic($execution, Response::MODEL_EXECUTION); }); diff --git a/app/controllers/api/locale.php b/app/controllers/api/locale.php index 0494789180..a1f9c1035b 100644 --- a/app/controllers/api/locale.php +++ b/app/controllers/api/locale.php @@ -1,6 +1,6 @@ createNamespace($project->getId()); $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($project, Response::MODEL_PROJECT); + $response->dynamic($project, Response::MODEL_PROJECT); }); App::get('/v1/projects') @@ -162,7 +162,7 @@ App::get('/v1/projects') $results = $dbForConsole->find('projects', $queries, $limit, $offset, ['_id'], [$orderType]); $sum = $dbForConsole->count('projects', $queries, APP_LIMIT_COUNT); - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'projects' => $results, 'sum' => $sum, ]), Response::MODEL_PROJECT_LIST); @@ -191,7 +191,7 @@ App::get('/v1/projects/:projectId') throw new Exception('Project not found', 404); } - $response->dynamic2($project, Response::MODEL_PROJECT); + $response->dynamic($project, Response::MODEL_PROJECT); }); App::get('/v1/projects/:projectId/usage') @@ -440,7 +440,7 @@ App::patch('/v1/projects/:projectId') ->setAttribute('legalTaxId', $legalTaxId) ); - $response->dynamic2($project, Response::MODEL_PROJECT); + $response->dynamic($project, Response::MODEL_PROJECT); }); App::patch('/v1/projects/:projectId/oauth2') @@ -474,7 +474,7 @@ App::patch('/v1/projects/:projectId/oauth2') ->setAttribute('usersOauth2' . \ucfirst($provider) . 'Secret', $secret) ); - $response->dynamic2($project, Response::MODEL_PROJECT); + $response->dynamic($project, Response::MODEL_PROJECT); }); App::patch('/v1/projects/:projectId/auth/limit') @@ -505,7 +505,7 @@ App::patch('/v1/projects/:projectId/auth/limit') ->setAttribute('usersAuthLimit', $limit) ); - $response->dynamic2($project, Response::MODEL_PROJECT); + $response->dynamic($project, Response::MODEL_PROJECT); }); App::patch('/v1/projects/:projectId/auth/:method') @@ -540,7 +540,7 @@ App::patch('/v1/projects/:projectId/auth/:method') ->setAttribute($authKey, $status) ); - $response->dynamic2($project, Response::MODEL_PROJECT); + $response->dynamic($project, Response::MODEL_PROJECT); }); App::delete('/v1/projects/:projectId') @@ -638,7 +638,7 @@ App::post('/v1/projects/:projectId/webhooks') ); $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($webhook, Response::MODEL_WEBHOOK); + $response->dynamic($webhook, Response::MODEL_WEBHOOK); }); App::get('/v1/projects/:projectId/webhooks') @@ -666,7 +666,7 @@ App::get('/v1/projects/:projectId/webhooks') $webhooks = $project->getAttribute('webhooks', []); - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'webhooks' => $webhooks, 'sum' => count($webhooks), ]), Response::MODEL_WEBHOOK_LIST); @@ -702,7 +702,7 @@ App::get('/v1/projects/:projectId/webhooks/:webhookId') throw new Exception('Webhook not found', 404); } - $response->dynamic2($webhook, Response::MODEL_WEBHOOK); + $response->dynamic($webhook, Response::MODEL_WEBHOOK); }); App::put('/v1/projects/:projectId/webhooks/:webhookId') @@ -754,7 +754,7 @@ App::put('/v1/projects/:projectId/webhooks/:webhookId') $dbForConsole->updateDocument('projects', $project->getId(), $project); - $response->dynamic2($webhook, Response::MODEL_WEBHOOK); + $response->dynamic($webhook, Response::MODEL_WEBHOOK); }); App::delete('/v1/projects/:projectId/webhooks/:webhookId') @@ -828,7 +828,7 @@ App::post('/v1/projects/:projectId/keys') ); $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($key, Response::MODEL_KEY); + $response->dynamic($key, Response::MODEL_KEY); }); App::get('/v1/projects/:projectId/keys') @@ -856,7 +856,7 @@ App::get('/v1/projects/:projectId/keys') $keys = $project->getAttribute('keys', []); - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'keys' => $keys, 'sum' => count($keys), ]), Response::MODEL_KEY_LIST); @@ -889,7 +889,7 @@ App::get('/v1/projects/:projectId/keys/:keyId') throw new Exception('Key not found', 404); } - $response->dynamic2($key, Response::MODEL_KEY); + $response->dynamic($key, Response::MODEL_KEY); }); App::put('/v1/projects/:projectId/keys/:keyId') @@ -931,7 +931,7 @@ App::put('/v1/projects/:projectId/keys/:keyId') $dbForConsole->updateDocument('projects', $project->getId(), $project); - $response->dynamic2($key, Response::MODEL_KEY); + $response->dynamic($key, Response::MODEL_KEY); }); App::delete('/v1/projects/:projectId/keys/:keyId') @@ -1032,7 +1032,7 @@ App::post('/v1/projects/:projectId/tasks') } $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($task, Response::MODEL_TASK); + $response->dynamic($task, Response::MODEL_TASK); }); App::get('/v1/projects/:projectId/tasks') @@ -1060,7 +1060,7 @@ App::get('/v1/projects/:projectId/tasks') $tasks = $project->getAttribute('tasks', []); - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'tasks' => $tasks, 'sum' => count($tasks), ]), Response::MODEL_TASK_LIST); @@ -1097,7 +1097,7 @@ App::get('/v1/projects/:projectId/tasks/:taskId') throw new Exception('Task not found', 404); } - $response->dynamic2($task, Response::MODEL_TASK); + $response->dynamic($task, Response::MODEL_TASK); }); App::put('/v1/projects/:projectId/tasks/:taskId') @@ -1163,7 +1163,7 @@ App::put('/v1/projects/:projectId/tasks/:taskId') ResqueScheduler::enqueueAt($next, 'v1-tasks', 'TasksV1', $task->getArrayCopy()); } - $response->dynamic2($task, Response::MODEL_TASK); + $response->dynamic($task, Response::MODEL_TASK); }); App::delete('/v1/projects/:projectId/tasks/:taskId') @@ -1244,7 +1244,7 @@ App::post('/v1/projects/:projectId/platforms') ); $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($platform, Response::MODEL_PLATFORM); + $response->dynamic($platform, Response::MODEL_PLATFORM); }); App::get('/v1/projects/:projectId/platforms') @@ -1272,7 +1272,7 @@ App::get('/v1/projects/:projectId/platforms') $platforms = $project->getAttribute('platforms', []); - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'platforms' => $platforms, 'sum' => count($platforms), ]), Response::MODEL_PLATFORM_LIST); @@ -1308,7 +1308,7 @@ App::get('/v1/projects/:projectId/platforms/:platformId') throw new Exception('Platform not found', 404); } - $response->dynamic2($platform, Response::MODEL_PLATFORM); + $response->dynamic($platform, Response::MODEL_PLATFORM); }); App::put('/v1/projects/:projectId/platforms/:platformId') @@ -1363,7 +1363,7 @@ App::put('/v1/projects/:projectId/platforms/:platformId') $dbForConsole->updateDocument('projects', $project->getId(), $project); - $response->dynamic2($platform, Response::MODEL_PLATFORM); + $response->dynamic($platform, Response::MODEL_PLATFORM); }); App::delete('/v1/projects/:projectId/platforms/:platformId') @@ -1453,7 +1453,7 @@ App::post('/v1/projects/:projectId/domains') ); $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($domain, Response::MODEL_DOMAIN); + $response->dynamic($domain, Response::MODEL_DOMAIN); }); App::get('/v1/projects/:projectId/domains') @@ -1481,7 +1481,7 @@ App::get('/v1/projects/:projectId/domains') $domains = $project->getAttribute('domains', []); - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'domains' => $domains, 'sum' => count($domains), ]), Response::MODEL_DOMAIN_LIST); @@ -1517,7 +1517,7 @@ App::get('/v1/projects/:projectId/domains/:domainId') throw new Exception('Domain not found', 404); } - $response->dynamic2($domain, Response::MODEL_DOMAIN); + $response->dynamic($domain, Response::MODEL_DOMAIN); }); App::patch('/v1/projects/:projectId/domains/:domainId/verification') @@ -1557,7 +1557,7 @@ App::patch('/v1/projects/:projectId/domains/:domainId/verification') } if ($domain->getAttribute('verification') === true) { - return $response->dynamic2($domain, Response::MODEL_DOMAIN); + return $response->dynamic($domain, Response::MODEL_DOMAIN); } $validator = new CNAME($target->get()); // Verify Domain with DNS records @@ -1578,7 +1578,7 @@ App::patch('/v1/projects/:projectId/domains/:domainId/verification') 'domain' => $domain->getAttribute('domain'), ]); - $response->dynamic2($domain, Response::MODEL_DOMAIN); + $response->dynamic($domain, Response::MODEL_DOMAIN); }); App::delete('/v1/projects/:projectId/domains/:domainId') diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 45a7078a4c..71c49d61a7 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -1,7 +1,6 @@ setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($data, Response::MODEL_BUCKET); + $response->dynamic($data, Response::MODEL_BUCKET); }); App::get('/v1/storage/buckets') @@ -104,7 +104,7 @@ App::get('/v1/storage/buckets') $queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, $search)] : []; - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'buckets' => $dbForInternal->find('buckets', $queries, $limit, $offset, ['_id'], [$orderType]), 'sum' => $dbForInternal->count('buckets', $queries, APP_LIMIT_COUNT), ]), Response::MODEL_BUCKET_LIST); @@ -134,7 +134,7 @@ App::get('/v1/storage/buckets/:bucketId') throw new Exception('Bucket not found', 404); } - $response->dynamic2($bucket, Response::MODEL_BUCKET); + $response->dynamic($bucket, Response::MODEL_BUCKET); }); App::put('/v1/storage/buckets/:bucketId') @@ -192,7 +192,7 @@ App::put('/v1/storage/buckets/:bucketId') ->setParam('data', $bucket->getArrayCopy()) ; - $response->dynamic2($bucket, Response::MODEL_BUCKET); + $response->dynamic($bucket, Response::MODEL_BUCKET); }); App::delete('/v1/storage/buckets/:bucketId') @@ -235,7 +235,7 @@ App::delete('/v1/storage/buckets/:bucketId') } $events - ->setParam('eventData', $response->output2($bucket, Response::MODEL_BUCKET)) + ->setParam('eventData', $response->output($bucket, Response::MODEL_BUCKET)) ; $audits @@ -276,7 +276,7 @@ App::post('/v1/storage/buckets/:bucketId/files') /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ - /** @var Appwrite\Database\Document $user */ + /** @var Utopia\Database\Document $user */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $usage */ @@ -492,7 +492,8 @@ App::post('/v1/storage/buckets/:bucketId/files') } $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($file, Response::MODEL_FILE); + $response->dynamic($file, Response::MODEL_FILE); + ; }); App::get('/v1/storage/buckets/:bucketId/files') @@ -530,7 +531,7 @@ App::get('/v1/storage/buckets/:bucketId/files') $queries[] = [new Query('name', Query::TYPE_SEARCH, [$search])]; } - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'files' => $dbForInternal->find('files', $queries, $limit, $offset, ['_id'], [$orderType]), 'sum' => $dbForInternal->count('files', $queries, APP_LIMIT_COUNT), ]), Response::MODEL_FILE_LIST); @@ -568,7 +569,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId') throw new Exception('File not found', 404); } - $response->dynamic2($file, Response::MODEL_FILE); + $response->dynamic($file, Response::MODEL_FILE); }); App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') @@ -957,7 +958,7 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId') ->setParam('resource', 'storage/files/' . $file->getId()) ; - $response->dynamic2($file, Response::MODEL_FILE); + $response->dynamic($file, Response::MODEL_FILE); }); App::delete('/v1/storage/buckets/:bucketId/files/:fileId') @@ -1018,7 +1019,7 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId') ; $events - ->setParam('eventData', $response->output2($file, Response::MODEL_FILE)) + ->setParam('eventData', $response->output($file, Response::MODEL_FILE)) ; $response->noContent(); diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 5ad8ecd6c3..4e82260343 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -1,7 +1,6 @@ desc('Create Team') @@ -80,7 +80,7 @@ App::post('/v1/teams') } $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($team, Response::MODEL_TEAM); + $response->dynamic($team, Response::MODEL_TEAM); }); App::get('/v1/teams') @@ -109,7 +109,7 @@ App::get('/v1/teams') $results = $dbForInternal->find('teams', $queries, $limit, $offset, ['_id'], [$orderType]); $sum = $dbForInternal->count('teams', $queries, APP_LIMIT_COUNT); - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'teams' => $results, 'sum' => $sum, ]), Response::MODEL_TEAM_LIST); @@ -139,7 +139,7 @@ App::get('/v1/teams/:teamId') throw new Exception('Team not found', 404); } - $response->dynamic2($team, Response::MODEL_TEAM); + $response->dynamic($team, Response::MODEL_TEAM); }); App::put('/v1/teams/:teamId') @@ -170,7 +170,7 @@ App::put('/v1/teams/:teamId') $team = $dbForInternal->updateDocument('teams', $team->getId(), $team->setAttribute('name', $name)); - $response->dynamic2($team, Response::MODEL_TEAM); + $response->dynamic($team, Response::MODEL_TEAM); }); App::delete('/v1/teams/:teamId') @@ -222,7 +222,7 @@ App::delete('/v1/teams/:teamId') ; $events - ->setParam('eventData', $response->output2($team, Response::MODEL_TEAM)) + ->setParam('eventData', $response->output($team, Response::MODEL_TEAM)) ; $response->noContent(); @@ -256,8 +256,8 @@ App::post('/v1/teams/:teamId/memberships') ->inject('mails') ->action(function ($teamId, $email, $name, $roles, $url, $response, $project, $user, $dbForInternal, $locale, $audits, $mails) { /** @var Appwrite\Utopia\Response $response */ - /** @var Appwrite\Database\Document $project */ - /** @var Appwrite\Database\Document $user */ + /** @var Utopia\Database\Document $project */ + /** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Database $dbForInternal */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $mails */ @@ -409,7 +409,7 @@ App::post('/v1/teams/:teamId/memberships') ; $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($membership + $response->dynamic($membership ->setAttribute('email', $email) ->setAttribute('name', $name) , Response::MODEL_MEMBERSHIP); @@ -457,7 +457,7 @@ App::get('/v1/teams/:teamId/memberships') $users[] = new Document(\array_merge($temp, $membership->getArrayCopy())); } - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'memberships' => $users, 'sum' => $sum, ]), Response::MODEL_MEMBERSHIP_LIST); @@ -486,7 +486,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId') ->action(function ($teamId, $membershipId, $roles, $request, $response, $user, $dbForInternal, $audits) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ - /** @var Appwrite\Database\Document $user */ + /** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Database $dbForInternal */ /** @var Appwrite\Event\Event $audits */ @@ -525,7 +525,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId') ->setParam('resource', 'teams/'.$teamId) ; - $response->dynamic2($membership, Response::MODEL_MEMBERSHIP); + $response->dynamic($membership, Response::MODEL_MEMBERSHIP); }); App::patch('/v1/teams/:teamId/memberships/:membershipId/status') @@ -553,7 +553,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status') ->action(function ($teamId, $membershipId, $userId, $secret, $request, $response, $user, $dbForInternal, $geodb, $audits) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ - /** @var Appwrite\Database\Document $user */ + /** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Database $dbForInternal */ /** @var MaxMind\Db\Reader $geodb */ /** @var Appwrite\Event\Event $audits */ @@ -661,7 +661,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status') ->addCookie(Auth::$cookieName, Auth::encodeSession($user->getId(), $secret), $expiry, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, Config::getParam('cookieSamesite')) ; - $response->dynamic2($membership + $response->dynamic($membership ->setAttribute('email', $user->getAttribute('email')) ->setAttribute('name', $user->getAttribute('name')) , Response::MODEL_MEMBERSHIP); @@ -744,7 +744,7 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId') ; $events - ->setParam('eventData', $response->output2($membership, Response::MODEL_MEMBERSHIP)) + ->setParam('eventData', $response->output($membership, Response::MODEL_MEMBERSHIP)) ; $response->noContent(); diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 8a1be03744..2abbc5b50a 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -65,7 +65,7 @@ App::post('/v1/users') } $response->setStatusCode(Response::STATUS_CODE_CREATED); - $response->dynamic2($user, Response::MODEL_USER); + $response->dynamic($user, Response::MODEL_USER); }); App::get('/v1/users') @@ -92,7 +92,7 @@ App::get('/v1/users') $results = $dbForInternal->find('users', [], $limit, $offset, ['_id'], [$orderType]); $sum = $dbForInternal->count('users', [], APP_LIMIT_COUNT); - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'users' => $results, 'sum' => $sum, ]), Response::MODEL_USER_LIST); @@ -122,7 +122,7 @@ App::get('/v1/users/:userId') throw new Exception('User not found', 404); } - $response->dynamic2($user, Response::MODEL_USER); + $response->dynamic($user, Response::MODEL_USER); }); App::get('/v1/users/:userId/prefs') @@ -151,7 +151,7 @@ App::get('/v1/users/:userId/prefs') $prefs = $user->getAttribute('prefs', new \stdClass()); - $response->dynamic2(new Document($prefs), Response::MODEL_PREFERENCES); + $response->dynamic(new Document($prefs), Response::MODEL_PREFERENCES); }); App::get('/v1/users/:userId/sessions') @@ -194,7 +194,7 @@ App::get('/v1/users/:userId/sessions') $sessions[$key] = $session; } - $response->dynamic2(new Document([ + $response->dynamic(new Document([ 'sessions' => $sessions, 'sum' => count($sessions), ]), Response::MODEL_SESSION_LIST); @@ -218,7 +218,7 @@ App::get('/v1/users/:userId/logs') ->inject('geodb') ->action(function ($userId, $response, $dbForInternal, $locale, $geodb) { /** @var Appwrite\Utopia\Response $response */ - /** @var Appwrite\Database\Document $project */ + /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Locale\Locale $locale */ /** @var MaxMind\Db\Reader $geodb */ @@ -305,7 +305,7 @@ App::get('/v1/users/:userId/logs') } } - $response->dynamic2(new Document(['logs' => $output]), Response::MODEL_LOG_LIST); + $response->dynamic(new Document(['logs' => $output]), Response::MODEL_LOG_LIST); }); App::patch('/v1/users/:userId/status') @@ -336,7 +336,7 @@ App::patch('/v1/users/:userId/status') $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('status', (bool) $status)); - $response->dynamic2($user, Response::MODEL_USER); + $response->dynamic($user, Response::MODEL_USER); }); App::patch('/v1/users/:userId/verification') @@ -367,7 +367,7 @@ App::patch('/v1/users/:userId/verification') $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('emailVerification', $emailVerification)); - $response->dynamic2($user, Response::MODEL_USER); + $response->dynamic($user, Response::MODEL_USER); }); App::patch('/v1/users/:userId/prefs') @@ -398,7 +398,7 @@ App::patch('/v1/users/:userId/prefs') $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('prefs', $prefs)); - $response->dynamic2(new Document($prefs), Response::MODEL_PREFERENCES); + $response->dynamic(new Document($prefs), Response::MODEL_PREFERENCES); }); App::delete('/v1/users/:userId/sessions/:sessionId') @@ -440,7 +440,7 @@ App::delete('/v1/users/:userId/sessions/:sessionId') $user->setAttribute('sessions', $sessions); $events - ->setParam('eventData', $response->output2($user, Response::MODEL_USER)) + ->setParam('eventData', $response->output($user, Response::MODEL_USER)) ; $dbForInternal->updateDocument('users', $user->getId(), $user); @@ -486,7 +486,7 @@ App::delete('/v1/users/:userId/sessions') $dbForInternal->updateDocument('users', $user->getId(), $user->getAttribute('sessions', [])); $events - ->setParam('eventData', $response->output2($user, Response::MODEL_USER)) + ->setParam('eventData', $response->output($user, Response::MODEL_USER)) ; $response->noContent(); @@ -535,7 +535,7 @@ App::delete('/v1/users/:userId') ; $events - ->setParam('eventData', $response->output2($user, Response::MODEL_USER)) + ->setParam('eventData', $response->output($user, Response::MODEL_USER)) ; // TODO : Response filter implementation diff --git a/app/controllers/general.php b/app/controllers/general.php index d8f24019f8..46bd81689d 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -10,16 +10,14 @@ use Utopia\Exception; use Utopia\Config\Config; use Utopia\Domains\Domain; use Appwrite\Auth\Auth; -use Appwrite\Database\Validator\Authorization; use Appwrite\Network\Validator\Origin; use Appwrite\Utopia\Response\Filters\V06; use Appwrite\Utopia\Response\Filters\V07; use Appwrite\Utopia\Response\Filters\V08; use Utopia\CLI\Console; -use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Query; -use Utopia\Database\Validator\Authorization as Authorization2; +use Utopia\Database\Validator\Authorization; Config::setParam('domainVerification', false); Config::setParam('cookieDomain', 'localhost'); @@ -44,7 +42,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons $domains[$domain->get()] = false; Console::warning($domain->get() . ' is not a publicly accessible domain. Skipping SSL certificate generation.'); } else { - Authorization2::disable(); + Authorization::disable(); $certificate = $dbForConsole->findFirst('certificates', [ new Query('domain', QUERY::TYPE_EQUAL, [$domain->get()]) @@ -55,7 +53,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons 'domain' => $domain->get(), ]); $certificate = $dbForConsole->createDocument('certificates', $certificate); - Authorization2::enable(); + Authorization::enable(); Console::info('Issuing a TLS certificate for the master domain (' . $domain->get() . ') in a few seconds...'); @@ -66,7 +64,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons 'validateCNAME' => false, ]); } else { - Authorization2::enable(); // ensure authorization is reenabled + Authorization::enable(); // ensure authorization is reenabled } $domains[$domain->get()] = true; } @@ -239,26 +237,21 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons $scopes = \array_merge($roles[$role]['scopes'], $key->getAttribute('scopes', [])); Authorization::setDefaultStatus(false); // Cancel security segmentation for API keys. - Authorization2::setDefaultStatus(false); // Cancel security segmentation for API keys. } } if ($user->getId()) { Authorization::setRole('user:'.$user->getId()); - Authorization2::setRole('user:'.$user->getId()); } Authorization::setRole('role:'.$role); - Authorization2::setRole('role:'.$role); \array_map(function ($node) { if (isset($node['teamId']) && isset($node['roles'])) { Authorization::setRole('team:'.$node['teamId']); - Authorization2::setRole('team:'.$node['teamId']); foreach ($node['roles'] as $nodeRole) { // Set all team roles Authorization::setRole('team:'.$node['teamId'].'/'.$nodeRole); - Authorization2::setRole('team:'.$node['teamId'].'/'.$nodeRole); } } }, $user->getAttribute('memberships', [])); @@ -305,7 +298,7 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\View $layout */ - /** @var Appwrite\Database\Document $project */ + /** @var Utopia\Database\Document $project */ if ($error instanceof PDOException) { throw $error; @@ -393,7 +386,7 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) { $response->html($layout->render()); } - $response->dynamic2(new Document($output), + $response->dynamic(new Document($output), $utopia->isDevelopment() ? Response::MODEL_ERROR_DEV : Response::MODEL_ERROR); }, ['error', 'utopia', 'request', 'response', 'layout', 'project']); diff --git a/app/controllers/mock.php b/app/controllers/mock.php index 17bade5793..9d4479c01f 100644 --- a/app/controllers/mock.php +++ b/app/controllers/mock.php @@ -2,7 +2,7 @@ global $utopia, $request, $response; -use Appwrite\Database\Document; +use Utopia\Database\Document; use Appwrite\Network\Validator\Host; use Appwrite\Utopia\Response; use Utopia\App; diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 24fed96611..836ef8f714 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -1,7 +1,7 @@ on('start', function (Server $http) use ($payloadSize, $register) { $app = new App('UTC'); go(function() use ($register, $app) { - $db = $register->get('dbPool')->get(); - $redis = $register->get('redisPool')->get(); + // wait for database to be ready + $attempts = 0; + $max = 10; + $sleep = 1; + + do { + try { + $attempts++; + $db = $register->get('dbPool')->get(); + $redis = $register->get('redisPool')->get(); + break; // leave the do-while if successful + } catch(\Exception $e) { + Console::warning("Database not ready. Retrying connection ({$attempts})..."); + if ($attempts >= $max) { + throw new \Exception('Failed to connect to database: '. $e->getMessage()); + } + sleep($sleep); + } + } while ($attempts < $max); App::setResource('db', function () use (&$db) { return $db; @@ -69,9 +85,6 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) { return $app; }); - // wait for database to be ready - sleep(5); - $dbForConsole = $app->getResource('dbForConsole'); /** @var Utopia\Database\Database $dbForConsole */ if(!$dbForConsole->exists()) { @@ -170,9 +183,6 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo Authorization::cleanRoles(); Authorization::setRole('role:all'); - Authorization2::cleanRoles(); - Authorization2::setRole('role:all'); - $app->run($request, $response); } catch (\Throwable $th) { Console::error('[Error] Type: '.get_class($th)); diff --git a/app/init.php b/app/init.php index ee69ce5c85..06fc9a0b63 100644 --- a/app/init.php +++ b/app/init.php @@ -24,7 +24,6 @@ use Appwrite\Database\Database; use Appwrite\Database\Adapter\MySQL as MySQLAdapter; use Appwrite\Database\Adapter\Redis as RedisAdapter; use Appwrite\Database\Document; -use Appwrite\Database\Validator\Authorization; use Appwrite\Event\Event; use Appwrite\OpenSSL\OpenSSL; use Utopia\App; @@ -39,7 +38,7 @@ use Utopia\Cache\Cache; use Utopia\Database\Adapter\MariaDB; use Utopia\Database\Document as Document2; use Utopia\Database\Database as Database2; -use Utopia\Database\Validator\Authorization as Authorization2; +use Utopia\Database\Validator\Authorization; use Swoole\Database\PDOConfig; use Swoole\Database\PDOPool; use Swoole\Database\RedisConfig; @@ -58,8 +57,8 @@ const APP_LIMIT_USERS = 10000; const APP_LIMIT_ANTIVIRUS = 20971520; //20MB const APP_LIMIT_ENCRYPTION = 20971520; //20MB const APP_LIMIT_COMPRESSION = 20971520; //20MB -const APP_CACHE_BUSTER = 149; -const APP_VERSION_STABLE = '0.9.1'; +const APP_CACHE_BUSTER = 150; +const APP_VERSION_STABLE = '0.9.2'; const APP_STORAGE_UPLOADS = '/storage/uploads'; const APP_STORAGE_FUNCTIONS = '/storage/functions'; const APP_STORAGE_CACHE = '/storage/cache'; @@ -443,7 +442,6 @@ App::setResource('user', function($mode, $project, $console, $request, $response /** @var string $mode */ Authorization::setDefaultStatus(true); - Authorization2::setDefaultStatus(true); Auth::setCookieName('a_session_'.$project->getId()); @@ -488,7 +486,6 @@ App::setResource('user', function($mode, $project, $console, $request, $response if (APP_MODE_ADMIN === $mode) { if ($user->find('teamId', $project->getAttribute('teamId'), 'memberships')) { Authorization::setDefaultStatus(false); // Cancel security segmentation for admin users. - Authorization2::setDefaultStatus(false); // Cancel security segmentation for admin users. } else { $user = new Document2(['$id' => '', '$collection' => 'users']); } @@ -533,12 +530,10 @@ App::setResource('project', function($dbForConsole, $request, $console) { } Authorization::disable(); - Authorization2::disable(); $project = $dbForConsole->getDocument('projects', $projectId); Authorization::reset(); - Authorization2::reset(); return $project; }, ['dbForConsole', 'request', 'console']); diff --git a/app/workers.php b/app/workers.php index ff5ba1dbd3..7dd48eaff8 100644 --- a/app/workers.php +++ b/app/workers.php @@ -23,10 +23,12 @@ $register->set('db', function () { return $pdo; }); + $register->set('cache', function () { // Register cache connection $redis = new Redis(); $redis->pconnect(App::getEnv('_APP_REDIS_HOST', ''), App::getEnv('_APP_REDIS_PORT', '')); $redis->setOption(Redis::OPT_READ_TIMEOUT, -1); return $redis; -}); \ No newline at end of file +}); + diff --git a/app/workers/audits.php b/app/workers/audits.php index 495c93bc48..663de3ce4f 100644 --- a/app/workers/audits.php +++ b/app/workers/audits.php @@ -2,11 +2,7 @@ use Appwrite\Resque\Worker; use Utopia\Audit\Audit; -use Utopia\Cache\Adapter\Redis; -use Utopia\Cache\Cache; use Utopia\CLI\Console; -use Utopia\Database\Adapter\MariaDB; -use Utopia\Database\Database; require_once __DIR__.'/../workers.php'; @@ -23,8 +19,6 @@ class AuditsV1 extends Worker public function run(): void { - global $register; - $projectId = $this->args['projectId']; $userId = $this->args['userId']; $event = $this->args['event']; @@ -32,12 +26,8 @@ class AuditsV1 extends Worker $userAgent = $this->args['userAgent']; $ip = $this->args['ip']; $data = $this->args['data']; - $db = $register->get('db', true); - $cache = new Cache(new Redis($register->get('cache'))); - $dbForInternal = new Database(new MariaDB($db), $cache); - $dbForInternal->setNamespace('project_'.$projectId.'_internal'); - + $dbForInternal = $this->getInternalDB($projectId); $audit = new Audit($dbForInternal); $audit->log($userId, $event, $resource, $userAgent, $ip, '', $data); diff --git a/app/workers/certificates.php b/app/workers/certificates.php index 1db2a46360..1720d6adb9 100644 --- a/app/workers/certificates.php +++ b/app/workers/certificates.php @@ -3,13 +3,9 @@ use Appwrite\Network\Validator\CNAME; use Appwrite\Resque\Worker; use Utopia\App; -use Utopia\Cache\Adapter\Redis; -use Utopia\Cache\Cache; use Utopia\CLI\Console; -use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Query; -use Utopia\Database\Adapter\MariaDB; use Utopia\Database\Validator\Authorization; use Utopia\Domains\Domain; @@ -28,180 +24,167 @@ class CertificatesV1 extends Worker public function run(): void { - global $register; + $dbForConsole = $this->getConsoleDB(); - go(function() use ($register) { - $db = $register->get('dbPool')->get(); - $redis = $register->get('redisPool')->get(); + /** + * 1. Get new domain document - DONE + * 1.1. Validate domain is valid, public suffix is known and CNAME records are verified - DONE + * 2. Check if a certificate already exists - DONE + * 3. Check if certificate is about to expire, if not - skip it + * 3.1. Create / renew certificate + * 3.2. Update loadblancer + * 3.3. Update database (domains, change date, expiry) + * 3.4. Set retry on failure + * 3.5. Schedule to renew certificate in 60 days + */ - $cache = new Cache(new Redis($redis)); - $dbForConsole = new Database(new MariaDB($db), $cache); - $dbForConsole->setNamespace('project_console_internal'); + Authorization::disable(); - /** - * 1. Get new domain document - DONE - * 1.1. Validate domain is valid, public suffix is known and CNAME records are verified - DONE - * 2. Check if a certificate already exists - DONE - * 3. Check if certificate is about to expire, if not - skip it - * 3.1. Create / renew certificate - * 3.2. Update loadblancer - * 3.3. Update database (domains, change date, expiry) - * 3.4. Set retry on failure - * 3.5. Schedule to renew certificate in 60 days - */ + // Args + $document = $this->args['document']; + $domain = $this->args['domain']; - Authorization::disable(); - - // Args - $document = $this->args['document']; - $domain = $this->args['domain']; - - // Validation Args - $validateTarget = $this->args['validateTarget'] ?? true; - $validateCNAME = $this->args['validateCNAME'] ?? true; - - // Options - $domain = new Domain((!empty($domain)) ? $domain : ''); - $expiry = 60 * 60 * 24 * 30 * 2; // 60 days - $safety = 60 * 60; // 1 hour - $renew = (\time() + $expiry); - - if(empty($domain->get())) { - throw new Exception('Missing domain'); - } - - if(!$domain->isKnown() || $domain->isTest()) { - throw new Exception('Unknown public suffix for domain'); - } - - if($validateTarget) { - $target = new Domain(App::getEnv('_APP_DOMAIN_TARGET', '')); + // Validation Args + $validateTarget = $this->args['validateTarget'] ?? true; + $validateCNAME = $this->args['validateCNAME'] ?? true; - if(!$target->isKnown() || $target->isTest()) { - throw new Exception('Unreachable CNAME target ('.$target->get().'), please use a domain with a public suffix.'); - } + // Options + $domain = new Domain((!empty($domain)) ? $domain : ''); + $expiry = 60 * 60 * 24 * 30 * 2; // 60 days + $safety = 60 * 60; // 1 hour + $renew = (\time() + $expiry); + + if(empty($domain->get())) { + throw new Exception('Missing domain'); + } + + if(!$domain->isKnown() || $domain->isTest()) { + throw new Exception('Unknown public suffix for domain'); + } + + if($validateTarget) { + $target = new Domain(App::getEnv('_APP_DOMAIN_TARGET', '')); + + if(!$target->isKnown() || $target->isTest()) { + throw new Exception('Unreachable CNAME target ('.$target->get().'), please use a domain with a public suffix.'); } + } - if($validateCNAME) { - $validator = new CNAME($target->get()); // Verify Domain with DNS records - - if(!$validator->isValid($domain->get())) { - throw new Exception('Failed to verify domain DNS records'); - } + if($validateCNAME) { + $validator = new CNAME($target->get()); // Verify Domain with DNS records + + if(!$validator->isValid($domain->get())) { + throw new Exception('Failed to verify domain DNS records'); } + } - $certificate = $dbForConsole->findFirst('certificates', [ - new Query('domain', QUERY::TYPE_EQUAL, [$domain->get()]) - ], /*limit*/ 1); + $certificate = $dbForConsole->findFirst('certificates', [ + new Query('domain', QUERY::TYPE_EQUAL, [$domain->get()]) + ], /*limit*/ 1); - // $condition = ($certificate - // && $certificate instanceof Document - // && isset($certificate['issueDate']) - // && (($certificate['issueDate'] + ($expiry)) > time())) ? 'true' : 'false'; + // $condition = ($certificate + // && $certificate instanceof Document + // && isset($certificate['issueDate']) + // && (($certificate['issueDate'] + ($expiry)) > time())) ? 'true' : 'false'; - // throw new Exception('cert issued at'.date('d.m.Y H:i', $certificate['issueDate']).' | renew date is: '.date('d.m.Y H:i', ($certificate['issueDate'] + ($expiry))).' | condition is '.$condition); + // throw new Exception('cert issued at'.date('d.m.Y H:i', $certificate['issueDate']).' | renew date is: '.date('d.m.Y H:i', ($certificate['issueDate'] + ($expiry))).' | condition is '.$condition); - $certificate = (!empty($certificate) && $certificate instanceof $certificate) ? $certificate->getArrayCopy() : []; + $certificate = (!empty($certificate) && $certificate instanceof $certificate) ? $certificate->getArrayCopy() : []; - if(!empty($certificate) - && isset($certificate['issueDate']) - && (($certificate['issueDate'] + ($expiry)) > \time())) { // Check last issue time - throw new Exception('Renew isn\'t required'); + if(!empty($certificate) + && isset($certificate['issueDate']) + && (($certificate['issueDate'] + ($expiry)) > \time())) { // Check last issue time + throw new Exception('Renew isn\'t required'); + } + + $staging = (App::isProduction()) ? '' : ' --dry-run'; + $email = App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS'); + + if(empty($email)) { + throw new Exception('You must set a valid security email address (_APP_SYSTEM_SECURITY_EMAIL_ADDRESS) to issue an SSL certificate'); + } + + $stdout = ''; + $stderr = ''; + + $exit = Console::execute("certbot certonly --webroot --noninteractive --agree-tos{$staging}" + ." --email ".$email + ." -w ".APP_STORAGE_CERTIFICATES + ." -d {$domain->get()}", '', $stdout, $stderr); + + if($exit !== 0) { + throw new Exception('Failed to issue a certificate with message: '.$stderr); + } + + $path = APP_STORAGE_CERTIFICATES.'/'.$domain->get(); + + if(!\is_readable($path)) { + if (!\mkdir($path, 0755, true)) { + throw new Exception('Failed to create path...'); } + } - $staging = (App::isProduction()) ? '' : ' --dry-run'; - $email = App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS'); + if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/cert.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/cert.pem')) { + throw new Exception('Failed to rename certificate cert.pem: '.\json_encode($stdout)); + } - if(empty($email)) { - throw new Exception('You must set a valid security email address (_APP_SYSTEM_SECURITY_EMAIL_ADDRESS) to issue an SSL certificate'); - } + if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/chain.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/chain.pem')) { + throw new Exception('Failed to rename certificate chain.pem: '.\json_encode($stdout)); + } - $stdout = ''; - $stderr = ''; + if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/fullchain.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/fullchain.pem')) { + throw new Exception('Failed to rename certificate fullchain.pem: '.\json_encode($stdout)); + } - $exit = Console::execute("certbot certonly --webroot --noninteractive --agree-tos{$staging}" - ." --email ".$email - ." -w ".APP_STORAGE_CERTIFICATES - ." -d {$domain->get()}", '', $stdout, $stderr); + if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/privkey.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/privkey.pem')) { + throw new Exception('Failed to rename certificate privkey.pem: '.\json_encode($stdout)); + } - if($exit !== 0) { - throw new Exception('Failed to issue a certificate with message: '.$stderr); - } + $certificate = new Document(\array_merge($certificate, [ + 'domain' => $domain->get(), + 'issueDate' => \time(), + 'renewDate' => $renew, + 'attempts' => 0, + 'log' => \json_encode($stdout), + ])); - $path = APP_STORAGE_CERTIFICATES.'/'.$domain->get(); + $certificate = $dbForConsole->createDocument('certificates', $certificate); - if(!\is_readable($path)) { - if (!\mkdir($path, 0755, true)) { - throw new Exception('Failed to create path...'); - } - } - - if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/cert.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/cert.pem')) { - throw new Exception('Failed to rename certificate cert.pem: '.\json_encode($stdout)); - } + if(!$certificate) { + throw new Exception('Failed saving certificate to DB'); + } - if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/chain.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/chain.pem')) { - throw new Exception('Failed to rename certificate chain.pem: '.\json_encode($stdout)); - } - - if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/fullchain.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/fullchain.pem')) { - throw new Exception('Failed to rename certificate fullchain.pem: '.\json_encode($stdout)); - } - - if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/privkey.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/privkey.pem')) { - throw new Exception('Failed to rename certificate privkey.pem: '.\json_encode($stdout)); - } - - $certificate = new Document(\array_merge($certificate, [ - 'domain' => $domain->get(), - 'issueDate' => \time(), - 'renewDate' => $renew, - 'attempts' => 0, - 'log' => \json_encode($stdout), + if(!empty($document)) { + $certificate = new Document(\array_merge($document, [ + 'updated' => \time(), + 'certificateId' => $certificate->getId(), ])); - $certificate = $dbForConsole->createDocument('certificates', $certificate); + $certificate = $dbForConsole->updateDocument('certificates', $certificate->getId(), $certificate); if(!$certificate) { - throw new Exception('Failed saving certificate to DB'); + throw new Exception('Failed saving domain to DB'); } + } - if(!empty($document)) { - $certificate = new Document(\array_merge($document, [ - 'updated' => \time(), - 'certificateId' => $certificate->getId(), - ])); - - $certificate = $dbForConsole->updateDocument('certificates', $certificate->getId(), $certificate); - - if(!$certificate) { - throw new Exception('Failed saving domain to DB'); - } - } - - $config = - "tls: - certificates: - - certFile: /storage/certificates/{$domain->get()}/fullchain.pem - keyFile: /storage/certificates/{$domain->get()}/privkey.pem"; + $config = +"tls: + certificates: + - certFile: /storage/certificates/{$domain->get()}/fullchain.pem + keyFile: /storage/certificates/{$domain->get()}/privkey.pem"; - if(!\file_put_contents(APP_STORAGE_CONFIG.'/'.$domain->get().'.yml', $config)) { - throw new Exception('Failed to save SSL configuration'); - } + if(!\file_put_contents(APP_STORAGE_CONFIG.'/'.$domain->get().'.yml', $config)) { + throw new Exception('Failed to save SSL configuration'); + } - ResqueScheduler::enqueueAt($renew + $safety, 'v1-certificates', 'CertificatesV1', [ - 'document' => [], - 'domain' => $domain->get(), - 'validateTarget' => $validateTarget, - 'validateCNAME' => $validateCNAME, - ]); // Async task rescheduale + ResqueScheduler::enqueueAt($renew + $safety, 'v1-certificates', 'CertificatesV1', [ + 'document' => [], + 'domain' => $domain->get(), + 'validateTarget' => $validateTarget, + 'validateCNAME' => $validateCNAME, + ]); // Async task rescheduale - Authorization::reset(); - - // Return db connections to pool - $register->get('dbPool')->put($db); - $register->get('redisPool')->put($redis); - }); + Authorization::reset(); } public function shutdown(): void diff --git a/app/workers/database.php b/app/workers/database.php index b024871045..544ffe1060 100644 --- a/app/workers/database.php +++ b/app/workers/database.php @@ -1,14 +1,10 @@ deleteIndex($collectionId, $id); } - - /** - * @param string $projectId - * - * @return Database - */ - protected function getInternalDB($projectId): Database - { - global $register; - - $dbForInternal = null; - - go(function() use ($register, $projectId, &$dbForInternal) { - $db = $register->get('dbPool')->get(); - $redis = $register->get('redisPool')->get(); - - $cache = new Cache(new RedisCache($redis)); - $dbForInternal = new Database(new MariaDB($db), $cache); - $dbForInternal->setNamespace('project_'.$projectId.'_internal'); // Main DB - - }); - - return $dbForInternal; - } - - /** - * @param string $projectId - * - * @return Database - */ - protected function getExternalDB($projectId): Database - { - global $register; - - /** @var Database $dbForExternal */ - $dbForExternal = null; - - go(function() use ($register, $projectId, &$dbForExternal) { - $db = $register->get('dbPool')->get(); - $redis = $register->get('redisPool')->get(); - - $cache = new Cache(new RedisCache($redis)); - $dbForExternal = new Database(new MariaDB($db), $cache); - $dbForExternal->setNamespace('project_'.$projectId.'_external'); // Main DB - - }); - - return $dbForExternal; - } } diff --git a/app/workers/deletes.php b/app/workers/deletes.php index 1242d7a8ab..e98723a5ea 100644 --- a/app/workers/deletes.php +++ b/app/workers/deletes.php @@ -3,17 +3,13 @@ use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Query; -use Utopia\Cache\Adapter\Redis as RedisCache; use Utopia\Database\Validator\Authorization; use Appwrite\Resque\Worker; use Utopia\Storage\Device\Local; use Utopia\Abuse\Abuse; use Utopia\Abuse\Adapters\TimeLimit; use Utopia\CLI\Console; -use Utopia\Config\Config; use Utopia\Audit\Audit; -use Utopia\Cache\Cache; -use Utopia\Database\Adapter\MariaDB; require_once __DIR__.'/../workers.php'; @@ -351,48 +347,4 @@ class DeletesV1 extends Worker Console::info("No certificate files found for {$domain}"); } } - - /** - * @param string $projectId - * @return Database - */ - protected function getInternalDB($projectId): Database - { - global $register; - - $cache = new Cache(new RedisCache($register->get('cache'))); - $dbForInternal = new Database(new MariaDB($register->get('db')), $cache); - $dbForInternal->setNamespace('project_'.$projectId.'_internal'); // Main DB - - return $dbForInternal; - } - - /** - * @param string $projectId - * @return Database - */ - protected function getExternalDB($projectId): Database - { - global $register; - - $cache = new Cache(new RedisCache($register->get('cache'))); - $dbForExternal = new Database(new MariaDB($register->get('db')), $cache); - $dbForExternal->setNamespace('project_'.$projectId.'_external'); // Main DB - - return $dbForExternal; - } - - /** - * @return Database - */ - protected function getConsoleDB(): Database - { - global $register; - - $cache = new Cache(new RedisCache($register->get('cache'))); - $dbForConsole = new Database(new MariaDB($register->get('db')), $cache); - $dbForConsole->setNamespace('project_console_internal'); // Main DB - - return $dbForConsole; - } } diff --git a/app/workers/functions.php b/app/workers/functions.php index 8db7d64753..510346fb48 100644 --- a/app/workers/functions.php +++ b/app/workers/functions.php @@ -6,11 +6,8 @@ use Appwrite\Utopia\Response\Model\Execution; use Cron\CronExpression; use Swoole\Runtime; use Utopia\App; -use Utopia\Cache\Adapter\Redis; -use Utopia\Cache\Cache; use Utopia\CLI\Console; use Utopia\Config\Config; -use Utopia\Database\Adapter\MariaDB; use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Validator\Authorization; @@ -139,9 +136,6 @@ class FunctionsV1 extends Worker { global $register; - $db = $register->get('db'); - $cache = $register->get('cache'); - $projectId = $this->args['projectId'] ?? ''; $functionId = $this->args['functionId'] ?? ''; $webhooks = $this->args['webhooks'] ?? []; @@ -154,9 +148,7 @@ class FunctionsV1 extends Worker $userId = $this->args['userId'] ?? ''; $jwt = $this->args['jwt'] ?? ''; - $cache = new Cache(new Redis($cache)); - $database = new Database(new MariaDB($db), $cache); - $database->setNamespace('project_'.$projectId.'_internal'); + $database = $this->getInternalDB($projectId); switch ($trigger) { case 'event': @@ -413,15 +405,24 @@ class FunctionsV1 extends Worker " --workdir /usr/local/src". " ".\implode(" ", $vars). " {$runtime['image']}". - " sh -c 'mv /tmp/code.tar.gz /usr/local/src/code.tar.gz && tar -zxf /usr/local/src/code.tar.gz --strip 1 && rm /usr/local/src/code.tar.gz && tail -f /dev/null'" + " tail -f /dev/null" , '', $stdout, $stderr, 30); - $executionEnd = \microtime(true); - if($exitCode !== 0) { throw new Exception('Failed to create function environment: '.$stderr); } + $exitCodeUntar = Console::execute("docker exec ". + $container. + " sh -c 'mv /tmp/code.tar.gz /usr/local/src/code.tar.gz && tar -zxf /usr/local/src/code.tar.gz --strip 1 && rm /usr/local/src/code.tar.gz'" + , '', $stdout, $stderr, 60); + + if($exitCodeUntar !== 0) { + throw new Exception('Failed to extract tar: '.$stderr); + } + + $executionEnd = \microtime(true); + $list[$container] = [ 'name' => $container, 'online' => true, diff --git a/app/workers/tasks.php b/app/workers/tasks.php index cb24c65a9f..b3469393ef 100644 --- a/app/workers/tasks.php +++ b/app/workers/tasks.php @@ -28,11 +28,6 @@ class TasksV1 extends Worker public function run(): void { - global $register; - - $db = $register->get('db'); - $cache = $register->get('cache'); - $projectId = $this->args['projectId'] ?? null; $taskId = $this->args['$id'] ?? null; $updated = $this->args['updated'] ?? null; @@ -44,9 +39,7 @@ class TasksV1 extends Worker $logLimit = 5; $alert = ''; - $cache = new Cache(new Redis($cache)); - $dbForConsole = new Database(new MariaDB($db), $cache); - $dbForConsole->setNamespace('project_console_internal'); + $dbForConsole = $this->getConsoleDB(); /* * 1. Get Original Task diff --git a/composer.lock b/composer.lock index 870718a771..8dd812f792 100644 --- a/composer.lock +++ b/composer.lock @@ -5287,16 +5287,16 @@ }, { "name": "symfony/console", - "version": "v5.3.2", + "version": "v5.3.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "649730483885ff2ca99ca0560ef0e5f6b03f2ac1" + "reference": "ebd610dacd40d75b6a12bf64b5ccd494fc7d6ab1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/649730483885ff2ca99ca0560ef0e5f6b03f2ac1", - "reference": "649730483885ff2ca99ca0560ef0e5f6b03f2ac1", + "url": "https://api.github.com/repos/symfony/console/zipball/ebd610dacd40d75b6a12bf64b5ccd494fc7d6ab1", + "reference": "ebd610dacd40d75b6a12bf64b5ccd494fc7d6ab1", "shasum": "" }, "require": { @@ -5304,11 +5304,12 @@ "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "^1.8", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/service-contracts": "^1.1|^2", "symfony/string": "^5.1" }, "conflict": { + "psr/log": ">=3", "symfony/dependency-injection": "<4.4", "symfony/dotenv": "<5.1", "symfony/event-dispatcher": "<4.4", @@ -5316,10 +5317,10 @@ "symfony/process": "<4.4" }, "provide": { - "psr/log-implementation": "1.0" + "psr/log-implementation": "1.0|2.0" }, "require-dev": { - "psr/log": "~1.0", + "psr/log": "^1|^2", "symfony/config": "^4.4|^5.0", "symfony/dependency-injection": "^4.4|^5.0", "symfony/event-dispatcher": "^4.4|^5.0", @@ -5365,7 +5366,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.3.2" + "source": "https://github.com/symfony/console/tree/v5.3.4" }, "funding": [ { @@ -5381,7 +5382,7 @@ "type": "tidelift" } ], - "time": "2021-06-12T09:42:48+00:00" + "time": "2021-07-26T16:33:26+00:00" }, { "name": "symfony/deprecation-contracts", diff --git a/docker-compose.yml b/docker-compose.yml index 32ec332314..ed50016ed5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -508,17 +508,6 @@ services: networks: - appwrite - swagger-validator: - image: 'swaggerapi/swagger-validator-v2:v2.0.5' - container_name: appwrite-swagger-validator - ports: - - '9506:8080' - environment: - - REJECT_LOCAL=false - - REJECT_REDIRECT=false - networks: - - appwrite - # redis-commander: # image: rediscommander/redis-commander:latest # restart: unless-stopped diff --git a/docs/references/teams/create-team-membership.md b/docs/references/teams/create-team-membership.md index a920c260be..c6d81de484 100644 --- a/docs/references/teams/create-team-membership.md +++ b/docs/references/teams/create-team-membership.md @@ -1,5 +1,5 @@ -Use this endpoint to invite a new member to join your team. An email with a link to join the team will be sent to the new member email address if the member doesn't exist in the project it will be created automatically. +Use this endpoint to invite a new member to join your team. If initiated from Client SDK, an email with a link to join the team will be sent to the new member's email address if the member doesn't exist in the project it will be created automatically. If initiated from server side SDKs, new member will automatically be added to the team. -Use the 'URL' parameter to redirect the user from the invitation email back to your app. When the user is redirected, use the [Update Team Membership Status](/docs/client/teams#teamsUpdateMembershipStatus) endpoint to allow the user to accept the invitation to the team. +Use the 'URL' parameter to redirect the user from the invitation email back to your app. When the user is redirected, use the [Update Team Membership Status](/docs/client/teams#teamsUpdateMembershipStatus) endpoint to allow the user to accept the invitation to the team. While calling from side SDKs the redirect url can be empty string. Please note that in order to avoid a [Redirect Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URL's are the once from domains you have set when added your platforms in the console interface. \ No newline at end of file diff --git a/src/Appwrite/Auth/Auth.php b/src/Appwrite/Auth/Auth.php index 3ae28997b1..56f708493b 100644 --- a/src/Appwrite/Auth/Auth.php +++ b/src/Appwrite/Auth/Auth.php @@ -2,7 +2,7 @@ namespace Appwrite\Auth; -use Appwrite\Database\Document; +use Utopia\Database\Document; class Auth { diff --git a/src/Appwrite/Migration/Migration.php b/src/Appwrite/Migration/Migration.php index bd03e7d339..8eae515b9b 100644 --- a/src/Appwrite/Migration/Migration.php +++ b/src/Appwrite/Migration/Migration.php @@ -40,6 +40,7 @@ abstract class Migration '0.8.0' => 'V07', '0.9.0' => 'V08', '0.9.1' => 'V08', + '0.9.2' => 'V08', ]; /** diff --git a/src/Appwrite/Resque/Worker.php b/src/Appwrite/Resque/Worker.php index db8dc91ce7..84241173f5 100644 --- a/src/Appwrite/Resque/Worker.php +++ b/src/Appwrite/Resque/Worker.php @@ -2,6 +2,12 @@ namespace Appwrite\Resque; +use Utopia\Cache\Cache; +use Utopia\Cache\Adapter\Redis as RedisCache; +use Utopia\CLI\Console; +use Utopia\Database\Database; +use Utopia\Database\Adapter\MariaDB; + abstract class Worker { public $args = []; @@ -12,6 +18,13 @@ abstract class Worker abstract public function shutdown(): void; + const MAX_ATTEMPTS = 10; + const SLEEP_TIME = 2; + + const DATABASE_INTERNAL = 'internal'; + const DATABASE_EXTERNAL = 'external'; + const DATABASE_CONSOLE = 'console'; + public function setUp(): void { $this->init(); @@ -26,4 +39,91 @@ abstract class Worker { $this->shutdown(); } + /** + * Get internal project database + * @param string $projectId + * @return Database + */ + protected function getInternalDB(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); + } + + /** + * Get console database + * @return Database + */ + protected function getConsoleDB(): Database + { + return $this->getDB(self::DATABASE_CONSOLE); + } + + /** + * Get console database + * @param string $type One of (internal, external, console) + * @param string $projectId of internal or external DB + * @return Database + */ + private function getDB($type, $projectId = ''): Database + { + global $register; + + $namespace = ''; + $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}_internal"; + break; + case self::DATABASE_EXTERNAL: + if (!$projectId) { + throw new \Exception('ProjectID not provided - cannot get database'); + } + $namespace = "project_{$projectId}_external"; + break; + case self::DATABASE_CONSOLE: + $namespace = "project_console_internal"; + $sleep = 5; // ConsoleDB needs extra sleep time to ensure tables are created + break; + default: + throw new \Exception('Unknown database type: ' . $type); + break; + } + + $attempts = 0; + + do { + try { + $attempts++; + $cache = new Cache(new RedisCache($register->get('cache'))); + $database = new Database(new MariaDB($register->get('db')), $cache); + $database->setNamespace($namespace); // Main DB + if (!$database->exists()) { + throw new \Exception("Table does not exist: {$database->getNamespace()}"); + } + break; // leave loop if successful + } catch(\Exception $e) { + Console::warning("Database not ready. Retrying connection ({$attempts})..."); + if ($attempts >= self::MAX_ATTEMPTS) { + throw new \Exception('Failed to connect to database: '. $e->getMessage()); + } + sleep($sleep); + } + } while ($attempts < self::MAX_ATTEMPTS); + + return $database; + } } \ No newline at end of file diff --git a/src/Appwrite/Specification/Format/OpenAPI3.php b/src/Appwrite/Specification/Format/OpenAPI3.php index b14134cdf2..02b3c315d0 100644 --- a/src/Appwrite/Specification/Format/OpenAPI3.php +++ b/src/Appwrite/Specification/Format/OpenAPI3.php @@ -238,7 +238,7 @@ class OpenAPI3 extends Format $node['schema']['type'] = $validator->getType(); $node['schema']['x-example'] = false; break; - case 'Appwrite\Database\Validator\UID': + case 'Utopia\Database\Validator\UID': $node['schema']['type'] = $validator->getType(); $node['schema']['x-example'] = '['.\strtoupper(Template::fromCamelCaseToSnake($node['name'])).']'; break; diff --git a/src/Appwrite/Specification/Format/Swagger2.php b/src/Appwrite/Specification/Format/Swagger2.php index 9809220f87..d8a84e3ccf 100644 --- a/src/Appwrite/Specification/Format/Swagger2.php +++ b/src/Appwrite/Specification/Format/Swagger2.php @@ -234,7 +234,7 @@ class Swagger2 extends Format $node['type'] = $validator->getType(); $node['x-example'] = false; break; - case 'Appwrite\Database\Validator\UID': + case 'Utopia\Database\Validator\UID': $node['type'] = $validator->getType(); $node['x-example'] = '['.\strtoupper(Template::fromCamelCaseToSnake($node['name'])).']'; break; diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index ddfc9f7819..bd71089a14 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -5,7 +5,7 @@ namespace Appwrite\Utopia; use Exception; use Utopia\Swoole\Response as SwooleResponse; use Swoole\Http\Response as SwooleHTTPResponse; -use Appwrite\Database\Document; +use Utopia\Database\Document; use Appwrite\Utopia\Response\Filter; use Appwrite\Utopia\Response\Model; use Appwrite\Utopia\Response\Model\None; @@ -46,7 +46,6 @@ use Appwrite\Utopia\Response\Model\Webhook; use Appwrite\Utopia\Response\Model\Preferences; use Appwrite\Utopia\Response\Model\Mock; // Keep last use stdClass; -use Utopia\Database\Document as DatabaseDocument; /** * @method Response public function setStatusCode(int $code = 200) @@ -290,27 +289,6 @@ class Response extends SwooleResponse $this->json(!empty($output) ? $output : new stdClass()); } - /** - * Validate response objects and outputs - * the response according to given format type - * - * @param DatabaseDocument $document - * @param string $model - * - * return void - */ - public function dynamic2(DatabaseDocument $document, string $model): void - { - $output = $this->output2($document, $model); - - // If filter is set, parse the output - if(self::isFilter()){ - $output = self::getFilter()->parse($output, $model); - } - - $this->json(!empty($output) ? $output : new stdClass()); - } - /** * Generate valid response object from document data * @@ -363,58 +341,6 @@ class Response extends SwooleResponse return $this->payload; } - /** - * Generate valid response object from document data - * - * @param DatabaseDocument $document - * @param string $model - * - * return array - */ - public function output2(DatabaseDocument $document, string $model): array - { - $data = $document; - $model = $this->getModel($model); - $output = []; - - if ($model->isAny()) { - $this->payload = $document->getArrayCopy(); - return $this->payload; - } - - foreach ($model->getRules() as $key => $rule) { - if (!$document->isSet($key)) { - if (!is_null($rule['default'])) { - $document->setAttribute($key, $rule['default']); - } else { - throw new Exception('Model '.$model->getName().' is missing response key: '.$key); - } - } - - if ($rule['array']) { - if (!is_array($data[$key])) { - throw new Exception($key.' must be an array of type '.$rule['type']); - } - - foreach ($data[$key] as &$item) { - if ($item instanceof Document) { - if (!array_key_exists($rule['type'], $this->models)) { - throw new Exception('Missing model for rule: '. $rule['type']); - } - - $item = $this->output($item, $rule['type']); - } - } - } - - $output[$key] = $data[$key]; - } - - $this->payload = $output; - - return $this->payload; - } - /** * YAML * diff --git a/tests/e2e/General/HTTPTest.php b/tests/e2e/General/HTTPTest.php index 78f77f4d12..4f9a8dc95d 100644 --- a/tests/e2e/General/HTTPTest.php +++ b/tests/e2e/General/HTTPTest.php @@ -133,7 +133,7 @@ class HTTPTest extends Scope } $client = new Client(); - $client->setEndpoint('http://appwrite-swagger-validator:8080'); + $client->setEndpoint('https://validator.swagger.io'); /** * Test for SUCCESS diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index f958de5205..4def7dede6 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -185,7 +185,32 @@ class FunctionsCustomClientTest extends Scope $this->assertEquals(201, $execution['headers']['status-code']); + $executionId = $execution['body']['$id'] ?? ''; + sleep(10); + + $executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions/'.$executionId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + 'x-appwrite-key' => $apikey, + ]); + + $output = json_decode($executions['body']['stdout'], true); + + $this->assertEquals(200, $executions['headers']['status-code']); + $this->assertEquals('completed', $executions['body']['status']); + $this->assertEquals($functionId, $output['APPWRITE_FUNCTION_ID']); + $this->assertEquals('Test', $output['APPWRITE_FUNCTION_NAME']); + $this->assertEquals($tagId, $output['APPWRITE_FUNCTION_TAG']); + $this->assertEquals('http', $output['APPWRITE_FUNCTION_TRIGGER']); + $this->assertEquals('PHP', $output['APPWRITE_FUNCTION_RUNTIME_NAME']); + $this->assertEquals('8.0', $output['APPWRITE_FUNCTION_RUNTIME_VERSION']); + $this->assertEquals('', $output['APPWRITE_FUNCTION_EVENT']); + $this->assertEquals('', $output['APPWRITE_FUNCTION_EVENT_DATA']); + $this->assertEquals('foobar', $output['APPWRITE_FUNCTION_DATA']); + $this->assertEquals($this->getUser()['$id'], $output['APPWRITE_FUNCTION_USER_ID']); + $this->assertNotEmpty($output['APPWRITE_FUNCTION_JWT']); + $executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions', [ 'content-type' => 'application/json', 'x-appwrite-project' => $projectId, diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index cf0a1cafc4..775eca06e2 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -582,8 +582,31 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(201, $execution['headers']['status-code']); + $executionId = $execution['body']['$id'] ?? ''; + sleep(10); + $executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions/'.$executionId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $output = json_decode($executions['body']['stdout'], true); + + $this->assertEquals(200, $executions['headers']['status-code']); + $this->assertEquals('completed', $executions['body']['status']); + $this->assertEquals($functionId, $output['APPWRITE_FUNCTION_ID']); + $this->assertEquals('Test '.$name, $output['APPWRITE_FUNCTION_NAME']); + $this->assertEquals($tagId, $output['APPWRITE_FUNCTION_TAG']); + $this->assertEquals('http', $output['APPWRITE_FUNCTION_TRIGGER']); + $this->assertEquals('PHP', $output['APPWRITE_FUNCTION_RUNTIME_NAME']); + $this->assertEquals('8.0', $output['APPWRITE_FUNCTION_RUNTIME_VERSION']); + $this->assertEquals('', $output['APPWRITE_FUNCTION_EVENT']); + $this->assertEquals('', $output['APPWRITE_FUNCTION_EVENT_DATA']); + $this->assertEquals('foobar', $output['APPWRITE_FUNCTION_DATA']); + $this->assertEquals('', $output['APPWRITE_FUNCTION_USER_ID']); + $this->assertEmpty($output['APPWRITE_FUNCTION_JWT']); + $executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], diff --git a/tests/resources/functions/php-fn.tar.gz b/tests/resources/functions/php-fn.tar.gz index a97a2e2352..5e359122fa 100644 Binary files a/tests/resources/functions/php-fn.tar.gz and b/tests/resources/functions/php-fn.tar.gz differ diff --git a/tests/resources/functions/php-fn/index.php b/tests/resources/functions/php-fn/index.php index 32af3ccb16..449658e1e7 100644 --- a/tests/resources/functions/php-fn/index.php +++ b/tests/resources/functions/php-fn/index.php @@ -17,15 +17,18 @@ use Appwrite\Services\Storage; // $result = $storage->getFile($_ENV['APPWRITE_FILEID']); -echo $_ENV['APPWRITE_FUNCTION_ID']."\n"; -echo $_ENV['APPWRITE_FUNCTION_NAME']."\n"; -echo $_ENV['APPWRITE_FUNCTION_TAG']."\n"; -echo $_ENV['APPWRITE_FUNCTION_TRIGGER']."\n"; -echo $_ENV['APPWRITE_FUNCTION_RUNTIME_NAME']."\n"; -echo $_ENV['APPWRITE_FUNCTION_RUNTIME_VERSION']."\n"; -// echo $result['$id']; -echo $_ENV['APPWRITE_FUNCTION_EVENT']."\n"; -echo $_ENV['APPWRITE_FUNCTION_EVENT_DATA']."\n"; -echo 'data:'.$_ENV['APPWRITE_FUNCTION_DATA']."\n"; -echo 'userId:'.$_ENV['APPWRITE_FUNCTION_USER_ID']."\n"; -echo 'jwt:'.$_ENV['APPWRITE_FUNCTION_JWT']."\n"; +$output = [ + 'APPWRITE_FUNCTION_ID' => $_ENV['APPWRITE_FUNCTION_ID'], + 'APPWRITE_FUNCTION_NAME' => $_ENV['APPWRITE_FUNCTION_NAME'], + 'APPWRITE_FUNCTION_TAG' => $_ENV['APPWRITE_FUNCTION_TAG'], + 'APPWRITE_FUNCTION_TRIGGER' => $_ENV['APPWRITE_FUNCTION_TRIGGER'], + 'APPWRITE_FUNCTION_RUNTIME_NAME' => $_ENV['APPWRITE_FUNCTION_RUNTIME_NAME'], + 'APPWRITE_FUNCTION_RUNTIME_VERSION' => $_ENV['APPWRITE_FUNCTION_RUNTIME_VERSION'], + 'APPWRITE_FUNCTION_EVENT' => $_ENV['APPWRITE_FUNCTION_EVENT'], + 'APPWRITE_FUNCTION_EVENT_DATA' => $_ENV['APPWRITE_FUNCTION_EVENT_DATA'], + 'APPWRITE_FUNCTION_DATA' => $_ENV['APPWRITE_FUNCTION_DATA'], + 'APPWRITE_FUNCTION_USER_ID' => $_ENV['APPWRITE_FUNCTION_USER_ID'], + 'APPWRITE_FUNCTION_JWT' => $_ENV['APPWRITE_FUNCTION_JWT'], +]; + +echo json_encode($output);