1
0
Fork 0
mirror of synced 2024-07-03 13:41:01 +12:00

Merge branch 'feat-storage-buckets' into feat-sb-delete

This commit is contained in:
Damodar Lohani 2021-07-28 15:33:10 +05:45
commit f9df66b925
39 changed files with 675 additions and 674 deletions

View file

@ -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 # Version 0.9.1
## Bugs ## Bugs

View file

@ -609,13 +609,13 @@ $collections = [
], ],
], ],
'indexes' => [ 'indexes' => [
// [ [
// '$id' => '_key_provider_providerUid', '$id' => '_key_provider_providerUid',
// 'type' => Database::INDEX_KEY, 'type' => Database::INDEX_KEY,
// 'attributes' => ['provider', 'providerUid'], 'attributes' => ['provider', 'providerUid'],
// 'lengths' => [100, 100], 'lengths' => [100, 100],
// 'orders' => [Database::ORDER_ASC, Database::ORDER_ASC], 'orders' => [Database::ORDER_ASC, Database::ORDER_ASC],
// ] ]
], ],
], ],

View file

@ -53,7 +53,7 @@ App::post('/v1/account')
->action(function ($email, $password, $name, $request, $response, $project, $dbForInternal, $audits) { ->action(function ($email, $password, $name, $request, $response, $project, $dbForInternal, $audits) {
/** @var Utopia\Swoole\Request $request */ /** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */ /** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $audits */
@ -119,7 +119,7 @@ App::post('/v1/account')
; ;
$response->setStatusCode(Response::STATUS_CODE_CREATED); $response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($user, Response::MODEL_USER); $response->dynamic($user, Response::MODEL_USER);
}); });
App::post('/v1/account/sessions') App::post('/v1/account/sessions')
@ -229,7 +229,7 @@ App::post('/v1/account/sessions')
->setAttribute('countryName', $countryName) ->setAttribute('countryName', $countryName)
; ;
$response->dynamic2($session, Response::MODEL_SESSION); $response->dynamic($session, Response::MODEL_SESSION);
}); });
App::get('/v1/account/sessions/oauth2/:provider') 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) { ->action(function ($provider, $success, $failure, $scopes, $request, $response, $project) {
/** @var Utopia\Swoole\Request $request */ /** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */ /** @var Utopia\Database\Document $project */
$protocol = $request->getProtocol(); $protocol = $request->getProtocol();
$callback = $protocol.'://'.$request->getHostname().'/v1/account/sessions/oauth2/callback/'.$provider.'/'.$project->getId(); $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) { ->action(function ($provider, $code, $state, $request, $response, $project, $user, $dbForInternal, $geodb, $audits, $events) use ($oauthDefaultSuccess) {
/** @var Utopia\Swoole\Request $request */ /** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */ /** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Database\Database $dbForInternal */
/** @var MaxMind\Db\Reader $geodb */ /** @var MaxMind\Db\Reader $geodb */
@ -546,7 +546,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
->setParam('data', ['provider' => $provider]) ->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')) { if (!Config::getParam('domainVerification')) {
$response $response
@ -603,7 +603,7 @@ App::post('/v1/account/sessions/anonymous')
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Locale\Locale $locale */ /** @var Utopia\Locale\Locale $locale */
/** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Document $user */
/** @var Appwrite\Database\Document $project */ /** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Database\Database $dbForInternal */
/** @var MaxMind\Db\Reader $geodb */ /** @var MaxMind\Db\Reader $geodb */
/** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $audits */
@ -710,7 +710,7 @@ App::post('/v1/account/sessions/anonymous')
->setAttribute('countryName', $countryName) ->setAttribute('countryName', $countryName)
; ;
$response->dynamic2($session, Response::MODEL_SESSION); $response->dynamic($session, Response::MODEL_SESSION);
}); });
App::post('/v1/account/jwt') App::post('/v1/account/jwt')
@ -737,7 +737,7 @@ App::post('/v1/account/jwt')
$current = new Document(); $current = new Document();
foreach ($sessions as $session) { 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 if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
$current = $session; $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. $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->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2(new Document(['jwt' => $jwt->encode([ $response->dynamic(new Document(['jwt' => $jwt->encode([
// 'uid' => 1, // 'uid' => 1,
// 'aud' => 'http://site.com', // 'aud' => 'http://site.com',
// 'scopes' => ['user'], // 'scopes' => ['user'],
@ -778,7 +778,7 @@ App::get('/v1/account')
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Document $user */
$response->dynamic2($user, Response::MODEL_USER); $response->dynamic($user, Response::MODEL_USER);
}); });
App::get('/v1/account/prefs') App::get('/v1/account/prefs')
@ -800,7 +800,7 @@ App::get('/v1/account/prefs')
$prefs = $user->getAttribute('prefs', new \stdClass()); $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') App::get('/v1/account/sessions')
@ -837,7 +837,7 @@ App::get('/v1/account/sessions')
$sessions[$key] = $session; $sessions[$key] = $session;
} }
$response->dynamic2(new Document([ $response->dynamic(new Document([
'sessions' => $sessions, 'sessions' => $sessions,
'sum' => count($sessions), 'sum' => count($sessions),
]), Response::MODEL_SESSION_LIST); ]), Response::MODEL_SESSION_LIST);
@ -861,7 +861,7 @@ App::get('/v1/account/logs')
->inject('dbForInternal') ->inject('dbForInternal')
->action(function ($response, $user, $locale, $geodb, $dbForInternal) { ->action(function ($response, $user, $locale, $geodb, $dbForInternal) {
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */ /** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Document $user */
/** @var Utopia\Locale\Locale $locale */ /** @var Utopia\Locale\Locale $locale */
/** @var MaxMind\Db\Reader $geodb */ /** @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') App::get('/v1/account/sessions/:sessionId')
@ -935,7 +935,7 @@ App::get('/v1/account/sessions/:sessionId')
->inject('dbForInternal') ->inject('dbForInternal')
->action(function ($sessionId, $response, $user, $locale, $dbForInternal) { ->action(function ($sessionId, $response, $user, $locale, $dbForInternal) {
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $user */ /** @var Utopia\Database\Document $user */
/** @var Utopia\Locale\Locale $locale */ /** @var Utopia\Locale\Locale $locale */
/** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Database\Database $dbForInternal */
@ -956,7 +956,7 @@ App::get('/v1/account/sessions/:sessionId')
->setAttribute('countryName', $countryName) ->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()) ->setParam('resource', 'users/'.$user->getId())
; ;
$response->dynamic2($user, Response::MODEL_USER); $response->dynamic($user, Response::MODEL_USER);
}); });
App::patch('/v1/account/password') App::patch('/v1/account/password')
@ -1037,7 +1037,7 @@ App::patch('/v1/account/password')
->setParam('resource', 'users/'.$user->getId()) ->setParam('resource', 'users/'.$user->getId())
; ;
$response->dynamic2($user, Response::MODEL_USER); $response->dynamic($user, Response::MODEL_USER);
}); });
App::patch('/v1/account/email') App::patch('/v1/account/email')
@ -1092,7 +1092,7 @@ App::patch('/v1/account/email')
->setParam('resource', 'users/'.$user->getId()) ->setParam('resource', 'users/'.$user->getId())
; ;
$response->dynamic2($user, Response::MODEL_USER); $response->dynamic($user, Response::MODEL_USER);
}); });
App::patch('/v1/account/prefs') App::patch('/v1/account/prefs')
@ -1125,7 +1125,7 @@ App::patch('/v1/account/prefs')
->setParam('resource', 'users/'.$user->getId()) ->setParam('resource', 'users/'.$user->getId())
; ;
$response->dynamic2($user, Response::MODEL_USER); $response->dynamic($user, Response::MODEL_USER);
}); });
App::delete('/v1/account') App::delete('/v1/account')
@ -1172,7 +1172,7 @@ App::delete('/v1/account')
; ;
$events $events
->setParam('eventData', $response->output2($user, Response::MODEL_USER)) ->setParam('eventData', $response->output($user, Response::MODEL_USER))
; ;
if (!Config::getParam('domainVerification')) { if (!Config::getParam('domainVerification')) {
@ -1259,7 +1259,7 @@ App::delete('/v1/account/sessions/:sessionId')
$dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', $sessions)); $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', $sessions));
$events $events
->setParam('eventData', $response->output2($session, Response::MODEL_SESSION)) ->setParam('eventData', $response->output($session, Response::MODEL_SESSION))
; ;
return $response->noContent(); return $response->noContent();
@ -1332,7 +1332,7 @@ App::delete('/v1/account/sessions')
$dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', [])); $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', []));
$events $events
->setParam('eventData', $response->output2(new Document([ ->setParam('eventData', $response->output(new Document([
'sessions' => $sessions, 'sessions' => $sessions,
'sum' => count($sessions), 'sum' => count($sessions),
]), Response::MODEL_SESSION_LIST)) ]), Response::MODEL_SESSION_LIST))
@ -1369,7 +1369,7 @@ App::post('/v1/account/recovery')
/** @var Utopia\Swoole\Request $request */ /** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Database\Document $project */ /** @var Utopia\Database\Document $project */
/** @var Utopia\Locale\Locale $locale */ /** @var Utopia\Locale\Locale $locale */
/** @var Appwrite\Event\Event $mails */ /** @var Appwrite\Event\Event $mails */
/** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $audits */
@ -1443,7 +1443,7 @@ App::post('/v1/account/recovery')
$events $events
->setParam('eventData', ->setParam('eventData',
$response->output2($recovery->setAttribute('secret', $secret), $response->output($recovery->setAttribute('secret', $secret),
Response::MODEL_TOKEN Response::MODEL_TOKEN
)) ))
; ;
@ -1459,7 +1459,7 @@ App::post('/v1/account/recovery')
; ;
$response->setStatusCode(Response::STATUS_CODE_CREATED); $response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($recovery, Response::MODEL_TOKEN); $response->dynamic($recovery, Response::MODEL_TOKEN);
}); });
App::put('/v1/account/recovery') App::put('/v1/account/recovery')
@ -1533,7 +1533,7 @@ App::put('/v1/account/recovery')
->setParam('resource', 'users/'.$profile->getId()) ->setParam('resource', 'users/'.$profile->getId())
; ;
$response->dynamic2($recovery, Response::MODEL_TOKEN); $response->dynamic($recovery, Response::MODEL_TOKEN);
}); });
App::post('/v1/account/verification') 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) { ->action(function ($url, $request, $response, $project, $user, $dbForInternal, $locale, $audits, $events, $mails) {
/** @var Utopia\Swoole\Request $request */ /** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */ /** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Locale\Locale $locale */ /** @var Utopia\Locale\Locale $locale */
@ -1629,7 +1629,7 @@ App::post('/v1/account/verification')
$events $events
->setParam('eventData', ->setParam('eventData',
$response->output2($verification->setAttribute('secret', $verificationSecret), $response->output($verification->setAttribute('secret', $verificationSecret),
Response::MODEL_TOKEN Response::MODEL_TOKEN
)) ))
; ;
@ -1645,7 +1645,7 @@ App::post('/v1/account/verification')
; ;
$response->setStatusCode(Response::STATUS_CODE_CREATED); $response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($verification, Response::MODEL_TOKEN); $response->dynamic($verification, Response::MODEL_TOKEN);
}); });
App::put('/v1/account/verification') App::put('/v1/account/verification')
@ -1710,5 +1710,5 @@ App::put('/v1/account/verification')
->setParam('resource', 'users/'.$user->getId()) ->setParam('resource', 'users/'.$user->getId())
; ;
$response->dynamic2($verification, Response::MODEL_TOKEN); $response->dynamic($verification, Response::MODEL_TOKEN);
}); });

View file

@ -424,7 +424,7 @@ App::get('/v1/avatars/initials')
->inject('user') ->inject('user')
->action(function ($name, $width, $height, $color, $background, $response, $user) { ->action(function ($name, $width, $height, $color, $background, $response, $user) {
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $user */ /** @var Utopia\Database\Document $user */
$themes = [ $themes = [
['color' => '#27005e', 'background' => '#e1d2f6'], // VIOLET ['color' => '#27005e', 'background' => '#e1d2f6'], // VIOLET

View file

@ -67,7 +67,7 @@ App::post('/v1/database/collections')
; ;
$response->setStatusCode(Response::STATUS_CODE_CREATED); $response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($collection, Response::MODEL_COLLECTION); $response->dynamic($collection, Response::MODEL_COLLECTION);
}); });
App::get('/v1/database/collections') App::get('/v1/database/collections')
@ -93,7 +93,7 @@ App::get('/v1/database/collections')
$queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, [$search])] : []; $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]), 'collections' => $dbForExternal->find(Database::COLLECTIONS, $queries, $limit, $offset, ['_id'], [$orderType]),
'sum' => $dbForExternal->count(Database::COLLECTIONS, $queries, APP_LIMIT_COUNT), 'sum' => $dbForExternal->count(Database::COLLECTIONS, $queries, APP_LIMIT_COUNT),
]), Response::MODEL_COLLECTION_LIST); ]), Response::MODEL_COLLECTION_LIST);
@ -123,7 +123,7 @@ App::get('/v1/database/collections/:collectionId')
throw new Exception('Collection not found', 404); 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') App::put('/v1/database/collections/:collectionId')
@ -177,7 +177,7 @@ App::put('/v1/database/collections/:collectionId')
->setParam('data', $collection->getArrayCopy()) ->setParam('data', $collection->getArrayCopy())
; ;
$response->dynamic2($collection, Response::MODEL_COLLECTION); $response->dynamic($collection, Response::MODEL_COLLECTION);
}); });
App::delete('/v1/database/collections/:collectionId') App::delete('/v1/database/collections/:collectionId')
@ -212,7 +212,7 @@ App::delete('/v1/database/collections/:collectionId')
$dbForExternal->deleteCollection($collectionId); $dbForExternal->deleteCollection($collectionId);
$events $events
->setParam('eventData', $response->output2($collection, Response::MODEL_COLLECTION)) ->setParam('eventData', $response->output($collection, Response::MODEL_COLLECTION))
; ;
$audits $audits
@ -296,7 +296,7 @@ App::post('/v1/database/collections/:collectionId/attributes')
; ;
$response->setStatusCode(Response::STATUS_CODE_CREATED); $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') App::get('/v1/database/collections/:collectionId/attributes')
@ -331,7 +331,7 @@ App::get('/v1/database/collections/:collectionId/attributes')
])]); ])]);
}, $attributes); }, $attributes);
$response->dynamic2(new Document([ $response->dynamic(new Document([
'sum' => \count($attributes), 'sum' => \count($attributes),
'attributes' => $attributes 'attributes' => $attributes
]), Response::MODEL_ATTRIBUTE_LIST); ]), Response::MODEL_ATTRIBUTE_LIST);
@ -375,7 +375,7 @@ App::get('/v1/database/collections/:collectionId/attributes/:attributeId')
'collectionId' => $collectionId, 'collectionId' => $collectionId,
])]); ])]);
$response->dynamic2($attribute, Response::MODEL_ATTRIBUTE); $response->dynamic($attribute, Response::MODEL_ATTRIBUTE);
}); });
App::delete('/v1/database/collections/:collectionId/attributes/:attributeId') App::delete('/v1/database/collections/:collectionId/attributes/:attributeId')
@ -428,7 +428,7 @@ App::delete('/v1/database/collections/:collectionId/attributes/:attributeId')
; ;
$events $events
->setParam('payload', $response->output2($attribute, Response::MODEL_ATTRIBUTE)) ->setParam('payload', $response->output($attribute, Response::MODEL_ATTRIBUTE))
; ;
$audits $audits
@ -526,7 +526,7 @@ App::post('/v1/database/collections/:collectionId/indexes')
; ;
$response->setStatusCode(Response::STATUS_CODE_CREATED); $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); }, $indexes);
$response->dynamic2(new Document([ $response->dynamic(new Document([
'sum' => \count($indexes), 'sum' => \count($indexes),
'attributes' => $indexes, 'attributes' => $indexes,
]), Response::MODEL_INDEX_LIST); ]), Response::MODEL_INDEX_LIST);
@ -606,7 +606,7 @@ App::get('/v1/database/collections/:collectionId/indexes/:indexId')
'collectionId' => $collectionId, 'collectionId' => $collectionId,
])]); ])]);
$response->dynamic2($index, Response::MODEL_INDEX); $response->dynamic($index, Response::MODEL_INDEX);
}); });
App::delete('/v1/database/collections/:collectionId/indexes/:indexId') App::delete('/v1/database/collections/:collectionId/indexes/:indexId')
@ -659,7 +659,7 @@ App::delete('/v1/database/collections/:collectionId/indexes/:indexId')
; ;
$events $events
->setParam('payload', $response->output2($index, Response::MODEL_INDEX)) ->setParam('payload', $response->output($index, Response::MODEL_INDEX))
; ;
$audits $audits
@ -731,7 +731,7 @@ App::post('/v1/database/collections/:collectionId/documents')
; ;
$response->setStatusCode(Response::STATUS_CODE_CREATED); $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') 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); $documents = $dbForExternal->find($collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes);
$response->dynamic2(new Document([ $response->dynamic(new Document([
'sum' => \count($documents), 'sum' => \count($documents),
'documents' => $documents, 'documents' => $documents,
]), Response::MODEL_DOCUMENT_LIST); ]), Response::MODEL_DOCUMENT_LIST);
@ -819,7 +819,7 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId')
throw new Exception('No document found', 404); 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') App::patch('/v1/database/collections/:collectionId/documents/:documentId')
@ -890,7 +890,7 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
->setParam('data', $document->getArrayCopy()) ->setParam('data', $document->getArrayCopy())
; ;
$response->dynamic2($document, Response::MODEL_DOCUMENT); $response->dynamic($document, Response::MODEL_DOCUMENT);
}); });
App::delete('/v1/database/collections/:collectionId/documents/:documentId') 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); $success = $dbForExternal->deleteDocument($collectionId, $documentId);
$events $events
->setParam('eventData', $response->output2($document, Response::MODEL_DOCUMENT)) ->setParam('eventData', $response->output($document, Response::MODEL_DOCUMENT))
; ;
$audits $audits

View file

@ -2,7 +2,7 @@
use Ahc\Jwt\JWT; use Ahc\Jwt\JWT;
use Appwrite\Auth\Auth; use Appwrite\Auth\Auth;
use Appwrite\Database\Validator\UID; use Utopia\Database\Validator\UID;
use Utopia\Storage\Storage; use Utopia\Storage\Storage;
use Utopia\Storage\Validator\File; use Utopia\Storage\Validator\File;
use Utopia\Storage\Validator\FileExt; use Utopia\Storage\Validator\FileExt;
@ -68,7 +68,7 @@ App::post('/v1/functions')
])); ]));
$response->setStatusCode(Response::STATUS_CODE_CREATED); $response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($function, Response::MODEL_FUNCTION); $response->dynamic($function, Response::MODEL_FUNCTION);
}); });
App::get('/v1/functions') App::get('/v1/functions')
@ -94,7 +94,7 @@ App::get('/v1/functions')
$queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, [$search])] : []; $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]), 'functions' => $dbForInternal->find('functions', $queries, $limit, $offset, ['_id'], [$orderType]),
'sum' => $dbForInternal->count('functions', $queries, APP_LIMIT_COUNT), 'sum' => $dbForInternal->count('functions', $queries, APP_LIMIT_COUNT),
]), Response::MODEL_FUNCTION_LIST); ]), Response::MODEL_FUNCTION_LIST);
@ -124,7 +124,7 @@ App::get('/v1/functions/:functionId')
throw new Exception('Function not found', 404); 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') App::get('/v1/functions/:functionId/usage')
@ -142,7 +142,7 @@ App::get('/v1/functions/:functionId/usage')
->inject('register') ->inject('register')
->action(function ($functionId, $range, $response, $project, $dbForInternal, $register) { ->action(function ($functionId, $range, $response, $project, $dbForInternal, $register) {
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */ /** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Registry\Registry $register */ /** @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) { ->action(function ($functionId, $name, $execute, $vars, $events, $schedule, $timeout, $response, $dbForInternal, $project) {
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Database\Document $project */ /** @var Utopia\Database\Document $project */
$function = $dbForInternal->getDocument('functions', $functionId); $function = $dbForInternal->getDocument('functions', $functionId);
@ -305,7 +305,7 @@ App::put('/v1/functions/:functionId')
]); // Async task rescheduale ]); // Async task rescheduale
} }
$response->dynamic2($function, Response::MODEL_FUNCTION); $response->dynamic($function, Response::MODEL_FUNCTION);
}); });
App::patch('/v1/functions/:functionId/tag') App::patch('/v1/functions/:functionId/tag')
@ -328,7 +328,7 @@ App::patch('/v1/functions/:functionId/tag')
->action(function ($functionId, $tag, $response, $dbForInternal, $project) { ->action(function ($functionId, $tag, $response, $dbForInternal, $project) {
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Database\Document $project */ /** @var Utopia\Database\Document $project */
$function = $dbForInternal->getDocument('functions', $functionId); $function = $dbForInternal->getDocument('functions', $functionId);
$tag = $dbForInternal->getDocument('tags', $tag); $tag = $dbForInternal->getDocument('tags', $tag);
@ -360,7 +360,7 @@ App::patch('/v1/functions/:functionId/tag')
]); // Async task rescheduale ]); // Async task rescheduale
} }
$response->dynamic2($function, Response::MODEL_FUNCTION); $response->dynamic($function, Response::MODEL_FUNCTION);
}); });
App::delete('/v1/functions/:functionId') App::delete('/v1/functions/:functionId')
@ -484,7 +484,7 @@ App::post('/v1/functions/:functionId/tags')
; ;
$response->setStatusCode(Response::STATUS_CODE_CREATED); $response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($tag, Response::MODEL_TAG); $response->dynamic($tag, Response::MODEL_TAG);
}); });
App::get('/v1/functions/:functionId/tags') 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]); $results = $dbForInternal->find('tags', $queries, $limit, $offset, ['_id'], [$orderType]);
$sum = $dbForInternal->count('tags', $queries, APP_LIMIT_COUNT); $sum = $dbForInternal->count('tags', $queries, APP_LIMIT_COUNT);
$response->dynamic2(new Document([ $response->dynamic(new Document([
'tags' => $results, 'tags' => $results,
'sum' => $sum, 'sum' => $sum,
]), Response::MODEL_TAG_LIST); ]), Response::MODEL_TAG_LIST);
@ -561,7 +561,7 @@ App::get('/v1/functions/:functionId/tags/:tagId')
throw new Exception('Tag not found', 404); 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') App::delete('/v1/functions/:functionId/tags/:tagId')
@ -645,9 +645,9 @@ App::post('/v1/functions/:functionId/executions')
->inject('user') ->inject('user')
->action(function ($functionId, $data, /*$async,*/ $response, $project, $dbForInternal, $user) { ->action(function ($functionId, $data, /*$async,*/ $response, $project, $dbForInternal, $user) {
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */ /** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Database\Document $user */ /** @var Utopia\Database\Document $user */
Authorization::disable(); Authorization::disable();
@ -696,20 +696,20 @@ App::post('/v1/functions/:functionId/executions')
$jwt = ''; // initialize $jwt = ''; // initialize
if (!$user->isEmpty()) { // If userId exists, generate a JWT for function if (!$user->isEmpty()) { // If userId exists, generate a JWT for function
$tokens = $user->getAttribute('tokens', []); $sessions = $user->getAttribute('sessions', []);
$session = new Document(); $current = new Document();
foreach ($tokens as $token) { /** @var Appwrite\Database\Document $token */ foreach ($sessions as $session) { /** @var Utopia\Database\Document $session */
if ($token->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
$session = $token; $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. $jwtObj = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 900, 10); // Instantiate with key, algo, maxAge and leeway.
$jwt = $jwtObj->encode([ $jwt = $jwtObj->encode([
'userId' => $user->getId(), '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->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($execution, Response::MODEL_EXECUTION); $response->dynamic($execution, Response::MODEL_EXECUTION);
}); });
App::get('/v1/functions/:functionId/executions') App::get('/v1/functions/:functionId/executions')
@ -765,7 +765,7 @@ App::get('/v1/functions/:functionId/executions')
new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]), new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]),
], APP_LIMIT_COUNT); ], APP_LIMIT_COUNT);
$response->dynamic2(new Document([ $response->dynamic(new Document([
'executions' => $results, 'executions' => $results,
'sum' => $sum, 'sum' => $sum,
]), Response::MODEL_EXECUTION_LIST); ]), Response::MODEL_EXECUTION_LIST);
@ -808,5 +808,5 @@ App::get('/v1/functions/:functionId/executions/:executionId')
throw new Exception('Execution not found', 404); throw new Exception('Execution not found', 404);
} }
$response->dynamic2($execution, Response::MODEL_EXECUTION); $response->dynamic($execution, Response::MODEL_EXECUTION);
}); });

View file

@ -1,6 +1,6 @@
<?php <?php
use Appwrite\Database\Document; use Utopia\Database\Document;
use Appwrite\Utopia\Response; use Appwrite\Utopia\Response;
use Utopia\App; use Utopia\App;
use Utopia\Config\Config; use Utopia\Config\Config;

View file

@ -134,7 +134,7 @@ App::post('/v1/projects')
$consoleDB->createNamespace($project->getId()); $consoleDB->createNamespace($project->getId());
$response->setStatusCode(Response::STATUS_CODE_CREATED); $response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($project, Response::MODEL_PROJECT); $response->dynamic($project, Response::MODEL_PROJECT);
}); });
App::get('/v1/projects') App::get('/v1/projects')
@ -162,7 +162,7 @@ App::get('/v1/projects')
$results = $dbForConsole->find('projects', $queries, $limit, $offset, ['_id'], [$orderType]); $results = $dbForConsole->find('projects', $queries, $limit, $offset, ['_id'], [$orderType]);
$sum = $dbForConsole->count('projects', $queries, APP_LIMIT_COUNT); $sum = $dbForConsole->count('projects', $queries, APP_LIMIT_COUNT);
$response->dynamic2(new Document([ $response->dynamic(new Document([
'projects' => $results, 'projects' => $results,
'sum' => $sum, 'sum' => $sum,
]), Response::MODEL_PROJECT_LIST); ]), Response::MODEL_PROJECT_LIST);
@ -191,7 +191,7 @@ App::get('/v1/projects/:projectId')
throw new Exception('Project not found', 404); 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') App::get('/v1/projects/:projectId/usage')
@ -440,7 +440,7 @@ App::patch('/v1/projects/:projectId')
->setAttribute('legalTaxId', $legalTaxId) ->setAttribute('legalTaxId', $legalTaxId)
); );
$response->dynamic2($project, Response::MODEL_PROJECT); $response->dynamic($project, Response::MODEL_PROJECT);
}); });
App::patch('/v1/projects/:projectId/oauth2') App::patch('/v1/projects/:projectId/oauth2')
@ -474,7 +474,7 @@ App::patch('/v1/projects/:projectId/oauth2')
->setAttribute('usersOauth2' . \ucfirst($provider) . 'Secret', $secret) ->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') App::patch('/v1/projects/:projectId/auth/limit')
@ -505,7 +505,7 @@ App::patch('/v1/projects/:projectId/auth/limit')
->setAttribute('usersAuthLimit', $limit) ->setAttribute('usersAuthLimit', $limit)
); );
$response->dynamic2($project, Response::MODEL_PROJECT); $response->dynamic($project, Response::MODEL_PROJECT);
}); });
App::patch('/v1/projects/:projectId/auth/:method') App::patch('/v1/projects/:projectId/auth/:method')
@ -540,7 +540,7 @@ App::patch('/v1/projects/:projectId/auth/:method')
->setAttribute($authKey, $status) ->setAttribute($authKey, $status)
); );
$response->dynamic2($project, Response::MODEL_PROJECT); $response->dynamic($project, Response::MODEL_PROJECT);
}); });
App::delete('/v1/projects/:projectId') App::delete('/v1/projects/:projectId')
@ -638,7 +638,7 @@ App::post('/v1/projects/:projectId/webhooks')
); );
$response->setStatusCode(Response::STATUS_CODE_CREATED); $response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($webhook, Response::MODEL_WEBHOOK); $response->dynamic($webhook, Response::MODEL_WEBHOOK);
}); });
App::get('/v1/projects/:projectId/webhooks') App::get('/v1/projects/:projectId/webhooks')
@ -666,7 +666,7 @@ App::get('/v1/projects/:projectId/webhooks')
$webhooks = $project->getAttribute('webhooks', []); $webhooks = $project->getAttribute('webhooks', []);
$response->dynamic2(new Document([ $response->dynamic(new Document([
'webhooks' => $webhooks, 'webhooks' => $webhooks,
'sum' => count($webhooks), 'sum' => count($webhooks),
]), Response::MODEL_WEBHOOK_LIST); ]), Response::MODEL_WEBHOOK_LIST);
@ -702,7 +702,7 @@ App::get('/v1/projects/:projectId/webhooks/:webhookId')
throw new Exception('Webhook not found', 404); 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') App::put('/v1/projects/:projectId/webhooks/:webhookId')
@ -754,7 +754,7 @@ App::put('/v1/projects/:projectId/webhooks/:webhookId')
$dbForConsole->updateDocument('projects', $project->getId(), $project); $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') App::delete('/v1/projects/:projectId/webhooks/:webhookId')
@ -828,7 +828,7 @@ App::post('/v1/projects/:projectId/keys')
); );
$response->setStatusCode(Response::STATUS_CODE_CREATED); $response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($key, Response::MODEL_KEY); $response->dynamic($key, Response::MODEL_KEY);
}); });
App::get('/v1/projects/:projectId/keys') App::get('/v1/projects/:projectId/keys')
@ -856,7 +856,7 @@ App::get('/v1/projects/:projectId/keys')
$keys = $project->getAttribute('keys', []); $keys = $project->getAttribute('keys', []);
$response->dynamic2(new Document([ $response->dynamic(new Document([
'keys' => $keys, 'keys' => $keys,
'sum' => count($keys), 'sum' => count($keys),
]), Response::MODEL_KEY_LIST); ]), Response::MODEL_KEY_LIST);
@ -889,7 +889,7 @@ App::get('/v1/projects/:projectId/keys/:keyId')
throw new Exception('Key not found', 404); 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') App::put('/v1/projects/:projectId/keys/:keyId')
@ -931,7 +931,7 @@ App::put('/v1/projects/:projectId/keys/:keyId')
$dbForConsole->updateDocument('projects', $project->getId(), $project); $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') App::delete('/v1/projects/:projectId/keys/:keyId')
@ -1032,7 +1032,7 @@ App::post('/v1/projects/:projectId/tasks')
} }
$response->setStatusCode(Response::STATUS_CODE_CREATED); $response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($task, Response::MODEL_TASK); $response->dynamic($task, Response::MODEL_TASK);
}); });
App::get('/v1/projects/:projectId/tasks') App::get('/v1/projects/:projectId/tasks')
@ -1060,7 +1060,7 @@ App::get('/v1/projects/:projectId/tasks')
$tasks = $project->getAttribute('tasks', []); $tasks = $project->getAttribute('tasks', []);
$response->dynamic2(new Document([ $response->dynamic(new Document([
'tasks' => $tasks, 'tasks' => $tasks,
'sum' => count($tasks), 'sum' => count($tasks),
]), Response::MODEL_TASK_LIST); ]), Response::MODEL_TASK_LIST);
@ -1097,7 +1097,7 @@ App::get('/v1/projects/:projectId/tasks/:taskId')
throw new Exception('Task not found', 404); 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') 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()); 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') App::delete('/v1/projects/:projectId/tasks/:taskId')
@ -1244,7 +1244,7 @@ App::post('/v1/projects/:projectId/platforms')
); );
$response->setStatusCode(Response::STATUS_CODE_CREATED); $response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($platform, Response::MODEL_PLATFORM); $response->dynamic($platform, Response::MODEL_PLATFORM);
}); });
App::get('/v1/projects/:projectId/platforms') App::get('/v1/projects/:projectId/platforms')
@ -1272,7 +1272,7 @@ App::get('/v1/projects/:projectId/platforms')
$platforms = $project->getAttribute('platforms', []); $platforms = $project->getAttribute('platforms', []);
$response->dynamic2(new Document([ $response->dynamic(new Document([
'platforms' => $platforms, 'platforms' => $platforms,
'sum' => count($platforms), 'sum' => count($platforms),
]), Response::MODEL_PLATFORM_LIST); ]), Response::MODEL_PLATFORM_LIST);
@ -1308,7 +1308,7 @@ App::get('/v1/projects/:projectId/platforms/:platformId')
throw new Exception('Platform not found', 404); 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') App::put('/v1/projects/:projectId/platforms/:platformId')
@ -1363,7 +1363,7 @@ App::put('/v1/projects/:projectId/platforms/:platformId')
$dbForConsole->updateDocument('projects', $project->getId(), $project); $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') App::delete('/v1/projects/:projectId/platforms/:platformId')
@ -1453,7 +1453,7 @@ App::post('/v1/projects/:projectId/domains')
); );
$response->setStatusCode(Response::STATUS_CODE_CREATED); $response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($domain, Response::MODEL_DOMAIN); $response->dynamic($domain, Response::MODEL_DOMAIN);
}); });
App::get('/v1/projects/:projectId/domains') App::get('/v1/projects/:projectId/domains')
@ -1481,7 +1481,7 @@ App::get('/v1/projects/:projectId/domains')
$domains = $project->getAttribute('domains', []); $domains = $project->getAttribute('domains', []);
$response->dynamic2(new Document([ $response->dynamic(new Document([
'domains' => $domains, 'domains' => $domains,
'sum' => count($domains), 'sum' => count($domains),
]), Response::MODEL_DOMAIN_LIST); ]), Response::MODEL_DOMAIN_LIST);
@ -1517,7 +1517,7 @@ App::get('/v1/projects/:projectId/domains/:domainId')
throw new Exception('Domain not found', 404); 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') 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) { 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 $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'), 'domain' => $domain->getAttribute('domain'),
]); ]);
$response->dynamic2($domain, Response::MODEL_DOMAIN); $response->dynamic($domain, Response::MODEL_DOMAIN);
}); });
App::delete('/v1/projects/:projectId/domains/:domainId') App::delete('/v1/projects/:projectId/domains/:domainId')

View file

@ -12,7 +12,7 @@ use Utopia\Cache\Cache;
use Utopia\Cache\Adapter\Filesystem; use Utopia\Cache\Adapter\Filesystem;
use Appwrite\ClamAV\Network; use Appwrite\ClamAV\Network;
use Utopia\Database\Document; use Utopia\Database\Document;
use Appwrite\Database\Validator\UID; use Utopia\Database\Validator\UID;
use Utopia\Storage\Storage; use Utopia\Storage\Storage;
use Utopia\Storage\Validator\File; use Utopia\Storage\Validator\File;
use Utopia\Storage\Validator\FileSize; use Utopia\Storage\Validator\FileSize;
@ -77,7 +77,7 @@ App::post('/v1/storage/buckets')
; ;
$response->setStatusCode(Response::STATUS_CODE_CREATED); $response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($data, Response::MODEL_BUCKET); $response->dynamic($data, Response::MODEL_BUCKET);
}); });
App::get('/v1/storage/buckets') App::get('/v1/storage/buckets')
@ -103,7 +103,7 @@ App::get('/v1/storage/buckets')
$queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, $search)] : []; $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]), 'buckets' => $dbForInternal->find('buckets', $queries, $limit, $offset, ['_id'], [$orderType]),
'sum' => $dbForInternal->count('buckets', $queries, APP_LIMIT_COUNT), 'sum' => $dbForInternal->count('buckets', $queries, APP_LIMIT_COUNT),
]), Response::MODEL_BUCKET_LIST); ]), Response::MODEL_BUCKET_LIST);
@ -133,7 +133,7 @@ App::get('/v1/storage/buckets/:bucketId')
throw new Exception('Bucket not found', 404); 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') App::put('/v1/storage/buckets/:bucketId')
@ -173,6 +173,13 @@ App::put('/v1/storage/buckets/:bucketId')
$read ??= $bucket->getAttribute('$read', []); // By default inherit read permissions $read ??= $bucket->getAttribute('$read', []); // By default inherit read permissions
$write ??= $bucket->getAttribute('$write',[]); // By default inherit write permissions $write ??= $bucket->getAttribute('$write',[]); // By default inherit write permissions
$read??=$bucket->getAttribute('$read', []); // By default inherit read permissions
$write??=$bucket->getAttribute('$write', []); // By default inherit write permissions
$maximumFileSize??=$bucket->getAttribute('maximumFileSize', (int)App::getEnv('_APP_STORAGE_LIMIT', 0));
$allowedFileExtensions??=$bucket->getAttribute('allowedFileExtensions', []);
$enabled??=$bucket->getAttribute('enabled', true);
$encryption??=$bucket->getAttribute('encryption', true);
$antiVirus??=$bucket->getAttribute('antiVirus', true);
$bucket = $dbForInternal->updateDocument('buckets', $bucket->getId(), $bucket $bucket = $dbForInternal->updateDocument('buckets', $bucket->getId(), $bucket
->setAttribute('name',$name) ->setAttribute('name',$name)
@ -191,7 +198,7 @@ App::put('/v1/storage/buckets/:bucketId')
->setParam('data', $bucket->getArrayCopy()) ->setParam('data', $bucket->getArrayCopy())
; ;
$response->dynamic2($bucket, Response::MODEL_BUCKET); $response->dynamic($bucket, Response::MODEL_BUCKET);
}); });
App::delete('/v1/storage/buckets/:bucketId') App::delete('/v1/storage/buckets/:bucketId')
@ -234,7 +241,7 @@ App::delete('/v1/storage/buckets/:bucketId')
} }
$events $events
->setParam('eventData', $response->output2($bucket, Response::MODEL_BUCKET)) ->setParam('eventData', $response->output($bucket, Response::MODEL_BUCKET))
; ;
$audits $audits
@ -275,7 +282,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
/** @var Utopia\Swoole\Request $request */ /** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Database\Document $user */ /** @var Utopia\Database\Document $user */
/** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $usage */ /** @var Appwrite\Event\Event $usage */
@ -399,7 +406,8 @@ App::post('/v1/storage/buckets/:bucketId/files')
; ;
$response->setStatusCode(Response::STATUS_CODE_CREATED); $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') App::get('/v1/storage/buckets/:bucketId/files')
@ -437,7 +445,7 @@ App::get('/v1/storage/buckets/:bucketId/files')
$queries[] = [new Query('name', Query::TYPE_SEARCH, [$search])]; $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]), 'files' => $dbForInternal->find('files', $queries, $limit, $offset, ['_id'], [$orderType]),
'sum' => $dbForInternal->count('files', $queries, APP_LIMIT_COUNT), 'sum' => $dbForInternal->count('files', $queries, APP_LIMIT_COUNT),
]), Response::MODEL_FILE_LIST); ]), Response::MODEL_FILE_LIST);
@ -475,7 +483,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId')
throw new Exception('File not found', 404); 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') App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
@ -827,7 +835,7 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId')
->setParam('resource', 'storage/files/'.$file->getId()) ->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') App::delete('/v1/storage/buckets/:bucketId/files/:fileId')
@ -886,7 +894,7 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId')
; ;
$events $events
->setParam('eventData', $response->output2($file, Response::MODEL_FILE)) ->setParam('eventData', $response->output($file, Response::MODEL_FILE))
; ;
$response->noContent(); $response->noContent();

View file

@ -1,7 +1,6 @@
<?php <?php
use Appwrite\Auth\Auth; use Appwrite\Auth\Auth;
use Appwrite\Database\Validator\UID;
use Appwrite\Detector\Detector; use Appwrite\Detector\Detector;
use Appwrite\Template\Template; use Appwrite\Template\Template;
use Appwrite\Utopia\Response; use Appwrite\Utopia\Response;
@ -19,6 +18,7 @@ use Utopia\Database\Exception\Duplicate;
use Utopia\Database\Query; use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key; use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
App::post('/v1/teams') App::post('/v1/teams')
->desc('Create Team') ->desc('Create Team')
@ -80,7 +80,7 @@ App::post('/v1/teams')
} }
$response->setStatusCode(Response::STATUS_CODE_CREATED); $response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($team, Response::MODEL_TEAM); $response->dynamic($team, Response::MODEL_TEAM);
}); });
App::get('/v1/teams') App::get('/v1/teams')
@ -109,7 +109,7 @@ App::get('/v1/teams')
$results = $dbForInternal->find('teams', $queries, $limit, $offset, ['_id'], [$orderType]); $results = $dbForInternal->find('teams', $queries, $limit, $offset, ['_id'], [$orderType]);
$sum = $dbForInternal->count('teams', $queries, APP_LIMIT_COUNT); $sum = $dbForInternal->count('teams', $queries, APP_LIMIT_COUNT);
$response->dynamic2(new Document([ $response->dynamic(new Document([
'teams' => $results, 'teams' => $results,
'sum' => $sum, 'sum' => $sum,
]), Response::MODEL_TEAM_LIST); ]), Response::MODEL_TEAM_LIST);
@ -139,7 +139,7 @@ App::get('/v1/teams/:teamId')
throw new Exception('Team not found', 404); throw new Exception('Team not found', 404);
} }
$response->dynamic2($team, Response::MODEL_TEAM); $response->dynamic($team, Response::MODEL_TEAM);
}); });
App::put('/v1/teams/:teamId') App::put('/v1/teams/:teamId')
@ -170,7 +170,7 @@ App::put('/v1/teams/:teamId')
$team = $dbForInternal->updateDocument('teams', $team->getId(), $team->setAttribute('name', $name)); $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') App::delete('/v1/teams/:teamId')
@ -222,7 +222,7 @@ App::delete('/v1/teams/:teamId')
; ;
$events $events
->setParam('eventData', $response->output2($team, Response::MODEL_TEAM)) ->setParam('eventData', $response->output($team, Response::MODEL_TEAM))
; ;
$response->noContent(); $response->noContent();
@ -256,8 +256,8 @@ App::post('/v1/teams/:teamId/memberships')
->inject('mails') ->inject('mails')
->action(function ($teamId, $email, $name, $roles, $url, $response, $project, $user, $dbForInternal, $locale, $audits, $mails) { ->action(function ($teamId, $email, $name, $roles, $url, $response, $project, $user, $dbForInternal, $locale, $audits, $mails) {
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */ /** @var Utopia\Database\Document $project */
/** @var Appwrite\Database\Document $user */ /** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $mails */ /** @var Appwrite\Event\Event $mails */
@ -409,7 +409,7 @@ App::post('/v1/teams/:teamId/memberships')
; ;
$response->setStatusCode(Response::STATUS_CODE_CREATED); $response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($membership $response->dynamic($membership
->setAttribute('email', $email) ->setAttribute('email', $email)
->setAttribute('name', $name) ->setAttribute('name', $name)
, Response::MODEL_MEMBERSHIP); , Response::MODEL_MEMBERSHIP);
@ -457,7 +457,7 @@ App::get('/v1/teams/:teamId/memberships')
$users[] = new Document(\array_merge($temp, $membership->getArrayCopy())); $users[] = new Document(\array_merge($temp, $membership->getArrayCopy()));
} }
$response->dynamic2(new Document([ $response->dynamic(new Document([
'memberships' => $users, 'memberships' => $users,
'sum' => $sum, 'sum' => $sum,
]), Response::MODEL_MEMBERSHIP_LIST); ]), 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) { ->action(function ($teamId, $membershipId, $roles, $request, $response, $user, $dbForInternal, $audits) {
/** @var Utopia\Swoole\Request $request */ /** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $user */ /** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $audits */
@ -525,7 +525,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
->setParam('resource', 'teams/'.$teamId) ->setParam('resource', 'teams/'.$teamId)
; ;
$response->dynamic2($membership, Response::MODEL_MEMBERSHIP); $response->dynamic($membership, Response::MODEL_MEMBERSHIP);
}); });
App::patch('/v1/teams/:teamId/memberships/:membershipId/status') 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) { ->action(function ($teamId, $membershipId, $userId, $secret, $request, $response, $user, $dbForInternal, $geodb, $audits) {
/** @var Utopia\Swoole\Request $request */ /** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $user */ /** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Database\Database $dbForInternal */
/** @var MaxMind\Db\Reader $geodb */ /** @var MaxMind\Db\Reader $geodb */
/** @var Appwrite\Event\Event $audits */ /** @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')) ->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('email', $user->getAttribute('email'))
->setAttribute('name', $user->getAttribute('name')) ->setAttribute('name', $user->getAttribute('name'))
, Response::MODEL_MEMBERSHIP); , Response::MODEL_MEMBERSHIP);
@ -744,7 +744,7 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
; ;
$events $events
->setParam('eventData', $response->output2($membership, Response::MODEL_MEMBERSHIP)) ->setParam('eventData', $response->output($membership, Response::MODEL_MEMBERSHIP))
; ;
$response->noContent(); $response->noContent();

View file

@ -65,7 +65,7 @@ App::post('/v1/users')
} }
$response->setStatusCode(Response::STATUS_CODE_CREATED); $response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($user, Response::MODEL_USER); $response->dynamic($user, Response::MODEL_USER);
}); });
App::get('/v1/users') App::get('/v1/users')
@ -92,7 +92,7 @@ App::get('/v1/users')
$results = $dbForInternal->find('users', [], $limit, $offset, ['_id'], [$orderType]); $results = $dbForInternal->find('users', [], $limit, $offset, ['_id'], [$orderType]);
$sum = $dbForInternal->count('users', [], APP_LIMIT_COUNT); $sum = $dbForInternal->count('users', [], APP_LIMIT_COUNT);
$response->dynamic2(new Document([ $response->dynamic(new Document([
'users' => $results, 'users' => $results,
'sum' => $sum, 'sum' => $sum,
]), Response::MODEL_USER_LIST); ]), Response::MODEL_USER_LIST);
@ -122,7 +122,7 @@ App::get('/v1/users/:userId')
throw new Exception('User not found', 404); 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') App::get('/v1/users/:userId/prefs')
@ -151,7 +151,7 @@ App::get('/v1/users/:userId/prefs')
$prefs = $user->getAttribute('prefs', new \stdClass()); $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') App::get('/v1/users/:userId/sessions')
@ -194,7 +194,7 @@ App::get('/v1/users/:userId/sessions')
$sessions[$key] = $session; $sessions[$key] = $session;
} }
$response->dynamic2(new Document([ $response->dynamic(new Document([
'sessions' => $sessions, 'sessions' => $sessions,
'sum' => count($sessions), 'sum' => count($sessions),
]), Response::MODEL_SESSION_LIST); ]), Response::MODEL_SESSION_LIST);
@ -218,7 +218,7 @@ App::get('/v1/users/:userId/logs')
->inject('geodb') ->inject('geodb')
->action(function ($userId, $response, $dbForInternal, $locale, $geodb) { ->action(function ($userId, $response, $dbForInternal, $locale, $geodb) {
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */ /** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Locale\Locale $locale */ /** @var Utopia\Locale\Locale $locale */
/** @var MaxMind\Db\Reader $geodb */ /** @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') 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)); $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') 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)); $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') 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)); $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') App::delete('/v1/users/:userId/sessions/:sessionId')
@ -440,7 +440,7 @@ App::delete('/v1/users/:userId/sessions/:sessionId')
$user->setAttribute('sessions', $sessions); $user->setAttribute('sessions', $sessions);
$events $events
->setParam('eventData', $response->output2($user, Response::MODEL_USER)) ->setParam('eventData', $response->output($user, Response::MODEL_USER))
; ;
$dbForInternal->updateDocument('users', $user->getId(), $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', [])); $dbForInternal->updateDocument('users', $user->getId(), $user->getAttribute('sessions', []));
$events $events
->setParam('eventData', $response->output2($user, Response::MODEL_USER)) ->setParam('eventData', $response->output($user, Response::MODEL_USER))
; ;
$response->noContent(); $response->noContent();
@ -535,7 +535,7 @@ App::delete('/v1/users/:userId')
; ;
$events $events
->setParam('eventData', $response->output2($user, Response::MODEL_USER)) ->setParam('eventData', $response->output($user, Response::MODEL_USER))
; ;
// TODO : Response filter implementation // TODO : Response filter implementation

View file

@ -10,16 +10,14 @@ use Utopia\Exception;
use Utopia\Config\Config; use Utopia\Config\Config;
use Utopia\Domains\Domain; use Utopia\Domains\Domain;
use Appwrite\Auth\Auth; use Appwrite\Auth\Auth;
use Appwrite\Database\Validator\Authorization;
use Appwrite\Network\Validator\Origin; use Appwrite\Network\Validator\Origin;
use Appwrite\Utopia\Response\Filters\V06; use Appwrite\Utopia\Response\Filters\V06;
use Appwrite\Utopia\Response\Filters\V07; use Appwrite\Utopia\Response\Filters\V07;
use Appwrite\Utopia\Response\Filters\V08; use Appwrite\Utopia\Response\Filters\V08;
use Utopia\CLI\Console; use Utopia\CLI\Console;
use Utopia\Database\Database;
use Utopia\Database\Document; use Utopia\Database\Document;
use Utopia\Database\Query; use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization as Authorization2; use Utopia\Database\Validator\Authorization;
Config::setParam('domainVerification', false); Config::setParam('domainVerification', false);
Config::setParam('cookieDomain', 'localhost'); Config::setParam('cookieDomain', 'localhost');
@ -44,7 +42,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons
$domains[$domain->get()] = false; $domains[$domain->get()] = false;
Console::warning($domain->get() . ' is not a publicly accessible domain. Skipping SSL certificate generation.'); Console::warning($domain->get() . ' is not a publicly accessible domain. Skipping SSL certificate generation.');
} else { } else {
Authorization2::disable(); Authorization::disable();
$certificate = $dbForConsole->findFirst('certificates', [ $certificate = $dbForConsole->findFirst('certificates', [
new Query('domain', QUERY::TYPE_EQUAL, [$domain->get()]) new Query('domain', QUERY::TYPE_EQUAL, [$domain->get()])
@ -55,7 +53,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons
'domain' => $domain->get(), 'domain' => $domain->get(),
]); ]);
$certificate = $dbForConsole->createDocument('certificates', $certificate); $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...'); 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, 'validateCNAME' => false,
]); ]);
} else { } else {
Authorization2::enable(); // ensure authorization is reenabled Authorization::enable(); // ensure authorization is reenabled
} }
$domains[$domain->get()] = true; $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', [])); $scopes = \array_merge($roles[$role]['scopes'], $key->getAttribute('scopes', []));
Authorization::setDefaultStatus(false); // Cancel security segmentation for API keys. Authorization::setDefaultStatus(false); // Cancel security segmentation for API keys.
Authorization2::setDefaultStatus(false); // Cancel security segmentation for API keys.
} }
} }
if ($user->getId()) { if ($user->getId()) {
Authorization::setRole('user:'.$user->getId()); Authorization::setRole('user:'.$user->getId());
Authorization2::setRole('user:'.$user->getId());
} }
Authorization::setRole('role:'.$role); Authorization::setRole('role:'.$role);
Authorization2::setRole('role:'.$role);
\array_map(function ($node) { \array_map(function ($node) {
if (isset($node['teamId']) && isset($node['roles'])) { if (isset($node['teamId']) && isset($node['roles'])) {
Authorization::setRole('team:'.$node['teamId']); Authorization::setRole('team:'.$node['teamId']);
Authorization2::setRole('team:'.$node['teamId']);
foreach ($node['roles'] as $nodeRole) { // Set all team roles foreach ($node['roles'] as $nodeRole) { // Set all team roles
Authorization::setRole('team:'.$node['teamId'].'/'.$nodeRole); Authorization::setRole('team:'.$node['teamId'].'/'.$nodeRole);
Authorization2::setRole('team:'.$node['teamId'].'/'.$nodeRole);
} }
} }
}, $user->getAttribute('memberships', [])); }, $user->getAttribute('memberships', []));
@ -305,7 +298,7 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) {
/** @var Utopia\Swoole\Request $request */ /** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Utopia\View $layout */ /** @var Utopia\View $layout */
/** @var Appwrite\Database\Document $project */ /** @var Utopia\Database\Document $project */
if ($error instanceof PDOException) { if ($error instanceof PDOException) {
throw $error; throw $error;
@ -393,7 +386,7 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) {
$response->html($layout->render()); $response->html($layout->render());
} }
$response->dynamic2(new Document($output), $response->dynamic(new Document($output),
$utopia->isDevelopment() ? Response::MODEL_ERROR_DEV : Response::MODEL_ERROR); $utopia->isDevelopment() ? Response::MODEL_ERROR_DEV : Response::MODEL_ERROR);
}, ['error', 'utopia', 'request', 'response', 'layout', 'project']); }, ['error', 'utopia', 'request', 'response', 'layout', 'project']);

View file

@ -2,7 +2,7 @@
global $utopia, $request, $response; global $utopia, $request, $response;
use Appwrite\Database\Document; use Utopia\Database\Document;
use Appwrite\Network\Validator\Host; use Appwrite\Network\Validator\Host;
use Appwrite\Utopia\Response; use Appwrite\Utopia\Response;
use Utopia\App; use Utopia\App;

View file

@ -1,7 +1,7 @@
<?php <?php
use Appwrite\Auth\Auth; use Appwrite\Auth\Auth;
use Appwrite\Database\Validator\Authorization; use Utopia\Database\Validator\Authorization;
use Utopia\App; use Utopia\App;
use Utopia\Exception; use Utopia\Exception;
use Utopia\Abuse\Abuse; use Utopia\Abuse\Abuse;
@ -120,8 +120,8 @@ App::init(function ($utopia, $request, $response, $project, $user) {
/** @var Utopia\App $utopia */ /** @var Utopia\App $utopia */
/** @var Utopia\Swoole\Request $request */ /** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */ /** @var Utopia\Database\Document $project */
/** @var Appwrite\Database\Document $user */ /** @var Utopia\Database\Document $user */
/** @var Utopia\Registry\Registry $register */ /** @var Utopia\Registry\Registry $register */
/** @var Appwrite\Event\Event $events */ /** @var Appwrite\Event\Event $events */
/** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $audits */
@ -174,7 +174,7 @@ App::shutdown(function ($utopia, $request, $response, $project, $events, $audits
/** @var Utopia\App $utopia */ /** @var Utopia\App $utopia */
/** @var Utopia\Swoole\Request $request */ /** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */ /** @var Utopia\Database\Document $project */
/** @var Appwrite\Event\Event $events */ /** @var Appwrite\Event\Event $events */
/** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $usage */ /** @var Appwrite\Event\Event $usage */

View file

@ -1,6 +1,5 @@
<?php <?php
use Appwrite\Database\Database;
use Appwrite\Specification\Format\OpenAPI3; use Appwrite\Specification\Format\OpenAPI3;
use Appwrite\Specification\Format\Swagger2; use Appwrite\Specification\Format\Swagger2;
use Appwrite\Specification\Specification; use Appwrite\Specification\Specification;
@ -8,7 +7,6 @@ use Utopia\App;
use Utopia\View; use Utopia\View;
use Utopia\Config\Config; use Utopia\Config\Config;
use Utopia\Exception; use Utopia\Exception;
use Utopia\Validator\Boolean;
use Utopia\Validator\Range; use Utopia\Validator\Range;
use Utopia\Validator\WhiteList; use Utopia\Validator\WhiteList;

View file

@ -2,7 +2,6 @@
require_once __DIR__.'/../vendor/autoload.php'; require_once __DIR__.'/../vendor/autoload.php';
use Appwrite\Database\Validator\Authorization;
use Appwrite\Utopia\Response; use Appwrite\Utopia\Response;
use Swoole\Process; use Swoole\Process;
use Swoole\Http\Server; use Swoole\Http\Server;
@ -11,7 +10,7 @@ use Swoole\Http\Response as SwooleResponse;
use Utopia\App; use Utopia\App;
use Utopia\CLI\Console; use Utopia\CLI\Console;
use Utopia\Config\Config; use Utopia\Config\Config;
use Utopia\Database\Validator\Authorization as Authorization2; use Utopia\Database\Validator\Authorization;
use Utopia\Audit\Audit; use Utopia\Audit\Audit;
use Utopia\Abuse\Adapters\TimeLimit; use Utopia\Abuse\Adapters\TimeLimit;
use Utopia\Database\Document; use Utopia\Database\Document;
@ -54,8 +53,25 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) {
$app = new App('UTC'); $app = new App('UTC');
go(function() use ($register, $app) { go(function() use ($register, $app) {
$db = $register->get('dbPool')->get(); // wait for database to be ready
$redis = $register->get('redisPool')->get(); $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) { App::setResource('db', function () use (&$db) {
return $db; return $db;
@ -69,9 +85,6 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) {
return $app; return $app;
}); });
// wait for database to be ready
sleep(5);
$dbForConsole = $app->getResource('dbForConsole'); /** @var Utopia\Database\Database $dbForConsole */ $dbForConsole = $app->getResource('dbForConsole'); /** @var Utopia\Database\Database $dbForConsole */
if(!$dbForConsole->exists()) { if(!$dbForConsole->exists()) {
@ -170,9 +183,6 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo
Authorization::cleanRoles(); Authorization::cleanRoles();
Authorization::setRole('role:all'); Authorization::setRole('role:all');
Authorization2::cleanRoles();
Authorization2::setRole('role:all');
$app->run($request, $response); $app->run($request, $response);
} catch (\Throwable $th) { } catch (\Throwable $th) {
Console::error('[Error] Type: '.get_class($th)); Console::error('[Error] Type: '.get_class($th));

View file

@ -24,7 +24,6 @@ use Appwrite\Database\Database;
use Appwrite\Database\Adapter\MySQL as MySQLAdapter; use Appwrite\Database\Adapter\MySQL as MySQLAdapter;
use Appwrite\Database\Adapter\Redis as RedisAdapter; use Appwrite\Database\Adapter\Redis as RedisAdapter;
use Appwrite\Database\Document; use Appwrite\Database\Document;
use Appwrite\Database\Validator\Authorization;
use Appwrite\Event\Event; use Appwrite\Event\Event;
use Appwrite\OpenSSL\OpenSSL; use Appwrite\OpenSSL\OpenSSL;
use Utopia\App; use Utopia\App;
@ -39,7 +38,7 @@ use Utopia\Cache\Cache;
use Utopia\Database\Adapter\MariaDB; use Utopia\Database\Adapter\MariaDB;
use Utopia\Database\Document as Document2; use Utopia\Database\Document as Document2;
use Utopia\Database\Database as Database2; 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\PDOConfig;
use Swoole\Database\PDOPool; use Swoole\Database\PDOPool;
use Swoole\Database\RedisConfig; use Swoole\Database\RedisConfig;
@ -58,8 +57,8 @@ const APP_LIMIT_USERS = 10000;
const APP_LIMIT_ANTIVIRUS = 20971520; //20MB const APP_LIMIT_ANTIVIRUS = 20971520; //20MB
const APP_LIMIT_ENCRYPTION = 20971520; //20MB const APP_LIMIT_ENCRYPTION = 20971520; //20MB
const APP_LIMIT_COMPRESSION = 20971520; //20MB const APP_LIMIT_COMPRESSION = 20971520; //20MB
const APP_CACHE_BUSTER = 149; const APP_CACHE_BUSTER = 150;
const APP_VERSION_STABLE = '0.9.1'; const APP_VERSION_STABLE = '0.9.2';
const APP_STORAGE_UPLOADS = '/storage/uploads'; const APP_STORAGE_UPLOADS = '/storage/uploads';
const APP_STORAGE_FUNCTIONS = '/storage/functions'; const APP_STORAGE_FUNCTIONS = '/storage/functions';
const APP_STORAGE_CACHE = '/storage/cache'; const APP_STORAGE_CACHE = '/storage/cache';
@ -443,7 +442,6 @@ App::setResource('user', function($mode, $project, $console, $request, $response
/** @var string $mode */ /** @var string $mode */
Authorization::setDefaultStatus(true); Authorization::setDefaultStatus(true);
Authorization2::setDefaultStatus(true);
Auth::setCookieName('a_session_'.$project->getId()); 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 (APP_MODE_ADMIN === $mode) {
if ($user->find('teamId', $project->getAttribute('teamId'), 'memberships')) { if ($user->find('teamId', $project->getAttribute('teamId'), 'memberships')) {
Authorization::setDefaultStatus(false); // Cancel security segmentation for admin users. Authorization::setDefaultStatus(false); // Cancel security segmentation for admin users.
Authorization2::setDefaultStatus(false); // Cancel security segmentation for admin users.
} else { } else {
$user = new Document2(['$id' => '', '$collection' => 'users']); $user = new Document2(['$id' => '', '$collection' => 'users']);
} }
@ -533,12 +530,10 @@ App::setResource('project', function($dbForConsole, $request, $console) {
} }
Authorization::disable(); Authorization::disable();
Authorization2::disable();
$project = $dbForConsole->getDocument('projects', $projectId); $project = $dbForConsole->getDocument('projects', $projectId);
Authorization::reset(); Authorization::reset();
Authorization2::reset();
return $project; return $project;
}, ['dbForConsole', 'request', 'console']); }, ['dbForConsole', 'request', 'console']);

View file

@ -23,6 +23,7 @@ $register->set('db', function () {
return $pdo; return $pdo;
}); });
$register->set('cache', function () { // Register cache connection $register->set('cache', function () { // Register cache connection
$redis = new Redis(); $redis = new Redis();
$redis->pconnect(App::getEnv('_APP_REDIS_HOST', ''), App::getEnv('_APP_REDIS_PORT', '')); $redis->pconnect(App::getEnv('_APP_REDIS_HOST', ''), App::getEnv('_APP_REDIS_PORT', ''));
@ -30,3 +31,4 @@ $register->set('cache', function () { // Register cache connection
return $redis; return $redis;
}); });

View file

@ -2,11 +2,7 @@
use Appwrite\Resque\Worker; use Appwrite\Resque\Worker;
use Utopia\Audit\Audit; use Utopia\Audit\Audit;
use Utopia\Cache\Adapter\Redis;
use Utopia\Cache\Cache;
use Utopia\CLI\Console; use Utopia\CLI\Console;
use Utopia\Database\Adapter\MariaDB;
use Utopia\Database\Database;
require_once __DIR__.'/../workers.php'; require_once __DIR__.'/../workers.php';
@ -23,8 +19,6 @@ class AuditsV1 extends Worker
public function run(): void public function run(): void
{ {
global $register;
$projectId = $this->args['projectId']; $projectId = $this->args['projectId'];
$userId = $this->args['userId']; $userId = $this->args['userId'];
$event = $this->args['event']; $event = $this->args['event'];
@ -32,12 +26,8 @@ class AuditsV1 extends Worker
$userAgent = $this->args['userAgent']; $userAgent = $this->args['userAgent'];
$ip = $this->args['ip']; $ip = $this->args['ip'];
$data = $this->args['data']; $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 = new Audit($dbForInternal);
$audit->log($userId, $event, $resource, $userAgent, $ip, '', $data); $audit->log($userId, $event, $resource, $userAgent, $ip, '', $data);

View file

@ -3,13 +3,9 @@
use Appwrite\Network\Validator\CNAME; use Appwrite\Network\Validator\CNAME;
use Appwrite\Resque\Worker; use Appwrite\Resque\Worker;
use Utopia\App; use Utopia\App;
use Utopia\Cache\Adapter\Redis;
use Utopia\Cache\Cache;
use Utopia\CLI\Console; use Utopia\CLI\Console;
use Utopia\Database\Database;
use Utopia\Database\Document; use Utopia\Database\Document;
use Utopia\Database\Query; use Utopia\Database\Query;
use Utopia\Database\Adapter\MariaDB;
use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Authorization;
use Utopia\Domains\Domain; use Utopia\Domains\Domain;
@ -28,180 +24,167 @@ class CertificatesV1 extends Worker
public function run(): void public function run(): void
{ {
global $register; $dbForConsole = $this->getConsoleDB();
go(function() use ($register) { /**
$db = $register->get('dbPool')->get(); * 1. Get new domain document - DONE
$redis = $register->get('redisPool')->get(); * 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)); Authorization::disable();
$dbForConsole = new Database(new MariaDB($db), $cache);
$dbForConsole->setNamespace('project_console_internal');
/** // Args
* 1. Get new domain document - DONE $document = $this->args['document'];
* 1.1. Validate domain is valid, public suffix is known and CNAME records are verified - DONE $domain = $this->args['domain'];
* 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
*/
Authorization::disable(); // Validation Args
$validateTarget = $this->args['validateTarget'] ?? true;
$validateCNAME = $this->args['validateCNAME'] ?? true;
// Args // Options
$document = $this->args['document']; $domain = new Domain((!empty($domain)) ? $domain : '');
$domain = $this->args['domain']; $expiry = 60 * 60 * 24 * 30 * 2; // 60 days
$safety = 60 * 60; // 1 hour
$renew = (\time() + $expiry);
// Validation Args if(empty($domain->get())) {
$validateTarget = $this->args['validateTarget'] ?? true; throw new Exception('Missing domain');
$validateCNAME = $this->args['validateCNAME'] ?? true; }
// Options if(!$domain->isKnown() || $domain->isTest()) {
$domain = new Domain((!empty($domain)) ? $domain : ''); throw new Exception('Unknown public suffix for domain');
$expiry = 60 * 60 * 24 * 30 * 2; // 60 days }
$safety = 60 * 60; // 1 hour
$renew = (\time() + $expiry);
if(empty($domain->get())) { if($validateTarget) {
throw new Exception('Missing domain'); $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(!$domain->isKnown() || $domain->isTest()) { if($validateCNAME) {
throw new Exception('Unknown public suffix for domain'); $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($validateTarget) { $certificate = $dbForConsole->findFirst('certificates', [
$target = new Domain(App::getEnv('_APP_DOMAIN_TARGET', '')); new Query('domain', QUERY::TYPE_EQUAL, [$domain->get()])
], /*limit*/ 1);
if(!$target->isKnown() || $target->isTest()) { // $condition = ($certificate
throw new Exception('Unreachable CNAME target ('.$target->get().'), please use a domain with a public suffix.'); // && $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);
$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');
}
$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...');
} }
}
if($validateCNAME) { if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/cert.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/cert.pem')) {
$validator = new CNAME($target->get()); // Verify Domain with DNS records throw new Exception('Failed to rename certificate cert.pem: '.\json_encode($stdout));
}
if(!$validator->isValid($domain->get())) { if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/chain.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/chain.pem')) {
throw new Exception('Failed to verify domain DNS records'); throw new Exception('Failed to rename certificate chain.pem: '.\json_encode($stdout));
} }
}
$certificate = $dbForConsole->findFirst('certificates', [ if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/fullchain.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/fullchain.pem')) {
new Query('domain', QUERY::TYPE_EQUAL, [$domain->get()]) throw new Exception('Failed to rename certificate fullchain.pem: '.\json_encode($stdout));
], /*limit*/ 1); }
// $condition = ($certificate if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/privkey.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/privkey.pem')) {
// && $certificate instanceof Document throw new Exception('Failed to rename certificate privkey.pem: '.\json_encode($stdout));
// && 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); $certificate = new Document(\array_merge($certificate, [
'domain' => $domain->get(),
'issueDate' => \time(),
'renewDate' => $renew,
'attempts' => 0,
'log' => \json_encode($stdout),
]));
$certificate = (!empty($certificate) && $certificate instanceof $certificate) ? $certificate->getArrayCopy() : []; $certificate = $dbForConsole->createDocument('certificates', $certificate);
if(!empty($certificate) if(!$certificate) {
&& isset($certificate['issueDate']) throw new Exception('Failed saving certificate to DB');
&& (($certificate['issueDate'] + ($expiry)) > \time())) { // Check last issue time }
throw new Exception('Renew isn\'t required');
}
$staging = (App::isProduction()) ? '' : ' --dry-run'; if(!empty($document)) {
$email = App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS'); $certificate = new Document(\array_merge($document, [
'updated' => \time(),
if(empty($email)) { 'certificateId' => $certificate->getId(),
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...');
}
}
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(!@\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),
])); ]));
$certificate = $dbForConsole->createDocument('certificates', $certificate); $certificate = $dbForConsole->updateDocument('certificates', $certificate->getId(), $certificate);
if(!$certificate) { if(!$certificate) {
throw new Exception('Failed saving certificate to DB'); throw new Exception('Failed saving domain to DB');
} }
}
if(!empty($document)) { $config =
$certificate = new Document(\array_merge($document, [ "tls:
'updated' => \time(), certificates:
'certificateId' => $certificate->getId(), - certFile: /storage/certificates/{$domain->get()}/fullchain.pem
])); keyFile: /storage/certificates/{$domain->get()}/privkey.pem";
$certificate = $dbForConsole->updateDocument('certificates', $certificate->getId(), $certificate); if(!\file_put_contents(APP_STORAGE_CONFIG.'/'.$domain->get().'.yml', $config)) {
throw new Exception('Failed to save SSL configuration');
}
if(!$certificate) { ResqueScheduler::enqueueAt($renew + $safety, 'v1-certificates', 'CertificatesV1', [
throw new Exception('Failed saving domain to DB'); 'document' => [],
} 'domain' => $domain->get(),
} 'validateTarget' => $validateTarget,
'validateCNAME' => $validateCNAME,
]); // Async task rescheduale
$config = Authorization::reset();
"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');
}
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);
});
} }
public function shutdown(): void public function shutdown(): void

View file

@ -1,14 +1,10 @@
<?php <?php
use Appwrite\Resque\Worker; use Appwrite\Resque\Worker;
use Utopia\Cache\Cache;
use Utopia\Cache\Adapter\Redis as RedisCache;
use Utopia\CLI\Console; use Utopia\CLI\Console;
use Utopia\Database\Database;
use Utopia\Database\Document; use Utopia\Database\Document;
use Utopia\Database\Adapter\MariaDB;
require_once __DIR__.'/../init.php'; require_once __DIR__.'/../workers.php';
Console::title('Database V1 Worker'); Console::title('Database V1 Worker');
Console::success(APP_NAME.' database worker v1 has started'."\n"); Console::success(APP_NAME.' database worker v1 has started'."\n");
@ -131,53 +127,4 @@ class DatabaseV1 extends Worker
$success = $dbForExternal->deleteIndex($collectionId, $id); $success = $dbForExternal->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;
}
} }

View file

@ -3,15 +3,14 @@
use Utopia\Database\Database; use Utopia\Database\Database;
use Utopia\Database\Document; use Utopia\Database\Document;
use Utopia\Database\Query; use Utopia\Database\Query;
use Utopia\Cache\Adapter\Redis as RedisCache;
use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Authorization;
use Appwrite\Resque\Worker; use Appwrite\Resque\Worker;
use Utopia\Storage\Device\Local; use Utopia\Storage\Device\Local;
use Utopia\Abuse\Abuse; use Utopia\Abuse\Abuse;
use Utopia\Abuse\Adapters\TimeLimit; use Utopia\Abuse\Adapters\TimeLimit;
use Utopia\CLI\Console; use Utopia\CLI\Console;
use Utopia\Config\Config;
use Utopia\Audit\Audit; use Utopia\Audit\Audit;
use Utopia\Cache\Adapter\Redis as RedisCache;
use Utopia\Cache\Cache; use Utopia\Cache\Cache;
use Utopia\Database\Adapter\MariaDB; use Utopia\Database\Adapter\MariaDB;

View file

@ -6,11 +6,8 @@ use Appwrite\Utopia\Response\Model\Execution;
use Cron\CronExpression; use Cron\CronExpression;
use Swoole\Runtime; use Swoole\Runtime;
use Utopia\App; use Utopia\App;
use Utopia\Cache\Adapter\Redis;
use Utopia\Cache\Cache;
use Utopia\CLI\Console; use Utopia\CLI\Console;
use Utopia\Config\Config; use Utopia\Config\Config;
use Utopia\Database\Adapter\MariaDB;
use Utopia\Database\Database; use Utopia\Database\Database;
use Utopia\Database\Document; use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Authorization;
@ -139,9 +136,6 @@ class FunctionsV1 extends Worker
{ {
global $register; global $register;
$db = $register->get('db');
$cache = $register->get('cache');
$projectId = $this->args['projectId'] ?? ''; $projectId = $this->args['projectId'] ?? '';
$functionId = $this->args['functionId'] ?? ''; $functionId = $this->args['functionId'] ?? '';
$webhooks = $this->args['webhooks'] ?? []; $webhooks = $this->args['webhooks'] ?? [];
@ -154,9 +148,7 @@ class FunctionsV1 extends Worker
$userId = $this->args['userId'] ?? ''; $userId = $this->args['userId'] ?? '';
$jwt = $this->args['jwt'] ?? ''; $jwt = $this->args['jwt'] ?? '';
$cache = new Cache(new Redis($cache)); $database = $this->getInternalDB($projectId);
$database = new Database(new MariaDB($db), $cache);
$database->setNamespace('project_'.$projectId.'_internal');
switch ($trigger) { switch ($trigger) {
case 'event': case 'event':
@ -413,15 +405,24 @@ class FunctionsV1 extends Worker
" --workdir /usr/local/src". " --workdir /usr/local/src".
" ".\implode(" ", $vars). " ".\implode(" ", $vars).
" {$runtime['image']}". " {$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); , '', $stdout, $stderr, 30);
$executionEnd = \microtime(true);
if($exitCode !== 0) { if($exitCode !== 0) {
throw new Exception('Failed to create function environment: '.$stderr); 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] = [ $list[$container] = [
'name' => $container, 'name' => $container,
'online' => true, 'online' => true,

View file

@ -28,11 +28,6 @@ class TasksV1 extends Worker
public function run(): void public function run(): void
{ {
global $register;
$db = $register->get('db');
$cache = $register->get('cache');
$projectId = $this->args['projectId'] ?? null; $projectId = $this->args['projectId'] ?? null;
$taskId = $this->args['$id'] ?? null; $taskId = $this->args['$id'] ?? null;
$updated = $this->args['updated'] ?? null; $updated = $this->args['updated'] ?? null;
@ -44,9 +39,7 @@ class TasksV1 extends Worker
$logLimit = 5; $logLimit = 5;
$alert = ''; $alert = '';
$cache = new Cache(new Redis($cache)); $dbForConsole = $this->getConsoleDB();
$dbForConsole = new Database(new MariaDB($db), $cache);
$dbForConsole->setNamespace('project_console_internal');
/* /*
* 1. Get Original Task * 1. Get Original Task

56
composer.lock generated
View file

@ -2079,16 +2079,16 @@
}, },
{ {
"name": "utopia-php/framework", "name": "utopia-php/framework",
"version": "0.16.1", "version": "0.16.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/utopia-php/framework.git", "url": "https://github.com/utopia-php/framework.git",
"reference": "e7440b91077ccf2f4f3908fde4f31d177f8ea692" "reference": "df02354a670df366b92e2e927fbf128be9a8e64e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/utopia-php/framework/zipball/e7440b91077ccf2f4f3908fde4f31d177f8ea692", "url": "https://api.github.com/repos/utopia-php/framework/zipball/df02354a670df366b92e2e927fbf128be9a8e64e",
"reference": "e7440b91077ccf2f4f3908fde4f31d177f8ea692", "reference": "df02354a670df366b92e2e927fbf128be9a8e64e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2122,9 +2122,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/utopia-php/framework/issues", "issues": "https://github.com/utopia-php/framework/issues",
"source": "https://github.com/utopia-php/framework/tree/0.16.1" "source": "https://github.com/utopia-php/framework/tree/0.16.2"
}, },
"time": "2021-07-18T10:59:00+00:00" "time": "2021-07-20T10:24:56+00:00"
}, },
{ {
"name": "utopia-php/image", "name": "utopia-php/image",
@ -3367,16 +3367,16 @@
}, },
{ {
"name": "nikic/php-parser", "name": "nikic/php-parser",
"version": "v4.11.0", "version": "v4.12.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/nikic/PHP-Parser.git", "url": "https://github.com/nikic/PHP-Parser.git",
"reference": "fe14cf3672a149364fb66dfe11bf6549af899f94" "reference": "6608f01670c3cc5079e18c1dab1104e002579143"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/fe14cf3672a149364fb66dfe11bf6549af899f94", "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6608f01670c3cc5079e18c1dab1104e002579143",
"reference": "fe14cf3672a149364fb66dfe11bf6549af899f94", "reference": "6608f01670c3cc5079e18c1dab1104e002579143",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3417,9 +3417,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/nikic/PHP-Parser/issues", "issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v4.11.0" "source": "https://github.com/nikic/PHP-Parser/tree/v4.12.0"
}, },
"time": "2021-07-03T13:36:55+00:00" "time": "2021-07-21T10:44:31+00:00"
}, },
{ {
"name": "openlss/lib-array2xml", "name": "openlss/lib-array2xml",
@ -3476,16 +3476,16 @@
}, },
{ {
"name": "phar-io/manifest", "name": "phar-io/manifest",
"version": "2.0.1", "version": "2.0.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phar-io/manifest.git", "url": "https://github.com/phar-io/manifest.git",
"reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133" "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
"reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3530,9 +3530,9 @@
"description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
"support": { "support": {
"issues": "https://github.com/phar-io/manifest/issues", "issues": "https://github.com/phar-io/manifest/issues",
"source": "https://github.com/phar-io/manifest/tree/master" "source": "https://github.com/phar-io/manifest/tree/2.0.3"
}, },
"time": "2020-06-27T14:33:11+00:00" "time": "2021-07-20T11:28:43+00:00"
}, },
{ {
"name": "phar-io/version", "name": "phar-io/version",
@ -5132,6 +5132,7 @@
"type": "github" "type": "github"
} }
], ],
"abandoned": true,
"time": "2020-09-28T06:45:17+00:00" "time": "2020-09-28T06:45:17+00:00"
}, },
{ {
@ -5297,16 +5298,16 @@
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v5.3.2", "version": "v5.3.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "649730483885ff2ca99ca0560ef0e5f6b03f2ac1" "reference": "ebd610dacd40d75b6a12bf64b5ccd494fc7d6ab1"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/649730483885ff2ca99ca0560ef0e5f6b03f2ac1", "url": "https://api.github.com/repos/symfony/console/zipball/ebd610dacd40d75b6a12bf64b5ccd494fc7d6ab1",
"reference": "649730483885ff2ca99ca0560ef0e5f6b03f2ac1", "reference": "ebd610dacd40d75b6a12bf64b5ccd494fc7d6ab1",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5314,11 +5315,12 @@
"symfony/deprecation-contracts": "^2.1", "symfony/deprecation-contracts": "^2.1",
"symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php73": "^1.8", "symfony/polyfill-php73": "^1.8",
"symfony/polyfill-php80": "^1.15", "symfony/polyfill-php80": "^1.16",
"symfony/service-contracts": "^1.1|^2", "symfony/service-contracts": "^1.1|^2",
"symfony/string": "^5.1" "symfony/string": "^5.1"
}, },
"conflict": { "conflict": {
"psr/log": ">=3",
"symfony/dependency-injection": "<4.4", "symfony/dependency-injection": "<4.4",
"symfony/dotenv": "<5.1", "symfony/dotenv": "<5.1",
"symfony/event-dispatcher": "<4.4", "symfony/event-dispatcher": "<4.4",
@ -5326,10 +5328,10 @@
"symfony/process": "<4.4" "symfony/process": "<4.4"
}, },
"provide": { "provide": {
"psr/log-implementation": "1.0" "psr/log-implementation": "1.0|2.0"
}, },
"require-dev": { "require-dev": {
"psr/log": "~1.0", "psr/log": "^1|^2",
"symfony/config": "^4.4|^5.0", "symfony/config": "^4.4|^5.0",
"symfony/dependency-injection": "^4.4|^5.0", "symfony/dependency-injection": "^4.4|^5.0",
"symfony/event-dispatcher": "^4.4|^5.0", "symfony/event-dispatcher": "^4.4|^5.0",
@ -5375,7 +5377,7 @@
"terminal" "terminal"
], ],
"support": { "support": {
"source": "https://github.com/symfony/console/tree/v5.3.2" "source": "https://github.com/symfony/console/tree/v5.3.4"
}, },
"funding": [ "funding": [
{ {
@ -5391,7 +5393,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-06-12T09:42:48+00:00" "time": "2021-07-26T16:33:26+00:00"
}, },
{ {
"name": "symfony/deprecation-contracts", "name": "symfony/deprecation-contracts",

View file

@ -508,17 +508,6 @@ services:
networks: networks:
- appwrite - 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: # redis-commander:
# image: rediscommander/redis-commander:latest # image: rediscommander/redis-commander:latest
# restart: unless-stopped # restart: unless-stopped

View file

@ -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. 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.

View file

@ -2,7 +2,7 @@
namespace Appwrite\Auth; namespace Appwrite\Auth;
use Appwrite\Database\Document; use Utopia\Database\Document;
class Auth class Auth
{ {

View file

@ -40,6 +40,7 @@ abstract class Migration
'0.8.0' => 'V07', '0.8.0' => 'V07',
'0.9.0' => 'V08', '0.9.0' => 'V08',
'0.9.1' => 'V08', '0.9.1' => 'V08',
'0.9.2' => 'V08',
]; ];
/** /**

View file

@ -2,6 +2,12 @@
namespace Appwrite\Resque; 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 abstract class Worker
{ {
public $args = []; public $args = [];
@ -12,6 +18,13 @@ abstract class Worker
abstract public function shutdown(): void; 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 public function setUp(): void
{ {
$this->init(); $this->init();
@ -26,4 +39,91 @@ abstract class Worker
{ {
$this->shutdown(); $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;
}
} }

View file

@ -238,7 +238,7 @@ class OpenAPI3 extends Format
$node['schema']['type'] = $validator->getType(); $node['schema']['type'] = $validator->getType();
$node['schema']['x-example'] = false; $node['schema']['x-example'] = false;
break; break;
case 'Appwrite\Database\Validator\UID': case 'Utopia\Database\Validator\UID':
$node['schema']['type'] = $validator->getType(); $node['schema']['type'] = $validator->getType();
$node['schema']['x-example'] = '['.\strtoupper(Template::fromCamelCaseToSnake($node['name'])).']'; $node['schema']['x-example'] = '['.\strtoupper(Template::fromCamelCaseToSnake($node['name'])).']';
break; break;

View file

@ -234,7 +234,7 @@ class Swagger2 extends Format
$node['type'] = $validator->getType(); $node['type'] = $validator->getType();
$node['x-example'] = false; $node['x-example'] = false;
break; break;
case 'Appwrite\Database\Validator\UID': case 'Utopia\Database\Validator\UID':
$node['type'] = $validator->getType(); $node['type'] = $validator->getType();
$node['x-example'] = '['.\strtoupper(Template::fromCamelCaseToSnake($node['name'])).']'; $node['x-example'] = '['.\strtoupper(Template::fromCamelCaseToSnake($node['name'])).']';
break; break;

View file

@ -5,7 +5,7 @@ namespace Appwrite\Utopia;
use Exception; use Exception;
use Utopia\Swoole\Response as SwooleResponse; use Utopia\Swoole\Response as SwooleResponse;
use Swoole\Http\Response as SwooleHTTPResponse; use Swoole\Http\Response as SwooleHTTPResponse;
use Appwrite\Database\Document; use Utopia\Database\Document;
use Appwrite\Utopia\Response\Filter; use Appwrite\Utopia\Response\Filter;
use Appwrite\Utopia\Response\Model; use Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response\Model\None; 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\Preferences;
use Appwrite\Utopia\Response\Model\Mock; // Keep last use Appwrite\Utopia\Response\Model\Mock; // Keep last
use stdClass; use stdClass;
use Utopia\Database\Document as DatabaseDocument;
/** /**
* @method Response public function setStatusCode(int $code = 200) * @method Response public function setStatusCode(int $code = 200)
@ -290,27 +289,6 @@ class Response extends SwooleResponse
$this->json(!empty($output) ? $output : new stdClass()); $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 * Generate valid response object from document data
* *
@ -363,58 +341,6 @@ class Response extends SwooleResponse
return $this->payload; 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 * YAML
* *

View file

@ -133,7 +133,7 @@ class HTTPTest extends Scope
} }
$client = new Client(); $client = new Client();
$client->setEndpoint('http://appwrite-swagger-validator:8080'); $client->setEndpoint('https://validator.swagger.io');
/** /**
* Test for SUCCESS * Test for SUCCESS

View file

@ -185,7 +185,32 @@ class FunctionsCustomClientTest extends Scope
$this->assertEquals(201, $execution['headers']['status-code']); $this->assertEquals(201, $execution['headers']['status-code']);
$executionId = $execution['body']['$id'] ?? '';
sleep(10); 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', [ $executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions', [
'content-type' => 'application/json', 'content-type' => 'application/json',
'x-appwrite-project' => $projectId, 'x-appwrite-project' => $projectId,

View file

@ -582,8 +582,31 @@ class FunctionsCustomServerTest extends Scope
$this->assertEquals(201, $execution['headers']['status-code']); $this->assertEquals(201, $execution['headers']['status-code']);
$executionId = $execution['body']['$id'] ?? '';
sleep(10); 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([ $executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions', array_merge([
'content-type' => 'application/json', 'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-project' => $this->getProject()['$id'],

View file

@ -233,12 +233,92 @@ trait WebhooksBase
return $data; return $data;
} }
public function testCreateFile(): array
public function testCreateStorageBucket(): array
{ {
/** /**
* Test for SUCCESS * Test for SUCCESS
*/ */
$file = $this->client->call(Client::METHOD_POST, '/storage/files', array_merge([ $bucket = $this->client->call(Client::METHOD_POST, '/storage/buckets', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'name' => 'Test Bucket',
'read' => ['role:all'],
'write' => ['role:all']
]);
$this->assertEquals($bucket['headers']['status-code'], 201);
$this->assertNotEmpty($bucket['body']['$id']);
$webhook = $this->getLastRequest();
$this->assertEquals($webhook['method'], 'POST');
$this->assertEquals($webhook['headers']['Content-Type'], 'application/json');
$this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'storage.buckets.create');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], 'not-yet-implemented');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
$this->assertEquals(empty($webhook['headers']['X-Appwrite-Webhook-User-Id'] ?? ''), true);
$this->assertNotEmpty($webhook['data']['$id']);
$this->assertEquals('Test Bucket', $webhook['data']['name']);
$this->assertEquals(true, $webhook['data']['enabled']);
$this->assertIsArray($webhook['data']['$read']);
$this->assertIsArray($webhook['data']['$write']);
return array_merge(['bucketId' => $bucket['body']['$id']]);
}
/**
* @depends testCreateStorageBucket
*/
public function testUpdateStorageBucket(array $data): array
{
/**
* Test for SUCCESS
*/
$bucket = $this->client->call(Client::METHOD_PUT, '/storage/buckets/' . $data['bucketId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'name' => 'Test Bucket Updated',
'enabled' => false,
]);
$this->assertEquals($bucket['headers']['status-code'], 200);
$this->assertNotEmpty($bucket['body']['$id']);
$webhook = $this->getLastRequest();
$this->assertEquals($webhook['method'], 'POST');
$this->assertEquals($webhook['headers']['Content-Type'], 'application/json');
$this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'storage.buckets.update');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], 'not-yet-implemented');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
$this->assertEquals(empty($webhook['headers']['X-Appwrite-Webhook-User-Id'] ?? ''), true);
$this->assertNotEmpty($webhook['data']['$id']);
$this->assertEquals('Test Bucket Updated', $webhook['data']['name']);
$this->assertEquals(false, $webhook['data']['enabled']);
$this->assertIsArray($webhook['data']['$read']);
$this->assertIsArray($webhook['data']['$write']);
return array_merge(['bucketId' => $bucket['body']['$id']]);
}
/**
* @depends testCreateStorageBucket
*/
public function testCreateBucketFile(array $data): array
{
/**
* Test for SUCCESS
*/
$file = $this->client->call(Client::METHOD_POST, '/storage/buckets/'. $data['bucketId'] . '/files', array_merge([
'content-type' => 'multipart/form-data', 'content-type' => 'multipart/form-data',
'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [ ], $this->getHeaders()), [
@ -273,18 +353,19 @@ trait WebhooksBase
/** /**
* Test for FAILURE * Test for FAILURE
*/ */
return ['fileId' => $file['body']['$id']]; $data ['fileId'] = $file['body']['$id'];
return $data;
} }
/** /**
* @depends testCreateFile * @depends testCreateBucketFile
*/ */
public function testUpdateFile(array $data): array public function testUpdateBucketFile(array $data): array
{ {
/** /**
* Test for SUCCESS * Test for SUCCESS
*/ */
$file = $this->client->call(Client::METHOD_PUT, '/storage/files/' . $data['fileId'], array_merge([ $file = $this->client->call(Client::METHOD_PUT, '/storage/buckets/' . $data['bucketId'] . '/files/' . $data['fileId'], array_merge([
'content-type' => 'application/json', 'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [ ], $this->getHeaders()), [
@ -318,14 +399,14 @@ trait WebhooksBase
} }
/** /**
* @depends testUpdateFile * @depends testUpdateBucketFile
*/ */
public function testDeleteFile(array $data): array public function testDeleteBucketFile(array $data): array
{ {
/** /**
* Test for SUCCESS * Test for SUCCESS
*/ */
$file = $this->client->call(Client::METHOD_DELETE, '/storage/files/' . $data['fileId'], array_merge([ $file = $this->client->call(Client::METHOD_DELETE, '/storage/buckets/' . $data['bucketId'] . '/files/' . $data['fileId'], array_merge([
'content-type' => 'application/json', 'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders())); ], $this->getHeaders()));
@ -355,6 +436,40 @@ trait WebhooksBase
return $data; return $data;
} }
/**
* @depends testDeleteBucketFile
*/
public function testDeleteStorageBucket(array $data)
{
/**
* Test for SUCCESS
*/
$bucket = $this->client->call(Client::METHOD_DELETE, '/storage/buckets/' . $data['bucketId'] , array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]));
$this->assertEquals($bucket['headers']['status-code'], 204);
$this->assertEmpty($bucket['body']);
$webhook = $this->getLastRequest();
$this->assertEquals($webhook['method'], 'POST');
$this->assertEquals($webhook['headers']['Content-Type'], 'application/json');
$this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'storage.buckets.delete');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], 'not-yet-implemented');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
$this->assertEquals(empty($webhook['headers']['X-Appwrite-Webhook-User-Id'] ?? ''), true);
$this->assertNotEmpty($webhook['data']['$id']);
$this->assertEquals('Test Bucket Updated', $webhook['data']['name']);
$this->assertEquals(false, $webhook['data']['enabled']);
$this->assertIsArray($webhook['data']['$read']);
$this->assertIsArray($webhook['data']['$write']);
}
public function testCreateTeam(): array public function testCreateTeam(): array
{ {
/** /**
@ -586,114 +701,4 @@ trait WebhooksBase
*/ */
return []; return [];
} }
public function testCreateStorageBucket(): array
{
/**
* Test for SUCCESS
*/
$bucket = $this->client->call(Client::METHOD_POST, '/storage/buckets', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'name' => 'Test Bucket',
]);
$this->assertEquals($bucket['headers']['status-code'], 201);
$this->assertNotEmpty($bucket['body']['$id']);
$webhook = $this->getLastRequest();
$this->assertEquals($webhook['method'], 'POST');
$this->assertEquals($webhook['headers']['Content-Type'], 'application/json');
$this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'storage.buckets.create');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], 'not-yet-implemented');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
$this->assertEquals(empty($webhook['headers']['X-Appwrite-Webhook-User-Id'] ?? ''), true);
$this->assertNotEmpty($webhook['data']['$id']);
$this->assertEquals('Test Bucket', $webhook['data']['name']);
$this->assertEquals(true, $webhook['data']['enabled']);
$this->assertIsArray($webhook['data']['$read']);
$this->assertIsArray($webhook['data']['$write']);
return array_merge(['bucketId' => $bucket['body']['$id']]);
}
/**
* @depends testCreateStorageBucket
*/
public function testUpdateStorageBucket(array $data): array
{
$id = $data['bucketId'];
/**
* Test for SUCCESS
*/
$bucket = $this->client->call(Client::METHOD_PUT, '/storage/buckets/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'name' => 'Test Bucket Updated',
'enabled' => false,
]);
$this->assertEquals($bucket['headers']['status-code'], 200);
$this->assertNotEmpty($bucket['body']['$id']);
$webhook = $this->getLastRequest();
$this->assertEquals($webhook['method'], 'POST');
$this->assertEquals($webhook['headers']['Content-Type'], 'application/json');
$this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'storage.buckets.update');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], 'not-yet-implemented');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
$this->assertEquals(empty($webhook['headers']['X-Appwrite-Webhook-User-Id'] ?? ''), true);
$this->assertNotEmpty($webhook['data']['$id']);
$this->assertEquals('Test Bucket Updated', $webhook['data']['name']);
$this->assertEquals(false, $webhook['data']['enabled']);
$this->assertIsArray($webhook['data']['$read']);
$this->assertIsArray($webhook['data']['$write']);
return array_merge(['bucketId' => $bucket['body']['$id']]);
}
/**
* @depends testCreateStorageBucket
*/
public function testDeleteStorageBucket(array $data)
{
$id = $data['bucketId'];
/**
* Test for SUCCESS
*/
$bucket = $this->client->call(Client::METHOD_DELETE, '/storage/buckets/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]));
$this->assertEquals($bucket['headers']['status-code'], 204);
$this->assertEmpty($bucket['body']);
$webhook = $this->getLastRequest();
$this->assertEquals($webhook['method'], 'POST');
$this->assertEquals($webhook['headers']['Content-Type'], 'application/json');
$this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'storage.buckets.delete');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], 'not-yet-implemented');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
$this->assertEquals(empty($webhook['headers']['X-Appwrite-Webhook-User-Id'] ?? ''), true);
$this->assertNotEmpty($webhook['data']['$id']);
$this->assertEquals('Test Bucket Updated', $webhook['data']['name']);
$this->assertEquals(false, $webhook['data']['enabled']);
$this->assertIsArray($webhook['data']['$read']);
$this->assertIsArray($webhook['data']['$write']);
}
} }

View file

@ -17,15 +17,18 @@ use Appwrite\Services\Storage;
// $result = $storage->getFile($_ENV['APPWRITE_FILEID']); // $result = $storage->getFile($_ENV['APPWRITE_FILEID']);
echo $_ENV['APPWRITE_FUNCTION_ID']."\n"; $output = [
echo $_ENV['APPWRITE_FUNCTION_NAME']."\n"; 'APPWRITE_FUNCTION_ID' => $_ENV['APPWRITE_FUNCTION_ID'],
echo $_ENV['APPWRITE_FUNCTION_TAG']."\n"; 'APPWRITE_FUNCTION_NAME' => $_ENV['APPWRITE_FUNCTION_NAME'],
echo $_ENV['APPWRITE_FUNCTION_TRIGGER']."\n"; 'APPWRITE_FUNCTION_TAG' => $_ENV['APPWRITE_FUNCTION_TAG'],
echo $_ENV['APPWRITE_FUNCTION_RUNTIME_NAME']."\n"; 'APPWRITE_FUNCTION_TRIGGER' => $_ENV['APPWRITE_FUNCTION_TRIGGER'],
echo $_ENV['APPWRITE_FUNCTION_RUNTIME_VERSION']."\n"; 'APPWRITE_FUNCTION_RUNTIME_NAME' => $_ENV['APPWRITE_FUNCTION_RUNTIME_NAME'],
// echo $result['$id']; 'APPWRITE_FUNCTION_RUNTIME_VERSION' => $_ENV['APPWRITE_FUNCTION_RUNTIME_VERSION'],
echo $_ENV['APPWRITE_FUNCTION_EVENT']."\n"; 'APPWRITE_FUNCTION_EVENT' => $_ENV['APPWRITE_FUNCTION_EVENT'],
echo $_ENV['APPWRITE_FUNCTION_EVENT_DATA']."\n"; 'APPWRITE_FUNCTION_EVENT_DATA' => $_ENV['APPWRITE_FUNCTION_EVENT_DATA'],
echo 'data:'.$_ENV['APPWRITE_FUNCTION_DATA']."\n"; 'APPWRITE_FUNCTION_DATA' => $_ENV['APPWRITE_FUNCTION_DATA'],
echo 'userId:'.$_ENV['APPWRITE_FUNCTION_USER_ID']."\n"; 'APPWRITE_FUNCTION_USER_ID' => $_ENV['APPWRITE_FUNCTION_USER_ID'],
echo 'jwt:'.$_ENV['APPWRITE_FUNCTION_JWT']."\n"; 'APPWRITE_FUNCTION_JWT' => $_ENV['APPWRITE_FUNCTION_JWT'],
];
echo json_encode($output);