Added env vars and new request methods
This commit is contained in:
parent
1c9bf4d0ab
commit
6824cf560f
27
app/app.php
27
app/app.php
|
@ -17,7 +17,6 @@ use Appwrite\Network\Validator\Origin;
|
|||
|
||||
// Config::setParam('domain', $request->getServer('HTTP_HOST', ''));
|
||||
// Config::setParam('domainVerification', false);
|
||||
// Config::setParam('version', App::getEnv('_APP_VERSION', 'UNKNOWN'));
|
||||
// Config::setParam('protocol', $request->getServer('HTTP_X_FORWARDED_PROTO', $request->getServer('REQUEST_SCHEME', 'https')));
|
||||
// Config::setParam('port', (string) \parse_url(Config::getParam('protocol').'://'.$request->getServer('HTTP_HOST', ''), PHP_URL_PORT));
|
||||
// Config::setParam('hostname', \parse_url(Config::getParam('protocol').'://'.$request->getServer('HTTP_HOST', null), PHP_URL_HOST));
|
||||
|
@ -131,10 +130,22 @@ use Appwrite\Network\Validator\Origin;
|
|||
// return false;
|
||||
// }))));
|
||||
|
||||
App::init(function ($utopia, $request, $response, $user, $project, $console, $webhooks, $audits, $usage, $clients, $locale) {
|
||||
|
||||
/** @var $locale Utopia\Locale\Locale */
|
||||
$localeParam = $request->getParam('locale', $request->getHeader('X-Appwrite-Locale', ''));
|
||||
App::init(function ($utopia, $request, $response, $console, $project, $user, $locale, $webhooks, $audits, $usage, $clients) {
|
||||
/** @var Utopia\Request $request */
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $console */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var Appwrite\Event\Event $webhook */
|
||||
/** @var Appwrite\Event\Event $audit */
|
||||
/** @var Appwrite\Event\Event $usage */
|
||||
/** @var Appwrite\Event\Event $mail */
|
||||
/** @var Appwrite\Event\Event $deletes */
|
||||
/** @var bool $mode */
|
||||
/** @var array $clients */
|
||||
|
||||
$localeParam = (string)$request->getParam('locale', $request->getHeader('X-Appwrite-Locale', ''));
|
||||
|
||||
if (\in_array($localeParam, Config::getParam('locale-codes'))) {
|
||||
$locale->setDefault($localeParam);
|
||||
|
@ -175,7 +186,7 @@ App::init(function ($utopia, $request, $response, $user, $project, $console, $we
|
|||
* @see https://www.owasp.org/index.php/List_of_useful_HTTP_headers
|
||||
*/
|
||||
if (App::getEnv('_APP_OPTIONS_FORCE_HTTPS', 'disabled') === 'enabled') { // Force HTTPS
|
||||
if(Config::getParam('protocol') !== 'https') {
|
||||
if($request->getProtocol() !== 'https') {
|
||||
return $response->redirect('https://' . Config::getParam('domain').$request->getServer('REQUEST_URI'));
|
||||
}
|
||||
|
||||
|
@ -317,7 +328,7 @@ App::init(function ($utopia, $request, $response, $user, $project, $console, $we
|
|||
->setParam('response', 0)
|
||||
->setParam('storage', 0)
|
||||
;
|
||||
}, ['utopia', 'request', 'response', 'user', 'project', 'console', 'webhook', 'audit', 'usage', 'clients', 'locale']);
|
||||
}, ['utopia', 'request', 'response', 'console', 'project', 'user', 'locale', 'webhook', 'audit', 'usage', 'clients']);
|
||||
|
||||
App::shutdown(function ($utopia, $response, $request, $webhook, $audit, $usage, $deletes, $mode, $project) {
|
||||
/*
|
||||
|
@ -363,7 +374,7 @@ App::options(function ($request, $response) {
|
|||
App::error(function ($error, $utopia, $request, $response, $project) {
|
||||
/** @var Exception $error */
|
||||
|
||||
$version = Config::getParam('version');
|
||||
$version = App::getEnv('_APP_VERSION', 'UNKNOWN');
|
||||
|
||||
switch ($error->getCode()) {
|
||||
case 400: // Error allowed publicly
|
||||
|
|
|
@ -167,7 +167,7 @@ App::post('/v1/account/sessions')
|
|||
/** @var Appwrite\Event\Event $webhook */
|
||||
/** @var Appwrite\Event\Event $audit */
|
||||
|
||||
$protocol = Config::getParam('protocol');
|
||||
$protocol = $request->getProtocol();
|
||||
$profile = $projectDB->getCollectionFirst([ // Get user by email address
|
||||
'limit' => 1,
|
||||
'filters' => [
|
||||
|
@ -264,7 +264,7 @@ App::get('/v1/account/sessions/oauth2/:provider')
|
|||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
|
||||
$protocol = Config::getParam('protocol');
|
||||
$protocol = $request->getProtocol();
|
||||
$callback = $protocol.'://'.$request->getServer('HTTP_HOST').'/v1/account/sessions/oauth2/callback/'.$provider.'/'.$project->getId();
|
||||
$appId = $project->getAttribute('usersOauth2'.\ucfirst($provider).'Appid', '');
|
||||
$appSecret = $project->getAttribute('usersOauth2'.\ucfirst($provider).'Secret', '{}');
|
||||
|
@ -304,16 +304,19 @@ App::get('/v1/account/sessions/oauth2/callback/:provider/:projectId')
|
|||
->param('provider', '', function () { return new WhiteList(\array_keys(Config::getParam('providers'))); }, 'OAuth2 provider.')
|
||||
->param('code', '', function () { return new Text(1024); }, 'OAuth2 code.')
|
||||
->param('state', '', function () { return new Text(2048); }, 'Login state params.', true)
|
||||
->action(function ($projectId, $provider, $code, $state, $response) {
|
||||
->action(function ($projectId, $provider, $code, $state, $request, $response) {
|
||||
/** @var Utopia\Request $request */
|
||||
/** @var Utopia\Response $response */
|
||||
|
||||
$domain = Config::getParam('domain');
|
||||
$protocol = Config::getParam('protocol');
|
||||
$protocol = $request->getProtocol();
|
||||
|
||||
$response
|
||||
->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
|
||||
->addHeader('Pragma', 'no-cache')
|
||||
->redirect($protocol.'://'.$domain.'/v1/account/sessions/oauth2/'.$provider.'/redirect?'
|
||||
.\http_build_query(['project' => $projectId, 'code' => $code, 'state' => $state]));
|
||||
}, ['response']);
|
||||
}, ['request', 'response']);
|
||||
|
||||
App::post('/v1/account/sessions/oauth2/callback/:provider/:projectId')
|
||||
->desc('OAuth2 Callback')
|
||||
|
@ -326,16 +329,19 @@ App::post('/v1/account/sessions/oauth2/callback/:provider/:projectId')
|
|||
->param('provider', '', function () { return new WhiteList(\array_keys(Config::getParam('providers'))); }, 'OAuth2 provider.')
|
||||
->param('code', '', function () { return new Text(1024); }, 'OAuth2 code.')
|
||||
->param('state', '', function () { return new Text(2048); }, 'Login state params.', true)
|
||||
->action(function ($projectId, $provider, $code, $state, $response) {
|
||||
->action(function ($projectId, $provider, $code, $state, $request, $response) {
|
||||
/** @var Utopia\Request $request */
|
||||
/** @var Utopia\Response $response */
|
||||
|
||||
$domain = Config::getParam('domain');
|
||||
$protocol = Config::getParam('protocol');
|
||||
$protocol = $request->getProtocol();
|
||||
|
||||
$response
|
||||
->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
|
||||
->addHeader('Pragma', 'no-cache')
|
||||
->redirect($protocol.'://'.$domain.'/v1/account/sessions/oauth2/'.$provider.'/redirect?'
|
||||
.\http_build_query(['project' => $projectId, 'code' => $code, 'state' => $state]));
|
||||
}, ['response']);
|
||||
}, ['request', 'response']);
|
||||
|
||||
App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||
->desc('OAuth2 Redirect')
|
||||
|
@ -357,7 +363,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Appwrite\Event\Event $audit */
|
||||
|
||||
$protocol = Config::getParam('protocol');
|
||||
$protocol = $request->getProtocol();
|
||||
$callback = $protocol.'://'.$request->getServer('HTTP_HOST').'/v1/account/sessions/oauth2/callback/'.$provider.'/'.$project->getId();
|
||||
$defaultState = ['success' => $project->getAttribute('url', ''), 'failure' => ''];
|
||||
$validateURL = new URL();
|
||||
|
@ -923,14 +929,15 @@ App::delete('/v1/account')
|
|||
->label('sdk.namespace', 'account')
|
||||
->label('sdk.method', 'delete')
|
||||
->label('sdk.description', '/docs/references/account/delete.md')
|
||||
->action(function ($response, $user, $projectDB, $audit, $webhook) {
|
||||
->action(function ($request, $response, $user, $projectDB, $audit, $webhook) {
|
||||
/** @var Utopia\Request $request */
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Appwrite\Event\Event $audit */
|
||||
/** @var Appwrite\Event\Event $webhook */
|
||||
|
||||
$protocol = Config::getParam('protocol');
|
||||
$protocol = $request->getProtocol();
|
||||
$user = $projectDB->updateDocument(\array_merge($user->getArrayCopy(), [
|
||||
'status' => Auth::USER_STATUS_BLOCKED,
|
||||
]));
|
||||
|
@ -972,7 +979,7 @@ App::delete('/v1/account')
|
|||
->addCookie(Auth::$cookieName, '', \time() - 3600, '/', COOKIE_DOMAIN, ('https' == $protocol), true, COOKIE_SAMESITE)
|
||||
->noContent()
|
||||
;
|
||||
}, ['response', 'user', 'projectDB', 'audit', 'webhook']);
|
||||
}, ['request', 'response', 'user', 'projectDB', 'audit', 'webhook']);
|
||||
|
||||
App::delete('/v1/account/sessions/:sessionId')
|
||||
->desc('Delete Account Session')
|
||||
|
@ -985,14 +992,15 @@ App::delete('/v1/account/sessions/:sessionId')
|
|||
->label('sdk.description', '/docs/references/account/delete-session.md')
|
||||
->label('abuse-limit', 100)
|
||||
->param('sessionId', null, function () { return new UID(); }, 'Session unique ID. Use the string \'current\' to delete the current device session.')
|
||||
->action(function ($sessionId, $response, $user, $projectDB, $audit, $webhook) {
|
||||
->action(function ($sessionId, $request, $response, $user, $projectDB, $audit, $webhook) {
|
||||
/** @var Utopia\Request $request */
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Appwrite\Event\Event $audit */
|
||||
/** @var Appwrite\Event\Event $webhook */
|
||||
|
||||
$protocol = Config::getParam('protocol');
|
||||
$protocol = $request->getProtocol();
|
||||
$sessionId = ($sessionId === 'current')
|
||||
? Auth::tokenVerify($user->getAttribute('tokens'), Auth::TOKEN_TYPE_LOGIN, Auth::$secret)
|
||||
: $sessionId;
|
||||
|
@ -1036,7 +1044,7 @@ App::delete('/v1/account/sessions/:sessionId')
|
|||
}
|
||||
|
||||
throw new Exception('Session not found', 404);
|
||||
}, ['response', 'user', 'projectDB', 'audit', 'webhook']);
|
||||
}, ['request', 'response', 'user', 'projectDB', 'audit', 'webhook']);
|
||||
|
||||
App::delete('/v1/account/sessions')
|
||||
->desc('Delete All Account Sessions')
|
||||
|
@ -1048,14 +1056,15 @@ App::delete('/v1/account/sessions')
|
|||
->label('sdk.method', 'deleteSessions')
|
||||
->label('sdk.description', '/docs/references/account/delete-sessions.md')
|
||||
->label('abuse-limit', 100)
|
||||
->action(function ($response, $user, $projectDB, $audit, $webhook) {
|
||||
->action(function ($request, $response, $user, $projectDB, $audit, $webhook) {
|
||||
/** @var Utopia\Request $request */
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Appwrite\Event\Event $audit */
|
||||
/** @var Appwrite\Event\Event $webhook */
|
||||
|
||||
$protocol = Config::getParam('protocol');
|
||||
$protocol = $request->getProtocol();
|
||||
$tokens = $user->getAttribute('tokens', []);
|
||||
|
||||
foreach ($tokens as $token) { /* @var $token Document */
|
||||
|
@ -1091,7 +1100,7 @@ App::delete('/v1/account/sessions')
|
|||
}
|
||||
|
||||
$response->noContent();
|
||||
}, ['response', 'user', 'projectDB', 'audit', 'webhook']);
|
||||
}, ['request', 'response', 'user', 'projectDB', 'audit', 'webhook']);
|
||||
|
||||
App::post('/v1/account/recovery')
|
||||
->desc('Create Password Recovery')
|
||||
|
|
|
@ -246,7 +246,7 @@ App::get('/v1/avatars/favicon')
|
|||
CURLOPT_MAXREDIRS => 3,
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_USERAGENT => \sprintf(APP_USERAGENT,
|
||||
Config::getParam('version'),
|
||||
App::getEnv('_APP_VERSION', 'UNKNOWN'),
|
||||
App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY)
|
||||
),
|
||||
]);
|
||||
|
|
|
@ -242,116 +242,119 @@ App::get('/v1/storage/files/:fileId/preview')
|
|||
->param('quality', 100, function () { return new Range(0, 100); }, 'Preview image quality. Pass an integer between 0 to 100. Defaults to 100.', true)
|
||||
->param('background', '', function () { return new HexColor(); }, 'Preview image background color. Only works with transparent images (png). Use a valid HEX color, no # is needed for prefix.', true)
|
||||
->param('output', null, function () { return new WhiteList(\array_merge(\array_keys(Config::getParam('storage-outputs')), [null])); }, 'Output format type (jpeg, jpg, png, gif and webp).', true)
|
||||
->action(
|
||||
function ($fileId, $width, $height, $quality, $background, $output) use ($request, $response, $projectDB, $project) {
|
||||
$storage = 'local';
|
||||
->action(function ($fileId, $width, $height, $quality, $background, $output, $request, $response, $project, $projectDB) {
|
||||
/** @var Utopia\Request $request */
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
|
||||
if (!\extension_loaded('imagick')) {
|
||||
throw new Exception('Imagick extension is missing', 500);
|
||||
}
|
||||
$storage = 'local';
|
||||
|
||||
if (!Storage::exists($storage)) {
|
||||
throw new Exception('No such storage device', 400);
|
||||
}
|
||||
if (!\extension_loaded('imagick')) {
|
||||
throw new Exception('Imagick extension is missing', 500);
|
||||
}
|
||||
|
||||
if ((\strpos($request->getServer('HTTP_ACCEPT'), 'image/webp') === false) && ('webp' == $output)) { // Fallback webp to jpeg when no browser support
|
||||
$output = 'jpg';
|
||||
}
|
||||
if (!Storage::exists($storage)) {
|
||||
throw new Exception('No such storage device', 400);
|
||||
}
|
||||
|
||||
$inputs = Config::getParam('storage-inputs');
|
||||
$outputs = Config::getParam('storage-outputs');
|
||||
$fileLogos = Config::getParam('storage-logos');
|
||||
if ((\strpos($request->getServer('HTTP_ACCEPT'), 'image/webp') === false) && ('webp' == $output)) { // Fallback webp to jpeg when no browser support
|
||||
$output = 'jpg';
|
||||
}
|
||||
|
||||
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache
|
||||
$key = \md5($fileId.$width.$height.$quality.$background.$storage.$output);
|
||||
$inputs = Config::getParam('storage-inputs');
|
||||
$outputs = Config::getParam('storage-outputs');
|
||||
$fileLogos = Config::getParam('storage-logos');
|
||||
|
||||
$file = $projectDB->getDocument($fileId);
|
||||
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache
|
||||
$key = \md5($fileId.$width.$height.$quality.$background.$storage.$output);
|
||||
|
||||
if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
$file = $projectDB->getDocument($fileId);
|
||||
|
||||
$path = $file->getAttribute('path');
|
||||
if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
|
||||
$path = $file->getAttribute('path');
|
||||
$type = \strtolower(\pathinfo($path, PATHINFO_EXTENSION));
|
||||
$algorithm = $file->getAttribute('algorithm');
|
||||
$cipher = $file->getAttribute('fileOpenSSLCipher');
|
||||
$mime = $file->getAttribute('mimeType');
|
||||
|
||||
if (!\in_array($mime, $inputs)) {
|
||||
$path = (\array_key_exists($mime, $fileLogos)) ? $fileLogos[$mime] : $fileLogos['default'];
|
||||
$algorithm = null;
|
||||
$cipher = null;
|
||||
$background = (empty($background)) ? 'eceff1' : $background;
|
||||
$type = \strtolower(\pathinfo($path, PATHINFO_EXTENSION));
|
||||
$algorithm = $file->getAttribute('algorithm');
|
||||
$cipher = $file->getAttribute('fileOpenSSLCipher');
|
||||
$mime = $file->getAttribute('mimeType');
|
||||
$key = \md5($path.$width.$height.$quality.$background.$storage.$output);
|
||||
}
|
||||
|
||||
if (!\in_array($mime, $inputs)) {
|
||||
$path = (\array_key_exists($mime, $fileLogos)) ? $fileLogos[$mime] : $fileLogos['default'];
|
||||
$algorithm = null;
|
||||
$cipher = null;
|
||||
$background = (empty($background)) ? 'eceff1' : $background;
|
||||
$type = \strtolower(\pathinfo($path, PATHINFO_EXTENSION));
|
||||
$key = \md5($path.$width.$height.$quality.$background.$storage.$output);
|
||||
}
|
||||
$compressor = new GZIP();
|
||||
$device = Storage::getDevice('local');
|
||||
|
||||
$compressor = new GZIP();
|
||||
$device = Storage::getDevice('local');
|
||||
if (!\file_exists($path)) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
|
||||
if (!\file_exists($path)) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
|
||||
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE.'/app-'.$project->getId())); // Limit file number or size
|
||||
$data = $cache->load($key, 60 * 60 * 24 * 30 * 3 /* 3 months */);
|
||||
|
||||
if ($data) {
|
||||
$output = (empty($output)) ? $type : $output;
|
||||
|
||||
$response
|
||||
->setContentType((\in_array($output, $outputs)) ? $outputs[$output] : $outputs['jpg'])
|
||||
->addHeader('Expires', $date)
|
||||
->addHeader('X-Appwrite-Cache', 'hit')
|
||||
->send($data)
|
||||
;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$source = $device->read($path);
|
||||
|
||||
if (!empty($cipher)) { // Decrypt
|
||||
$source = OpenSSL::decrypt(
|
||||
$source,
|
||||
$file->getAttribute('fileOpenSSLCipher'),
|
||||
App::getEnv('_APP_OPENSSL_KEY_V'.$file->getAttribute('fileOpenSSLVersion')),
|
||||
0,
|
||||
\hex2bin($file->getAttribute('fileOpenSSLIV')),
|
||||
\hex2bin($file->getAttribute('fileOpenSSLTag'))
|
||||
);
|
||||
}
|
||||
|
||||
if (!empty($algorithm)) {
|
||||
$source = $compressor->decompress($source);
|
||||
}
|
||||
|
||||
$resize = new Resize($source);
|
||||
|
||||
$resize->crop((int) $width, (int) $height);
|
||||
|
||||
if (!empty($background)) {
|
||||
$resize->setBackground('#'.$background);
|
||||
}
|
||||
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE.'/app-'.$project->getId())); // Limit file number or size
|
||||
$data = $cache->load($key, 60 * 60 * 24 * 30 * 3 /* 3 months */);
|
||||
|
||||
if ($data) {
|
||||
$output = (empty($output)) ? $type : $output;
|
||||
|
||||
$response
|
||||
->setContentType($outputs[$output])
|
||||
->setContentType((\in_array($output, $outputs)) ? $outputs[$output] : $outputs['jpg'])
|
||||
->addHeader('Expires', $date)
|
||||
->addHeader('X-Appwrite-Cache', 'miss')
|
||||
->send('')
|
||||
->addHeader('X-Appwrite-Cache', 'hit')
|
||||
->send($data)
|
||||
;
|
||||
|
||||
$data = $resize->output($output, $quality);
|
||||
|
||||
$cache->save($key, $data);
|
||||
|
||||
echo $data;
|
||||
|
||||
unset($resize);
|
||||
return;
|
||||
}
|
||||
);
|
||||
|
||||
$source = $device->read($path);
|
||||
|
||||
if (!empty($cipher)) { // Decrypt
|
||||
$source = OpenSSL::decrypt(
|
||||
$source,
|
||||
$file->getAttribute('fileOpenSSLCipher'),
|
||||
App::getEnv('_APP_OPENSSL_KEY_V'.$file->getAttribute('fileOpenSSLVersion')),
|
||||
0,
|
||||
\hex2bin($file->getAttribute('fileOpenSSLIV')),
|
||||
\hex2bin($file->getAttribute('fileOpenSSLTag'))
|
||||
);
|
||||
}
|
||||
|
||||
if (!empty($algorithm)) {
|
||||
$source = $compressor->decompress($source);
|
||||
}
|
||||
|
||||
$resize = new Resize($source);
|
||||
|
||||
$resize->crop((int) $width, (int) $height);
|
||||
|
||||
if (!empty($background)) {
|
||||
$resize->setBackground('#'.$background);
|
||||
}
|
||||
|
||||
$output = (empty($output)) ? $type : $output;
|
||||
|
||||
$response
|
||||
->setContentType($outputs[$output])
|
||||
->addHeader('Expires', $date)
|
||||
->addHeader('X-Appwrite-Cache', 'miss')
|
||||
->send('')
|
||||
;
|
||||
|
||||
$data = $resize->output($output, $quality);
|
||||
|
||||
$cache->save($key, $data);
|
||||
|
||||
echo $data;
|
||||
|
||||
unset($resize);
|
||||
}, ['request', 'response', 'project', 'projectDB']);
|
||||
|
||||
App::get('/v1/storage/files/:fileId/download')
|
||||
->desc('Get File for Download')
|
||||
|
@ -364,48 +367,49 @@ App::get('/v1/storage/files/:fileId/download')
|
|||
->label('sdk.response.type', '*')
|
||||
->label('sdk.methodType', 'location')
|
||||
->param('fileId', '', function () { return new UID(); }, 'File unique ID.')
|
||||
->action(
|
||||
function ($fileId) use ($response, $projectDB) {
|
||||
$file = $projectDB->getDocument($fileId);
|
||||
->action(function ($fileId, $response, $projectDB) {
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
|
||||
if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
$file = $projectDB->getDocument($fileId);
|
||||
|
||||
$path = $file->getAttribute('path', '');
|
||||
|
||||
if (!\file_exists($path)) {
|
||||
throw new Exception('File not found in '.$path, 404);
|
||||
}
|
||||
|
||||
$compressor = new GZIP();
|
||||
$device = Storage::getDevice('local');
|
||||
|
||||
$source = $device->read($path);
|
||||
|
||||
if (!empty($file->getAttribute('fileOpenSSLCipher'))) { // Decrypt
|
||||
$source = OpenSSL::decrypt(
|
||||
$source,
|
||||
$file->getAttribute('fileOpenSSLCipher'),
|
||||
App::getEnv('_APP_OPENSSL_KEY_V'.$file->getAttribute('fileOpenSSLVersion')),
|
||||
0,
|
||||
\hex2bin($file->getAttribute('fileOpenSSLIV')),
|
||||
\hex2bin($file->getAttribute('fileOpenSSLTag'))
|
||||
);
|
||||
}
|
||||
|
||||
$source = $compressor->decompress($source);
|
||||
|
||||
// Response
|
||||
$response
|
||||
->setContentType($file->getAttribute('mimeType'))
|
||||
->addHeader('Content-Disposition', 'attachment; filename="'.$file->getAttribute('name', '').'"')
|
||||
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT') // 45 days cache
|
||||
->addHeader('X-Peak', \memory_get_peak_usage())
|
||||
->send($source)
|
||||
;
|
||||
if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
);
|
||||
|
||||
$path = $file->getAttribute('path', '');
|
||||
|
||||
if (!\file_exists($path)) {
|
||||
throw new Exception('File not found in '.$path, 404);
|
||||
}
|
||||
|
||||
$compressor = new GZIP();
|
||||
$device = Storage::getDevice('local');
|
||||
|
||||
$source = $device->read($path);
|
||||
|
||||
if (!empty($file->getAttribute('fileOpenSSLCipher'))) { // Decrypt
|
||||
$source = OpenSSL::decrypt(
|
||||
$source,
|
||||
$file->getAttribute('fileOpenSSLCipher'),
|
||||
App::getEnv('_APP_OPENSSL_KEY_V'.$file->getAttribute('fileOpenSSLVersion')),
|
||||
0,
|
||||
\hex2bin($file->getAttribute('fileOpenSSLIV')),
|
||||
\hex2bin($file->getAttribute('fileOpenSSLTag'))
|
||||
);
|
||||
}
|
||||
|
||||
$source = $compressor->decompress($source);
|
||||
|
||||
// Response
|
||||
$response
|
||||
->setContentType($file->getAttribute('mimeType'))
|
||||
->addHeader('Content-Disposition', 'attachment; filename="'.$file->getAttribute('name', '').'"')
|
||||
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT') // 45 days cache
|
||||
->addHeader('X-Peak', \memory_get_peak_usage())
|
||||
->send($source)
|
||||
;
|
||||
}, ['response', 'projectDB']);
|
||||
|
||||
App::get('/v1/storage/files/:fileId/view')
|
||||
->desc('Get File for View')
|
||||
|
@ -419,65 +423,66 @@ App::get('/v1/storage/files/:fileId/view')
|
|||
->label('sdk.methodType', 'location')
|
||||
->param('fileId', '', function () { return new UID(); }, 'File unique ID.')
|
||||
->param('as', '', function () { return new WhiteList(['pdf', /*'html',*/ 'text']); }, 'Choose a file format to convert your file to. Currently you can only convert word and pdf files to pdf or txt. This option is currently experimental only, use at your own risk.', true)
|
||||
->action(
|
||||
function ($fileId, $as) use ($response, $projectDB) {
|
||||
$file = $projectDB->getDocument($fileId);
|
||||
$mimes = Config::getParam('storage-mimes');
|
||||
->action(function ($fileId, $as, $response, $projectDB) {
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
|
||||
if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
$file = $projectDB->getDocument($fileId);
|
||||
$mimes = Config::getParam('storage-mimes');
|
||||
|
||||
$path = $file->getAttribute('path', '');
|
||||
|
||||
if (!\file_exists($path)) {
|
||||
throw new Exception('File not found in '.$path, 404);
|
||||
}
|
||||
|
||||
$compressor = new GZIP();
|
||||
$device = Storage::getDevice('local');
|
||||
|
||||
$contentType = 'text/plain';
|
||||
|
||||
if (\in_array($file->getAttribute('mimeType'), $mimes)) {
|
||||
$contentType = $file->getAttribute('mimeType');
|
||||
}
|
||||
|
||||
$source = $device->read($path);
|
||||
|
||||
if (!empty($file->getAttribute('fileOpenSSLCipher'))) { // Decrypt
|
||||
$source = OpenSSL::decrypt(
|
||||
$source,
|
||||
$file->getAttribute('fileOpenSSLCipher'),
|
||||
App::getEnv('_APP_OPENSSL_KEY_V'.$file->getAttribute('fileOpenSSLVersion')),
|
||||
0,
|
||||
\hex2bin($file->getAttribute('fileOpenSSLIV')),
|
||||
\hex2bin($file->getAttribute('fileOpenSSLTag'))
|
||||
);
|
||||
}
|
||||
|
||||
$output = $compressor->decompress($source);
|
||||
$fileName = $file->getAttribute('name', '');
|
||||
|
||||
$contentTypes = [
|
||||
'pdf' => 'application/pdf',
|
||||
'text' => 'text/plain',
|
||||
];
|
||||
|
||||
$contentType = (\array_key_exists($as, $contentTypes)) ? $contentTypes[$as] : $contentType;
|
||||
|
||||
// Response
|
||||
$response
|
||||
->setContentType($contentType)
|
||||
->addHeader('Content-Security-Policy', 'script-src none;')
|
||||
->addHeader('X-Content-Type-Options', 'nosniff')
|
||||
->addHeader('Content-Disposition', 'inline; filename="'.$fileName.'"')
|
||||
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT') // 45 days cache
|
||||
->addHeader('X-Peak', \memory_get_peak_usage())
|
||||
->send($output)
|
||||
;
|
||||
if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
);
|
||||
|
||||
$path = $file->getAttribute('path', '');
|
||||
|
||||
if (!\file_exists($path)) {
|
||||
throw new Exception('File not found in '.$path, 404);
|
||||
}
|
||||
|
||||
$compressor = new GZIP();
|
||||
$device = Storage::getDevice('local');
|
||||
|
||||
$contentType = 'text/plain';
|
||||
|
||||
if (\in_array($file->getAttribute('mimeType'), $mimes)) {
|
||||
$contentType = $file->getAttribute('mimeType');
|
||||
}
|
||||
|
||||
$source = $device->read($path);
|
||||
|
||||
if (!empty($file->getAttribute('fileOpenSSLCipher'))) { // Decrypt
|
||||
$source = OpenSSL::decrypt(
|
||||
$source,
|
||||
$file->getAttribute('fileOpenSSLCipher'),
|
||||
App::getEnv('_APP_OPENSSL_KEY_V'.$file->getAttribute('fileOpenSSLVersion')),
|
||||
0,
|
||||
\hex2bin($file->getAttribute('fileOpenSSLIV')),
|
||||
\hex2bin($file->getAttribute('fileOpenSSLTag'))
|
||||
);
|
||||
}
|
||||
|
||||
$output = $compressor->decompress($source);
|
||||
$fileName = $file->getAttribute('name', '');
|
||||
|
||||
$contentTypes = [
|
||||
'pdf' => 'application/pdf',
|
||||
'text' => 'text/plain',
|
||||
];
|
||||
|
||||
$contentType = (\array_key_exists($as, $contentTypes)) ? $contentTypes[$as] : $contentType;
|
||||
|
||||
// Response
|
||||
$response
|
||||
->setContentType($contentType)
|
||||
->addHeader('Content-Security-Policy', 'script-src none;')
|
||||
->addHeader('X-Content-Type-Options', 'nosniff')
|
||||
->addHeader('Content-Disposition', 'inline; filename="'.$fileName.'"')
|
||||
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT') // 45 days cache
|
||||
->addHeader('X-Peak', \memory_get_peak_usage())
|
||||
->send($output)
|
||||
;
|
||||
}, ['response', 'projectDB']);
|
||||
|
||||
App::put('/v1/storage/files/:fileId')
|
||||
->desc('Update File')
|
||||
|
@ -491,39 +496,41 @@ App::put('/v1/storage/files/:fileId')
|
|||
->param('fileId', '', function () { return new UID(); }, 'File unique ID.')
|
||||
->param('read', [], function () { return new ArrayList(new Text(64)); }, 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
|
||||
->param('write', [], function () { return new ArrayList(new Text(64)); }, 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
|
||||
//->param('folderId', '', function () { return new UID(); }, 'Folder to associate files with.', true)
|
||||
->action(
|
||||
function ($fileId, $read, $write, $folderId = '') use ($response, $projectDB, $audit, $webhook) {
|
||||
$file = $projectDB->getDocument($fileId);
|
||||
->action(function ($fileId, $read, $write, $response, $projectDB, $webhook, $audit) {
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Appwrite\Event\Event $webhook */
|
||||
/** @var Appwrite\Event\Event $audit */
|
||||
|
||||
if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
$file = $projectDB->getDocument($fileId);
|
||||
|
||||
$file = $projectDB->updateDocument(\array_merge($file->getArrayCopy(), [
|
||||
'$permissions' => [
|
||||
'read' => $read,
|
||||
'write' => $write,
|
||||
],
|
||||
'folderId' => $folderId,
|
||||
]));
|
||||
|
||||
if (false === $file) {
|
||||
throw new Exception('Failed saving file to DB', 500);
|
||||
}
|
||||
|
||||
$webhook
|
||||
->setParam('payload', $file->getArrayCopy())
|
||||
;
|
||||
|
||||
$audit
|
||||
->setParam('event', 'storage.files.update')
|
||||
->setParam('resource', 'storage/files/'.$file->getId())
|
||||
;
|
||||
|
||||
$response->json($file->getArrayCopy());
|
||||
if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
);
|
||||
|
||||
$file = $projectDB->updateDocument(\array_merge($file->getArrayCopy(), [
|
||||
'$permissions' => [
|
||||
'read' => $read,
|
||||
'write' => $write,
|
||||
],
|
||||
'folderId' => '',
|
||||
]));
|
||||
|
||||
if (false === $file) {
|
||||
throw new Exception('Failed saving file to DB', 500);
|
||||
}
|
||||
|
||||
$webhook
|
||||
->setParam('payload', $file->getArrayCopy())
|
||||
;
|
||||
|
||||
$audit
|
||||
->setParam('event', 'storage.files.update')
|
||||
->setParam('resource', 'storage/files/'.$file->getId())
|
||||
;
|
||||
|
||||
$response->json($file->getArrayCopy());
|
||||
}, ['response', 'projectDB', 'webhook', 'audit']);
|
||||
|
||||
App::delete('/v1/storage/files/:fileId')
|
||||
->desc('Delete File')
|
||||
|
@ -535,38 +542,42 @@ App::delete('/v1/storage/files/:fileId')
|
|||
->label('sdk.method', 'deleteFile')
|
||||
->label('sdk.description', '/docs/references/storage/delete-file.md')
|
||||
->param('fileId', '', function () { return new UID(); }, 'File unique ID.')
|
||||
->action(
|
||||
function ($fileId) use ($response, $projectDB, $webhook, $audit, $usage) {
|
||||
$file = $projectDB->getDocument($fileId);
|
||||
->action(function ($fileId, $response, $projectDB, $webhook, $audit, $usage) {
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Appwrite\Event\Event $webhook */
|
||||
/** @var Appwrite\Event\Event $audit */
|
||||
/** @var Appwrite\Event\Event $usage */
|
||||
|
||||
$file = $projectDB->getDocument($fileId);
|
||||
|
||||
if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
|
||||
$device = Storage::getDevice('local');
|
||||
|
||||
if ($device->delete($file->getAttribute('path', ''))) {
|
||||
if (!$projectDB->deleteDocument($fileId)) {
|
||||
throw new Exception('Failed to remove file from DB', 500);
|
||||
}
|
||||
}
|
||||
|
||||
$webhook
|
||||
->setParam('payload', $file->getArrayCopy())
|
||||
;
|
||||
|
||||
$audit
|
||||
->setParam('event', 'storage.files.delete')
|
||||
->setParam('resource', 'storage/files/'.$file->getId())
|
||||
;
|
||||
|
||||
$usage
|
||||
->setParam('storage', $file->getAttribute('size', 0) * -1)
|
||||
;
|
||||
|
||||
$response->noContent();
|
||||
if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
);
|
||||
|
||||
$device = Storage::getDevice('local');
|
||||
|
||||
if ($device->delete($file->getAttribute('path', ''))) {
|
||||
if (!$projectDB->deleteDocument($fileId)) {
|
||||
throw new Exception('Failed to remove file from DB', 500);
|
||||
}
|
||||
}
|
||||
|
||||
$webhook
|
||||
->setParam('payload', $file->getArrayCopy())
|
||||
;
|
||||
|
||||
$audit
|
||||
->setParam('event', 'storage.files.delete')
|
||||
->setParam('resource', 'storage/files/'.$file->getId())
|
||||
;
|
||||
|
||||
$usage
|
||||
->setParam('storage', $file->getAttribute('size', 0) * -1)
|
||||
;
|
||||
|
||||
$response->noContent();
|
||||
}, ['fileId', 'response', 'projectDB', 'webhook', 'audit', 'usage']);
|
||||
|
||||
// App::get('/v1/storage/files/:fileId/scan')
|
||||
// ->desc('Scan Storage')
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,7 +11,6 @@ use Utopia\Validator\Range;
|
|||
use Utopia\Audit\Audit;
|
||||
use Utopia\Audit\Adapters\MySQL as AuditAdapter;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Locale\Locale;
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Auth\Validator\Password;
|
||||
use Appwrite\Database\Database;
|
||||
|
@ -31,64 +30,65 @@ App::post('/v1/users')
|
|||
->param('email', '', function () { return new Email(); }, 'User email.')
|
||||
->param('password', '', function () { return new Password(); }, 'User password. Must be between 6 to 32 chars.')
|
||||
->param('name', '', function () { return new Text(100); }, 'User name.', true)
|
||||
->action(
|
||||
function ($email, $password, $name) use ($response, $projectDB) {
|
||||
$profile = $projectDB->getCollectionFirst([ // Get user by email address
|
||||
'limit' => 1,
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_USERS,
|
||||
'email='.$email,
|
||||
],
|
||||
]);
|
||||
->action(function ($email, $password, $name, $response, $projectDB) {
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
|
||||
if (!empty($profile)) {
|
||||
throw new Exception('User already registered', 409);
|
||||
}
|
||||
$profile = $projectDB->getCollectionFirst([ // Get user by email address
|
||||
'limit' => 1,
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_USERS,
|
||||
'email='.$email,
|
||||
],
|
||||
]);
|
||||
|
||||
try {
|
||||
$user = $projectDB->createDocument([
|
||||
'$collection' => Database::SYSTEM_COLLECTION_USERS,
|
||||
'$permissions' => [
|
||||
'read' => ['*'],
|
||||
'write' => ['user:{self}'],
|
||||
],
|
||||
'email' => $email,
|
||||
'emailVerification' => false,
|
||||
'status' => Auth::USER_STATUS_UNACTIVATED,
|
||||
'password' => Auth::passwordHash($password),
|
||||
'password-update' => \time(),
|
||||
'registration' => \time(),
|
||||
'reset' => false,
|
||||
'name' => $name,
|
||||
], ['email' => $email]);
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception('Account already exists', 409);
|
||||
}
|
||||
|
||||
$oauth2Keys = [];
|
||||
|
||||
foreach (Config::getParam('providers') as $key => $provider) {
|
||||
if (!$provider['enabled']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$oauth2Keys[] = 'oauth2'.\ucfirst($key);
|
||||
$oauth2Keys[] = 'oauth2'.\ucfirst($key).'AccessToken';
|
||||
}
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->json(\array_merge($user->getArrayCopy(\array_merge([
|
||||
'$id',
|
||||
'status',
|
||||
'email',
|
||||
'registration',
|
||||
'emailVerification',
|
||||
'name',
|
||||
], $oauth2Keys)), ['roles' => []]));
|
||||
if (!empty($profile)) {
|
||||
throw new Exception('User already registered', 409);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
try {
|
||||
$user = $projectDB->createDocument([
|
||||
'$collection' => Database::SYSTEM_COLLECTION_USERS,
|
||||
'$permissions' => [
|
||||
'read' => ['*'],
|
||||
'write' => ['user:{self}'],
|
||||
],
|
||||
'email' => $email,
|
||||
'emailVerification' => false,
|
||||
'status' => Auth::USER_STATUS_UNACTIVATED,
|
||||
'password' => Auth::passwordHash($password),
|
||||
'password-update' => \time(),
|
||||
'registration' => \time(),
|
||||
'reset' => false,
|
||||
'name' => $name,
|
||||
], ['email' => $email]);
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception('Account already exists', 409);
|
||||
}
|
||||
|
||||
$oauth2Keys = [];
|
||||
|
||||
foreach (Config::getParam('providers') as $key => $provider) {
|
||||
if (!$provider['enabled']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$oauth2Keys[] = 'oauth2'.\ucfirst($key);
|
||||
$oauth2Keys[] = 'oauth2'.\ucfirst($key).'AccessToken';
|
||||
}
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->json(\array_merge($user->getArrayCopy(\array_merge([
|
||||
'$id',
|
||||
'status',
|
||||
'email',
|
||||
'registration',
|
||||
'emailVerification',
|
||||
'name',
|
||||
], $oauth2Keys)), ['roles' => []]));
|
||||
}, ['response', 'projectDB']);
|
||||
|
||||
App::get('/v1/users')
|
||||
->desc('List Users')
|
||||
->groups(['api', 'users'])
|
||||
|
@ -101,48 +101,49 @@ App::get('/v1/users')
|
|||
->param('limit', 25, function () { return new Range(0, 100); }, 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, function () { return new Range(0, 2000); }, 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('orderType', 'ASC', function () { return new WhiteList(['ASC', 'DESC']); }, 'Order result by ASC or DESC order.', true)
|
||||
->action(
|
||||
function ($search, $limit, $offset, $orderType) use ($response, $projectDB) {
|
||||
$results = $projectDB->getCollection([
|
||||
'limit' => $limit,
|
||||
'offset' => $offset,
|
||||
'orderField' => 'registration',
|
||||
'orderType' => $orderType,
|
||||
'orderCast' => 'int',
|
||||
'search' => $search,
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_USERS,
|
||||
],
|
||||
]);
|
||||
->action(function ($search, $limit, $offset, $orderType, $response, $projectDB) {
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
|
||||
$oauth2Keys = [];
|
||||
$results = $projectDB->getCollection([
|
||||
'limit' => $limit,
|
||||
'offset' => $offset,
|
||||
'orderField' => 'registration',
|
||||
'orderType' => $orderType,
|
||||
'orderCast' => 'int',
|
||||
'search' => $search,
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_USERS,
|
||||
],
|
||||
]);
|
||||
|
||||
foreach (Config::getParam('providers') as $key => $provider) {
|
||||
if (!$provider['enabled']) {
|
||||
continue;
|
||||
}
|
||||
$oauth2Keys = [];
|
||||
|
||||
$oauth2Keys[] = 'oauth2'.\ucfirst($key);
|
||||
$oauth2Keys[] = 'oauth2'.\ucfirst($key).'AccessToken';
|
||||
foreach (Config::getParam('providers') as $key => $provider) {
|
||||
if (!$provider['enabled']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$results = \array_map(function ($value) use ($oauth2Keys) { /* @var $value \Database\Document */
|
||||
return $value->getArrayCopy(\array_merge(
|
||||
[
|
||||
'$id',
|
||||
'status',
|
||||
'email',
|
||||
'registration',
|
||||
'emailVerification',
|
||||
'name',
|
||||
],
|
||||
$oauth2Keys
|
||||
));
|
||||
}, $results);
|
||||
|
||||
$response->json(['sum' => $projectDB->getSum(), 'users' => $results]);
|
||||
$oauth2Keys[] = 'oauth2'.\ucfirst($key);
|
||||
$oauth2Keys[] = 'oauth2'.\ucfirst($key).'AccessToken';
|
||||
}
|
||||
);
|
||||
|
||||
$results = \array_map(function ($value) use ($oauth2Keys) { /* @var $value \Database\Document */
|
||||
return $value->getArrayCopy(\array_merge(
|
||||
[
|
||||
'$id',
|
||||
'status',
|
||||
'email',
|
||||
'registration',
|
||||
'emailVerification',
|
||||
'name',
|
||||
],
|
||||
$oauth2Keys
|
||||
));
|
||||
}, $results);
|
||||
|
||||
$response->json(['sum' => $projectDB->getSum(), 'users' => $results]);
|
||||
}, ['response', 'projectDB']);
|
||||
|
||||
App::get('/v1/users/:userId')
|
||||
->desc('Get User')
|
||||
|
@ -153,38 +154,39 @@ App::get('/v1/users/:userId')
|
|||
->label('sdk.method', 'get')
|
||||
->label('sdk.description', '/docs/references/users/get-user.md')
|
||||
->param('userId', '', function () { return new UID(); }, 'User unique ID.')
|
||||
->action(
|
||||
function ($userId) use ($response, $projectDB) {
|
||||
$user = $projectDB->getDocument($userId);
|
||||
->action(function ($userId, $response, $projectDB) {
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
|
||||
if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
$user = $projectDB->getDocument($userId);
|
||||
|
||||
$oauth2Keys = [];
|
||||
|
||||
foreach (Config::getParam('providers') as $key => $provider) {
|
||||
if (!$provider['enabled']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$oauth2Keys[] = 'oauth2'.\ucfirst($key);
|
||||
$oauth2Keys[] = 'oauth2'.\ucfirst($key).'AccessToken';
|
||||
}
|
||||
|
||||
$response->json(\array_merge($user->getArrayCopy(\array_merge(
|
||||
[
|
||||
'$id',
|
||||
'status',
|
||||
'email',
|
||||
'registration',
|
||||
'emailVerification',
|
||||
'name',
|
||||
],
|
||||
$oauth2Keys
|
||||
)), ['roles' => []]));
|
||||
if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
);
|
||||
|
||||
$oauth2Keys = [];
|
||||
|
||||
foreach (Config::getParam('providers') as $key => $provider) {
|
||||
if (!$provider['enabled']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$oauth2Keys[] = 'oauth2'.\ucfirst($key);
|
||||
$oauth2Keys[] = 'oauth2'.\ucfirst($key).'AccessToken';
|
||||
}
|
||||
|
||||
$response->json(\array_merge($user->getArrayCopy(\array_merge(
|
||||
[
|
||||
'$id',
|
||||
'status',
|
||||
'email',
|
||||
'registration',
|
||||
'emailVerification',
|
||||
'name',
|
||||
],
|
||||
$oauth2Keys
|
||||
)), ['roles' => []]));
|
||||
}, ['response', 'projectDB']);
|
||||
|
||||
App::get('/v1/users/:userId/prefs')
|
||||
->desc('Get User Preferences')
|
||||
|
@ -195,26 +197,27 @@ App::get('/v1/users/:userId/prefs')
|
|||
->label('sdk.method', 'getPrefs')
|
||||
->label('sdk.description', '/docs/references/users/get-user-prefs.md')
|
||||
->param('userId', '', function () { return new UID(); }, 'User unique ID.')
|
||||
->action(
|
||||
function ($userId) use ($response, $projectDB) {
|
||||
$user = $projectDB->getDocument($userId);
|
||||
->action(function ($userId, $response, $projectDB) {
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
|
||||
if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
$user = $projectDB->getDocument($userId);
|
||||
|
||||
$prefs = $user->getAttribute('prefs', '');
|
||||
|
||||
try {
|
||||
$prefs = \json_decode($prefs, true);
|
||||
$prefs = ($prefs) ? $prefs : [];
|
||||
} catch (\Exception $error) {
|
||||
throw new Exception('Failed to parse prefs', 500);
|
||||
}
|
||||
|
||||
$response->json($prefs);
|
||||
if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
);
|
||||
|
||||
$prefs = $user->getAttribute('prefs', '');
|
||||
|
||||
try {
|
||||
$prefs = \json_decode($prefs, true);
|
||||
$prefs = ($prefs) ? $prefs : [];
|
||||
} catch (\Exception $error) {
|
||||
throw new Exception('Failed to parse prefs', 500);
|
||||
}
|
||||
|
||||
$response->json($prefs);
|
||||
}, ['response', 'projectDB']);
|
||||
|
||||
App::get('/v1/users/:userId/sessions')
|
||||
->desc('Get User Sessions')
|
||||
|
@ -225,60 +228,62 @@ App::get('/v1/users/:userId/sessions')
|
|||
->label('sdk.method', 'getSessions')
|
||||
->label('sdk.description', '/docs/references/users/get-user-sessions.md')
|
||||
->param('userId', '', function () { return new UID(); }, 'User unique ID.')
|
||||
->action(
|
||||
function ($userId) use ($response, $projectDB) {
|
||||
$user = $projectDB->getDocument($userId);
|
||||
->action(function ($userId, $response, $projectDB, $locale) {
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
|
||||
if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
$user = $projectDB->getDocument($userId);
|
||||
|
||||
$tokens = $user->getAttribute('tokens', []);
|
||||
$reader = new Reader(__DIR__.'/../../db/DBIP/dbip-country-lite-2020-01.mmdb');
|
||||
$sessions = [];
|
||||
$index = 0;
|
||||
$countries = Locale::getText('countries');
|
||||
|
||||
foreach ($tokens as $token) { /* @var $token Document */
|
||||
if (Auth::TOKEN_TYPE_LOGIN != $token->getAttribute('type')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$userAgent = (!empty($token->getAttribute('userAgent'))) ? $token->getAttribute('userAgent') : 'UNKNOWN';
|
||||
|
||||
$dd = new DeviceDetector($userAgent);
|
||||
|
||||
// OPTIONAL: If called, bot detection will completely be skipped (bots will be detected as regular devices then)
|
||||
// $dd->skipBotDetection();
|
||||
|
||||
$dd->parse();
|
||||
|
||||
$sessions[$index] = [
|
||||
'$id' => $token->getId(),
|
||||
'OS' => $dd->getOs(),
|
||||
'client' => $dd->getClient(),
|
||||
'device' => $dd->getDevice(),
|
||||
'brand' => $dd->getBrand(),
|
||||
'model' => $dd->getModel(),
|
||||
'ip' => $token->getAttribute('ip', ''),
|
||||
'geo' => [],
|
||||
];
|
||||
|
||||
try {
|
||||
$record = $reader->country($token->getAttribute('ip', ''));
|
||||
$sessions[$index]['geo']['isoCode'] = \strtolower($record->country->isoCode);
|
||||
$sessions[$index]['geo']['country'] = (isset($countries[$record->country->isoCode])) ? $countries[$record->country->isoCode] : Locale::getText('locale.country.unknown');
|
||||
} catch (\Exception $e) {
|
||||
$sessions[$index]['geo']['isoCode'] = '--';
|
||||
$sessions[$index]['geo']['country'] = Locale::getText('locale.country.unknown');
|
||||
}
|
||||
|
||||
++$index;
|
||||
}
|
||||
|
||||
$response->json($sessions);
|
||||
if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
);
|
||||
|
||||
$tokens = $user->getAttribute('tokens', []);
|
||||
$reader = new Reader(__DIR__.'/../../db/DBIP/dbip-country-lite-2020-01.mmdb');
|
||||
$sessions = [];
|
||||
$index = 0;
|
||||
$countries = $locale->getText('countries');
|
||||
|
||||
foreach ($tokens as $token) { /* @var $token Document */
|
||||
if (Auth::TOKEN_TYPE_LOGIN != $token->getAttribute('type')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$userAgent = (!empty($token->getAttribute('userAgent'))) ? $token->getAttribute('userAgent') : 'UNKNOWN';
|
||||
|
||||
$dd = new DeviceDetector($userAgent);
|
||||
|
||||
// OPTIONAL: If called, bot detection will completely be skipped (bots will be detected as regular devices then)
|
||||
// $dd->skipBotDetection();
|
||||
|
||||
$dd->parse();
|
||||
|
||||
$sessions[$index] = [
|
||||
'$id' => $token->getId(),
|
||||
'OS' => $dd->getOs(),
|
||||
'client' => $dd->getClient(),
|
||||
'device' => $dd->getDevice(),
|
||||
'brand' => $dd->getBrand(),
|
||||
'model' => $dd->getModel(),
|
||||
'ip' => $token->getAttribute('ip', ''),
|
||||
'geo' => [],
|
||||
];
|
||||
|
||||
try {
|
||||
$record = $reader->country($token->getAttribute('ip', ''));
|
||||
$sessions[$index]['geo']['isoCode'] = \strtolower($record->country->isoCode);
|
||||
$sessions[$index]['geo']['country'] = (isset($countries[$record->country->isoCode])) ? $countries[$record->country->isoCode] : $locale->getText('locale.country.unknown');
|
||||
} catch (\Exception $e) {
|
||||
$sessions[$index]['geo']['isoCode'] = '--';
|
||||
$sessions[$index]['geo']['country'] = $locale->getText('locale.country.unknown');
|
||||
}
|
||||
|
||||
++$index;
|
||||
}
|
||||
|
||||
$response->json($sessions);
|
||||
}, ['response', 'projectDB', 'locale']);
|
||||
|
||||
App::get('/v1/users/:userId/logs')
|
||||
->desc('Get User Logs')
|
||||
|
@ -289,77 +294,81 @@ App::get('/v1/users/:userId/logs')
|
|||
->label('sdk.method', 'getLogs')
|
||||
->label('sdk.description', '/docs/references/users/get-user-logs.md')
|
||||
->param('userId', '', function () { return new UID(); }, 'User unique ID.')
|
||||
->action(
|
||||
function ($userId) use ($response, $register, $projectDB, $project) {
|
||||
$user = $projectDB->getDocument($userId);
|
||||
->action(function ($userId, $response, $register, $project, $projectDB, $locale) {
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Utopia\Registry\Registry $register */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
|
||||
$user = $projectDB->getDocument($userId);
|
||||
|
||||
if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
$adapter = new AuditAdapter($register->get('db'));
|
||||
$adapter->setNamespace('app_'.$project->getId());
|
||||
|
||||
$audit = new Audit($adapter);
|
||||
|
||||
$countries = Locale::getText('countries');
|
||||
|
||||
$logs = $audit->getLogsByUserAndActions($user->getId(), [
|
||||
'account.create',
|
||||
'account.delete',
|
||||
'account.update.name',
|
||||
'account.update.email',
|
||||
'account.update.password',
|
||||
'account.update.prefs',
|
||||
'account.sessions.create',
|
||||
'account.sessions.delete',
|
||||
'account.recovery.create',
|
||||
'account.recovery.update',
|
||||
'account.verification.create',
|
||||
'account.verification.update',
|
||||
'teams.membership.create',
|
||||
'teams.membership.update',
|
||||
'teams.membership.delete',
|
||||
]);
|
||||
|
||||
$reader = new Reader(__DIR__.'/../../db/DBIP/dbip-country-lite-2020-01.mmdb');
|
||||
$output = [];
|
||||
|
||||
foreach ($logs as $i => &$log) {
|
||||
$log['userAgent'] = (!empty($log['userAgent'])) ? $log['userAgent'] : 'UNKNOWN';
|
||||
|
||||
$dd = new DeviceDetector($log['userAgent']);
|
||||
|
||||
$dd->skipBotDetection(); // OPTIONAL: If called, bot detection will completely be skipped (bots will be detected as regular devices then)
|
||||
|
||||
$dd->parse();
|
||||
|
||||
$output[$i] = [
|
||||
'event' => $log['event'],
|
||||
'ip' => $log['ip'],
|
||||
'time' => \strtotime($log['time']),
|
||||
'OS' => $dd->getOs(),
|
||||
'client' => $dd->getClient(),
|
||||
'device' => $dd->getDevice(),
|
||||
'brand' => $dd->getBrand(),
|
||||
'model' => $dd->getModel(),
|
||||
'geo' => [],
|
||||
];
|
||||
|
||||
try {
|
||||
$record = $reader->country($log['ip']);
|
||||
$output[$i]['geo']['isoCode'] = \strtolower($record->country->isoCode);
|
||||
$output[$i]['geo']['country'] = $record->country->name;
|
||||
$output[$i]['geo']['country'] = (isset($countries[$record->country->isoCode])) ? $countries[$record->country->isoCode] : Locale::getText('locale.country.unknown');
|
||||
} catch (\Exception $e) {
|
||||
$output[$i]['geo']['isoCode'] = '--';
|
||||
$output[$i]['geo']['country'] = Locale::getText('locale.country.unknown');
|
||||
}
|
||||
}
|
||||
|
||||
$response->json($output);
|
||||
if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
);
|
||||
|
||||
$adapter = new AuditAdapter($register->get('db'));
|
||||
$adapter->setNamespace('app_'.$project->getId());
|
||||
|
||||
$audit = new Audit($adapter);
|
||||
|
||||
$countries = $locale->getText('countries');
|
||||
|
||||
$logs = $audit->getLogsByUserAndActions($user->getId(), [
|
||||
'account.create',
|
||||
'account.delete',
|
||||
'account.update.name',
|
||||
'account.update.email',
|
||||
'account.update.password',
|
||||
'account.update.prefs',
|
||||
'account.sessions.create',
|
||||
'account.sessions.delete',
|
||||
'account.recovery.create',
|
||||
'account.recovery.update',
|
||||
'account.verification.create',
|
||||
'account.verification.update',
|
||||
'teams.membership.create',
|
||||
'teams.membership.update',
|
||||
'teams.membership.delete',
|
||||
]);
|
||||
|
||||
$reader = new Reader(__DIR__.'/../../db/DBIP/dbip-country-lite-2020-01.mmdb');
|
||||
$output = [];
|
||||
|
||||
foreach ($logs as $i => &$log) {
|
||||
$log['userAgent'] = (!empty($log['userAgent'])) ? $log['userAgent'] : 'UNKNOWN';
|
||||
|
||||
$dd = new DeviceDetector($log['userAgent']);
|
||||
|
||||
$dd->skipBotDetection(); // OPTIONAL: If called, bot detection will completely be skipped (bots will be detected as regular devices then)
|
||||
|
||||
$dd->parse();
|
||||
|
||||
$output[$i] = [
|
||||
'event' => $log['event'],
|
||||
'ip' => $log['ip'],
|
||||
'time' => \strtotime($log['time']),
|
||||
'OS' => $dd->getOs(),
|
||||
'client' => $dd->getClient(),
|
||||
'device' => $dd->getDevice(),
|
||||
'brand' => $dd->getBrand(),
|
||||
'model' => $dd->getModel(),
|
||||
'geo' => [],
|
||||
];
|
||||
|
||||
try {
|
||||
$record = $reader->country($log['ip']);
|
||||
$output[$i]['geo']['isoCode'] = \strtolower($record->country->isoCode);
|
||||
$output[$i]['geo']['country'] = $record->country->name;
|
||||
$output[$i]['geo']['country'] = (isset($countries[$record->country->isoCode])) ? $countries[$record->country->isoCode] : $locale->getText('locale.country.unknown');
|
||||
} catch (\Exception $e) {
|
||||
$output[$i]['geo']['isoCode'] = '--';
|
||||
$output[$i]['geo']['country'] = $locale->getText('locale.country.unknown');
|
||||
}
|
||||
}
|
||||
|
||||
$response->json($output);
|
||||
}, ['response', 'register', 'project', 'projectDB', 'locale']);
|
||||
|
||||
App::patch('/v1/users/:userId/status')
|
||||
->desc('Update User Status')
|
||||
|
@ -371,44 +380,45 @@ App::patch('/v1/users/:userId/status')
|
|||
->label('sdk.description', '/docs/references/users/update-user-status.md')
|
||||
->param('userId', '', function () { return new UID(); }, 'User unique ID.')
|
||||
->param('status', '', function () { return new WhiteList([Auth::USER_STATUS_ACTIVATED, Auth::USER_STATUS_BLOCKED, Auth::USER_STATUS_UNACTIVATED]); }, 'User Status code. To activate the user pass '.Auth::USER_STATUS_ACTIVATED.', to block the user pass '.Auth::USER_STATUS_BLOCKED.' and for disabling the user pass '.Auth::USER_STATUS_UNACTIVATED)
|
||||
->action(
|
||||
function ($userId, $status) use ($response, $projectDB) {
|
||||
$user = $projectDB->getDocument($userId);
|
||||
->action(function ($userId, $status, $response, $projectDB) {
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
|
||||
if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
$user = $projectDB->getDocument($userId);
|
||||
|
||||
$user = $projectDB->updateDocument(\array_merge($user->getArrayCopy(), [
|
||||
'status' => (int)$status,
|
||||
]));
|
||||
|
||||
if (false === $user) {
|
||||
throw new Exception('Failed saving user to DB', 500);
|
||||
}
|
||||
|
||||
$oauth2Keys = [];
|
||||
|
||||
foreach (Config::getParam('providers') as $key => $provider) {
|
||||
if (!$provider['enabled']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$oauth2Keys[] = 'oauth2'.\ucfirst($key);
|
||||
$oauth2Keys[] = 'oauth2'.\ucfirst($key).'AccessToken';
|
||||
}
|
||||
|
||||
$response
|
||||
->json(\array_merge($user->getArrayCopy(\array_merge([
|
||||
'$id',
|
||||
'status',
|
||||
'email',
|
||||
'registration',
|
||||
'emailVerification',
|
||||
'name',
|
||||
], $oauth2Keys)), ['roles' => []]));
|
||||
if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
);
|
||||
|
||||
$user = $projectDB->updateDocument(\array_merge($user->getArrayCopy(), [
|
||||
'status' => (int)$status,
|
||||
]));
|
||||
|
||||
if (false === $user) {
|
||||
throw new Exception('Failed saving user to DB', 500);
|
||||
}
|
||||
|
||||
$oauth2Keys = [];
|
||||
|
||||
foreach (Config::getParam('providers') as $key => $provider) {
|
||||
if (!$provider['enabled']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$oauth2Keys[] = 'oauth2'.\ucfirst($key);
|
||||
$oauth2Keys[] = 'oauth2'.\ucfirst($key).'AccessToken';
|
||||
}
|
||||
|
||||
$response
|
||||
->json(\array_merge($user->getArrayCopy(\array_merge([
|
||||
'$id',
|
||||
'status',
|
||||
'email',
|
||||
'registration',
|
||||
'emailVerification',
|
||||
'name',
|
||||
], $oauth2Keys)), ['roles' => []]));
|
||||
}, ['response', 'projectDB']);
|
||||
|
||||
App::patch('/v1/users/:userId/prefs')
|
||||
->desc('Update User Preferences')
|
||||
|
@ -420,37 +430,38 @@ App::patch('/v1/users/:userId/prefs')
|
|||
->label('sdk.description', '/docs/references/users/update-user-prefs.md')
|
||||
->param('userId', '', function () { return new UID(); }, 'User unique ID.')
|
||||
->param('prefs', '', function () { return new Assoc();}, 'Prefs key-value JSON object.')
|
||||
->action(
|
||||
function ($userId, $prefs) use ($response, $projectDB) {
|
||||
$user = $projectDB->getDocument($userId);
|
||||
->action(function ($userId, $prefs, $response, $projectDB) {
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
|
||||
if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
$user = $projectDB->getDocument($userId);
|
||||
|
||||
$old = \json_decode($user->getAttribute('prefs', '{}'), true);
|
||||
$old = ($old) ? $old : [];
|
||||
|
||||
$user = $projectDB->updateDocument(\array_merge($user->getArrayCopy(), [
|
||||
'prefs' => \json_encode(\array_merge($old, $prefs)),
|
||||
]));
|
||||
|
||||
if (false === $user) {
|
||||
throw new Exception('Failed saving user to DB', 500);
|
||||
}
|
||||
|
||||
$prefs = $user->getAttribute('prefs', '');
|
||||
|
||||
try {
|
||||
$prefs = \json_decode($prefs, true);
|
||||
$prefs = ($prefs) ? $prefs : [];
|
||||
} catch (\Exception $error) {
|
||||
throw new Exception('Failed to parse prefs', 500);
|
||||
}
|
||||
|
||||
$response->json($prefs);
|
||||
if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
);
|
||||
|
||||
$old = \json_decode($user->getAttribute('prefs', '{}'), true);
|
||||
$old = ($old) ? $old : [];
|
||||
|
||||
$user = $projectDB->updateDocument(\array_merge($user->getArrayCopy(), [
|
||||
'prefs' => \json_encode(\array_merge($old, $prefs)),
|
||||
]));
|
||||
|
||||
if (false === $user) {
|
||||
throw new Exception('Failed saving user to DB', 500);
|
||||
}
|
||||
|
||||
$prefs = $user->getAttribute('prefs', '');
|
||||
|
||||
try {
|
||||
$prefs = \json_decode($prefs, true);
|
||||
$prefs = ($prefs) ? $prefs : [];
|
||||
} catch (\Exception $error) {
|
||||
throw new Exception('Failed to parse prefs', 500);
|
||||
}
|
||||
|
||||
$response->json($prefs);
|
||||
}, ['response', 'projectDB']);
|
||||
|
||||
|
||||
App::delete('/v1/users/:userId/sessions/:sessionId')
|
||||
|
@ -464,27 +475,28 @@ App::delete('/v1/users/:userId/sessions/:sessionId')
|
|||
->label('abuse-limit', 100)
|
||||
->param('userId', '', function () { return new UID(); }, 'User unique ID.')
|
||||
->param('sessionId', null, function () { return new UID(); }, 'User unique session ID.')
|
||||
->action(
|
||||
function ($userId, $sessionId) use ($response, $request, $projectDB) {
|
||||
$user = $projectDB->getDocument($userId);
|
||||
->action(function ($userId, $sessionId, $response, $projectDB) {
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
|
||||
if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
$user = $projectDB->getDocument($userId);
|
||||
|
||||
$tokens = $user->getAttribute('tokens', []);
|
||||
if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
foreach ($tokens as $token) { /* @var $token Document */
|
||||
if ($sessionId == $token->getId()) {
|
||||
if (!$projectDB->deleteDocument($token->getId())) {
|
||||
throw new Exception('Failed to remove token from DB', 500);
|
||||
}
|
||||
$tokens = $user->getAttribute('tokens', []);
|
||||
|
||||
foreach ($tokens as $token) { /* @var $token Document */
|
||||
if ($sessionId == $token->getId()) {
|
||||
if (!$projectDB->deleteDocument($token->getId())) {
|
||||
throw new Exception('Failed to remove token from DB', 500);
|
||||
}
|
||||
}
|
||||
|
||||
$response->json(array('result' => 'success'));
|
||||
}
|
||||
);
|
||||
|
||||
$response->json(array('result' => 'success'));
|
||||
}, ['response', 'projectDB']);
|
||||
|
||||
App::delete('/v1/users/:userId/sessions')
|
||||
->desc('Delete User Sessions')
|
||||
|
@ -496,22 +508,23 @@ App::delete('/v1/users/:userId/sessions')
|
|||
->label('sdk.description', '/docs/references/users/delete-user-sessions.md')
|
||||
->label('abuse-limit', 100)
|
||||
->param('userId', '', function () { return new UID(); }, 'User unique ID.')
|
||||
->action(
|
||||
function ($userId) use ($response, $request, $projectDB) {
|
||||
$user = $projectDB->getDocument($userId);
|
||||
->action(function ($userId, $response, $projectDB) {
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
|
||||
if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
$user = $projectDB->getDocument($userId);
|
||||
|
||||
$tokens = $user->getAttribute('tokens', []);
|
||||
|
||||
foreach ($tokens as $token) { /* @var $token Document */
|
||||
if (!$projectDB->deleteDocument($token->getId())) {
|
||||
throw new Exception('Failed to remove token from DB', 500);
|
||||
}
|
||||
}
|
||||
|
||||
$response->json(array('result' => 'success'));
|
||||
if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
);
|
||||
|
||||
$tokens = $user->getAttribute('tokens', []);
|
||||
|
||||
foreach ($tokens as $token) { /* @var $token Document */
|
||||
if (!$projectDB->deleteDocument($token->getId())) {
|
||||
throw new Exception('Failed to remove token from DB', 500);
|
||||
}
|
||||
}
|
||||
|
||||
$response->json(array('result' => 'success'));
|
||||
}, ['response', 'projectDB']);
|
||||
|
|
|
@ -4,7 +4,11 @@ use Utopia\App;
|
|||
use Utopia\View;
|
||||
use Utopia\Config\Config;
|
||||
|
||||
App::init(function ($utopia, $response, $request, $layout) {
|
||||
App::init(function ($utopia, $request, $response, $layout) {
|
||||
/** @var Utopia\App $utopia */
|
||||
/** @var Utopia\Request $request */
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Utopia\View $layout */
|
||||
|
||||
/* AJAX check */
|
||||
if (!empty($request->getQuery('version', ''))) {
|
||||
|
@ -12,7 +16,7 @@ App::init(function ($utopia, $response, $request, $layout) {
|
|||
}
|
||||
$layout
|
||||
->setParam('title', APP_NAME)
|
||||
->setParam('protocol', Config::getParam('protocol'))
|
||||
->setParam('protocol', $request->getProtocol())
|
||||
->setParam('domain', Config::getParam('domain'))
|
||||
->setParam('home', App::getEnv('_APP_HOME'))
|
||||
->setParam('setup', App::getEnv('_APP_SETUP'))
|
||||
|
@ -36,8 +40,8 @@ App::init(function ($utopia, $response, $request, $layout) {
|
|||
$route = $utopia->match($request);
|
||||
$scope = $route->getLabel('scope', '');
|
||||
$layout
|
||||
->setParam('version', Config::getParam('version'))
|
||||
->setParam('version', App::getEnv('_APP_VERSION', 'UNKNOWN'))
|
||||
->setParam('isDev', App::isDevelopment())
|
||||
->setParam('class', $scope)
|
||||
;
|
||||
}, ['utopia', 'response', 'request', 'layout'], 'web');
|
||||
}, ['utopia', 'request', 'response', 'layout'], 'web');
|
||||
|
|
|
@ -29,7 +29,7 @@ App::shutdown(function ($response, $layout) {
|
|||
|
||||
$footer
|
||||
->setParam('home', App::getEnv('_APP_HOME', ''))
|
||||
->setParam('version', Config::getParam('version'))
|
||||
->setParam('version', App::getEnv('_APP_VERSION', 'UNKNOWN'))
|
||||
;
|
||||
|
||||
$layout
|
||||
|
|
|
@ -9,11 +9,13 @@ use Utopia\Validator\WhiteList;
|
|||
use Utopia\Validator\Range;
|
||||
|
||||
App::init(function ($layout) {
|
||||
/** @var Utopia\View $layout */
|
||||
|
||||
$header = new View(__DIR__.'/../../views/home/comps/header.phtml');
|
||||
$footer = new View(__DIR__.'/../../views/home/comps/footer.phtml');
|
||||
|
||||
$footer
|
||||
->setParam('version', Config::getParam('version'))
|
||||
->setParam('version', App::getEnv('_APP_VERSION', 'UNKNOWN'))
|
||||
;
|
||||
|
||||
$layout
|
||||
|
@ -27,6 +29,9 @@ App::init(function ($layout) {
|
|||
}, ['layout'], 'home');
|
||||
|
||||
App::shutdown(function ($response, $layout) {
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Utopia\View $layout */
|
||||
|
||||
$response->send($layout->render());
|
||||
}, ['response', 'layout'], 'home');
|
||||
|
||||
|
@ -34,90 +39,102 @@ App::get('/')
|
|||
->groups(['web', 'home'])
|
||||
->label('permission', 'public')
|
||||
->label('scope', 'home')
|
||||
->action(
|
||||
function () use ($response) {
|
||||
$response->redirect('/auth/signin');
|
||||
}
|
||||
);
|
||||
->action(function ($response) {
|
||||
/** @var Utopia\Response $response */
|
||||
|
||||
$response->redirect('/auth/signin');
|
||||
}, ['response']);
|
||||
|
||||
App::get('/auth/signin')
|
||||
->groups(['web', 'home'])
|
||||
->label('permission', 'public')
|
||||
->label('scope', 'home')
|
||||
->action(function () use ($layout) {
|
||||
->action(function ($layout) {
|
||||
/** @var Utopia\View $layout */
|
||||
|
||||
$page = new View(__DIR__.'/../../views/home/auth/signin.phtml');
|
||||
|
||||
$layout
|
||||
->setParam('title', 'Sign In - '.APP_NAME)
|
||||
->setParam('body', $page);
|
||||
});
|
||||
}, ['layout']);
|
||||
|
||||
App::get('/auth/signup')
|
||||
->groups(['web', 'home'])
|
||||
->label('permission', 'public')
|
||||
->label('scope', 'home')
|
||||
->action(function () use ($layout) {
|
||||
->action(function ($layout) {
|
||||
/** @var Utopia\View $layout */
|
||||
$page = new View(__DIR__.'/../../views/home/auth/signup.phtml');
|
||||
|
||||
$layout
|
||||
->setParam('title', 'Sign Up - '.APP_NAME)
|
||||
->setParam('body', $page);
|
||||
});
|
||||
}, ['layout']);
|
||||
|
||||
App::get('/auth/recovery')
|
||||
->groups(['web', 'home'])
|
||||
->label('permission', 'public')
|
||||
->label('scope', 'home')
|
||||
->action(function () use ($request, $layout) {
|
||||
->action(function ($layout) {
|
||||
/** @var Utopia\View $layout */
|
||||
|
||||
$page = new View(__DIR__.'/../../views/home/auth/recovery.phtml');
|
||||
|
||||
$layout
|
||||
->setParam('title', 'Password Recovery - '.APP_NAME)
|
||||
->setParam('body', $page);
|
||||
});
|
||||
}, ['layout']);
|
||||
|
||||
App::get('/auth/confirm')
|
||||
->groups(['web', 'home'])
|
||||
->label('permission', 'public')
|
||||
->label('scope', 'home')
|
||||
->action(function () use ($layout) {
|
||||
->action(function ($layout) {
|
||||
/** @var Utopia\View $layout */
|
||||
|
||||
$page = new View(__DIR__.'/../../views/home/auth/confirm.phtml');
|
||||
|
||||
$layout
|
||||
->setParam('title', 'Account Confirmation - '.APP_NAME)
|
||||
->setParam('body', $page);
|
||||
});
|
||||
}, ['layout']);
|
||||
|
||||
App::get('/auth/join')
|
||||
->groups(['web', 'home'])
|
||||
->label('permission', 'public')
|
||||
->label('scope', 'home')
|
||||
->action(function () use ($layout) {
|
||||
->action(function ($layout) {
|
||||
/** @var Utopia\View $layout */
|
||||
|
||||
$page = new View(__DIR__.'/../../views/home/auth/join.phtml');
|
||||
|
||||
$layout
|
||||
->setParam('title', 'Invitation - '.APP_NAME)
|
||||
->setParam('body', $page);
|
||||
});
|
||||
}, ['layout']);
|
||||
|
||||
App::get('/auth/recovery/reset')
|
||||
->groups(['web', 'home'])
|
||||
->label('permission', 'public')
|
||||
->label('scope', 'home')
|
||||
->action(function () use ($layout) {
|
||||
->action(function ($layout) {
|
||||
/** @var Utopia\View $layout */
|
||||
|
||||
$page = new View(__DIR__.'/../../views/home/auth/recovery/reset.phtml');
|
||||
|
||||
$layout
|
||||
->setParam('title', 'Password Reset - '.APP_NAME)
|
||||
->setParam('body', $page);
|
||||
});
|
||||
|
||||
}, ['layout']);
|
||||
|
||||
App::get('/auth/oauth2/success')
|
||||
->groups(['web', 'home'])
|
||||
->label('permission', 'public')
|
||||
->label('scope', 'home')
|
||||
->action(function () use ($layout) {
|
||||
->action(function ($layout) {
|
||||
/** @var Utopia\View $layout */
|
||||
|
||||
$page = new View(__DIR__.'/../../views/home/auth/oauth2.phtml');
|
||||
|
||||
$layout
|
||||
|
@ -126,13 +143,15 @@ App::get('/auth/oauth2/success')
|
|||
->setParam('header', [])
|
||||
->setParam('footer', [])
|
||||
;
|
||||
});
|
||||
}, ['layout']);
|
||||
|
||||
App::get('/auth/oauth2/failure')
|
||||
->groups(['web', 'home'])
|
||||
->label('permission', 'public')
|
||||
->label('scope', 'home')
|
||||
->action(function () use ($layout) {
|
||||
->action(function ($layout) {
|
||||
/** @var Utopia\View $layout */
|
||||
|
||||
$page = new View(__DIR__.'/../../views/home/auth/oauth2.phtml');
|
||||
|
||||
$layout
|
||||
|
@ -141,14 +160,16 @@ App::get('/auth/oauth2/failure')
|
|||
->setParam('header', [])
|
||||
->setParam('footer', [])
|
||||
;
|
||||
});
|
||||
}, ['layout']);
|
||||
|
||||
App::get('/error/:code')
|
||||
->groups(['web', 'home'])
|
||||
->label('permission', 'public')
|
||||
->label('scope', 'home')
|
||||
->param('code', null, new \Utopia\Validator\Numeric(), 'Valid status code number', false)
|
||||
->action(function ($code) use ($layout) {
|
||||
->action(function ($code, $layout) {
|
||||
/** @var Utopia\View $layout */
|
||||
|
||||
$page = new View(__DIR__.'/../../views/error.phtml');
|
||||
|
||||
$page
|
||||
|
@ -158,7 +179,7 @@ App::get('/error/:code')
|
|||
$layout
|
||||
->setParam('title', 'Error'.' - '.APP_NAME)
|
||||
->setParam('body', $page);
|
||||
});
|
||||
}, ['layout']);
|
||||
|
||||
App::get('/open-api-2.json')
|
||||
->groups(['web', 'home'])
|
||||
|
@ -167,401 +188,402 @@ App::get('/open-api-2.json')
|
|||
->param('platform', APP_PLATFORM_CLIENT, function () {return new WhiteList([APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER, APP_PLATFORM_CONSOLE]);}, 'Choose target platform.', true)
|
||||
->param('extensions', 0, function () {return new Range(0, 1);}, 'Show extra data.', true)
|
||||
->param('tests', 0, function () {return new Range(0, 1);}, 'Include only test services.', true)
|
||||
->action(
|
||||
function ($platform, $extensions, $tests) use ($response, $utopia) {
|
||||
$services = Config::getParam('services', []);
|
||||
->action(function ($platform, $extensions, $tests, $utopia, $response) {
|
||||
/** @var Utopia\App $utopia */
|
||||
/** @var Utopia\Response $response */
|
||||
|
||||
$services = Config::getParam('services', []);
|
||||
|
||||
function fromCamelCase($input)
|
||||
{
|
||||
\preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
|
||||
$ret = $matches[0];
|
||||
foreach ($ret as &$match) {
|
||||
$match = $match == \strtoupper($match) ? \strtolower($match) : \lcfirst($match);
|
||||
}
|
||||
|
||||
return \implode('_', $ret);
|
||||
}
|
||||
|
||||
function fromCamelCaseToDash($input)
|
||||
{
|
||||
return \str_replace([' ', '_'], '-', \strtolower(\preg_replace('/([a-zA-Z])(?=[A-Z])/', '$1-', $input)));
|
||||
}
|
||||
|
||||
foreach ($services as $service) { /* @noinspection PhpIncludeInspection */
|
||||
if ($tests && !isset($service['tests'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($tests && !$service['tests']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
function fromCamelCase($input)
|
||||
{
|
||||
\preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
|
||||
$ret = $matches[0];
|
||||
foreach ($ret as &$match) {
|
||||
$match = $match == \strtoupper($match) ? \strtolower($match) : \lcfirst($match);
|
||||
}
|
||||
if (!$tests && !$service['sdk']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
include_once \realpath(__DIR__.'/../../'.$service['controller']);
|
||||
}
|
||||
|
||||
return \implode('_', $ret);
|
||||
$security = [
|
||||
APP_PLATFORM_CLIENT => ['Project' => []],
|
||||
APP_PLATFORM_SERVER => ['Project' => [], 'Key' => []],
|
||||
APP_PLATFORM_CONSOLE => ['Project' => [], 'Key' => []],
|
||||
];
|
||||
|
||||
$platforms = [
|
||||
'client' => APP_PLATFORM_CLIENT,
|
||||
'server' => APP_PLATFORM_SERVER,
|
||||
'all' => APP_PLATFORM_CONSOLE,
|
||||
];
|
||||
|
||||
$keys = [
|
||||
APP_PLATFORM_CLIENT => [
|
||||
'Project' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Project',
|
||||
'description' => 'Your project ID',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Locale' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Locale',
|
||||
'description' => '',
|
||||
'in' => 'header',
|
||||
],
|
||||
],
|
||||
APP_PLATFORM_SERVER => [
|
||||
'Project' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Project',
|
||||
'description' => 'Your project ID',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Key' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Key',
|
||||
'description' => 'Your secret API key',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Locale' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Locale',
|
||||
'description' => '',
|
||||
'in' => 'header',
|
||||
],
|
||||
],
|
||||
APP_PLATFORM_CONSOLE => [
|
||||
'Project' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Project',
|
||||
'description' => 'Your project ID',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Key' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Key',
|
||||
'description' => 'Your secret API key',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Locale' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Locale',
|
||||
'description' => '',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Mode' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Mode',
|
||||
'description' => '',
|
||||
'in' => 'header',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
/*
|
||||
* Specifications (v3.0.0):
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md
|
||||
*/
|
||||
$output = [
|
||||
'swagger' => '2.0',
|
||||
'info' => [
|
||||
'version' => APP_VERSION_STABLE,
|
||||
'title' => APP_NAME,
|
||||
'description' => 'Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)',
|
||||
'termsOfService' => 'https://appwrite.io/policy/terms',
|
||||
'contact' => [
|
||||
'name' => 'Appwrite Team',
|
||||
'url' => 'https://appwrite.io/support',
|
||||
'email' => App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM),
|
||||
],
|
||||
'license' => [
|
||||
'name' => 'BSD-3-Clause',
|
||||
'url' => 'https://raw.githubusercontent.com/appwrite/appwrite/master/LICENSE',
|
||||
],
|
||||
],
|
||||
'host' => \parse_url(App::getEnv('_APP_HOME', Config::getParam('domain')), PHP_URL_HOST),
|
||||
'basePath' => '/v1',
|
||||
'schemes' => ['https'],
|
||||
'consumes' => ['application/json', 'multipart/form-data'],
|
||||
'produces' => ['application/json'],
|
||||
'securityDefinitions' => $keys[$platform],
|
||||
'paths' => [],
|
||||
'definitions' => [
|
||||
// 'Pet' => [
|
||||
// 'required' => ['id', 'name'],
|
||||
// 'properties' => [
|
||||
// 'id' => [
|
||||
// 'type' => 'integer',
|
||||
// 'format' => 'int64',
|
||||
// ],
|
||||
// 'name' => [
|
||||
// 'type' => 'string',
|
||||
// ],
|
||||
// 'tag' => [
|
||||
// 'type' => 'string',
|
||||
// ],
|
||||
// ],
|
||||
// ],
|
||||
// 'Pets' => array(
|
||||
// 'type' => 'array',
|
||||
// 'items' => array(
|
||||
// '$ref' => '#/definitions/Pet',
|
||||
// ),
|
||||
// ),
|
||||
'Error' => array(
|
||||
'required' => array(
|
||||
0 => 'code',
|
||||
1 => 'message',
|
||||
),
|
||||
'properties' => array(
|
||||
'code' => array(
|
||||
'type' => 'integer',
|
||||
'format' => 'int32',
|
||||
),
|
||||
'message' => array(
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
'externalDocs' => [
|
||||
'description' => 'Full API docs, specs and tutorials',
|
||||
'url' => Config::getParam('protocol').'://'.Config::getParam('domain').'/docs',
|
||||
],
|
||||
];
|
||||
|
||||
if ($extensions) {
|
||||
if (isset($output['securityDefinitions']['Project'])) {
|
||||
$output['securityDefinitions']['Project']['extensions'] = ['demo' => '5df5acd0d48c2'];
|
||||
}
|
||||
|
||||
if (isset($output['securityDefinitions']['Key'])) {
|
||||
$output['securityDefinitions']['Key']['extensions'] = ['demo' => '919c2d18fb5d4...a2ae413da83346ad2'];
|
||||
}
|
||||
|
||||
if (isset($output['securityDefinitions']['Locale'])) {
|
||||
$output['securityDefinitions']['Locale']['extensions'] = ['demo' => 'en'];
|
||||
}
|
||||
|
||||
function fromCamelCaseToDash($input)
|
||||
{
|
||||
return \str_replace([' ', '_'], '-', \strtolower(\preg_replace('/([a-zA-Z])(?=[A-Z])/', '$1-', $input)));
|
||||
if (isset($output['securityDefinitions']['Mode'])) {
|
||||
$output['securityDefinitions']['Mode']['extensions'] = ['demo' => ''];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($services as $service) { /* @noinspection PhpIncludeInspection */
|
||||
if ($tests && !isset($service['tests'])) {
|
||||
foreach ($utopia->getRoutes() as $key => $method) {
|
||||
foreach ($method as $route) { /* @var $route \Utopia\Route */
|
||||
if (!$route->getLabel('docs', true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($tests && !$service['tests']) {
|
||||
if (empty($route->getLabel('sdk.namespace', null))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$tests && !$service['sdk']) {
|
||||
|
||||
if ($platform !== APP_PLATFORM_CONSOLE && !\in_array($platforms[$platform], $route->getLabel('sdk.platform', []))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
include_once \realpath(__DIR__.'/../../'.$service['controller']);
|
||||
}
|
||||
|
||||
$security = [
|
||||
APP_PLATFORM_CLIENT => ['Project' => []],
|
||||
APP_PLATFORM_SERVER => ['Project' => [], 'Key' => []],
|
||||
APP_PLATFORM_CONSOLE => ['Project' => [], 'Key' => []],
|
||||
];
|
||||
$url = \str_replace('/v1', '', $route->getURL());
|
||||
$scope = $route->getLabel('scope', '');
|
||||
$hide = $route->getLabel('sdk.hide', false);
|
||||
$consumes = ['application/json'];
|
||||
|
||||
$platforms = [
|
||||
'client' => APP_PLATFORM_CLIENT,
|
||||
'server' => APP_PLATFORM_SERVER,
|
||||
'all' => APP_PLATFORM_CONSOLE,
|
||||
];
|
||||
if ($hide) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$keys = [
|
||||
APP_PLATFORM_CLIENT => [
|
||||
'Project' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Project',
|
||||
'description' => 'Your project ID',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Locale' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Locale',
|
||||
'description' => '',
|
||||
'in' => 'header',
|
||||
],
|
||||
],
|
||||
APP_PLATFORM_SERVER => [
|
||||
'Project' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Project',
|
||||
'description' => 'Your project ID',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Key' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Key',
|
||||
'description' => 'Your secret API key',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Locale' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Locale',
|
||||
'description' => '',
|
||||
'in' => 'header',
|
||||
],
|
||||
],
|
||||
APP_PLATFORM_CONSOLE => [
|
||||
'Project' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Project',
|
||||
'description' => 'Your project ID',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Key' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Key',
|
||||
'description' => 'Your secret API key',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Locale' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Locale',
|
||||
'description' => '',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Mode' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Mode',
|
||||
'description' => '',
|
||||
'in' => 'header',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
/*
|
||||
* Specifications (v3.0.0):
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md
|
||||
*/
|
||||
$output = [
|
||||
'swagger' => '2.0',
|
||||
'info' => [
|
||||
'version' => APP_VERSION_STABLE,
|
||||
'title' => APP_NAME,
|
||||
'description' => 'Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)',
|
||||
'termsOfService' => 'https://appwrite.io/policy/terms',
|
||||
'contact' => [
|
||||
'name' => 'Appwrite Team',
|
||||
'url' => 'https://appwrite.io/support',
|
||||
'email' => App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM),
|
||||
],
|
||||
'license' => [
|
||||
'name' => 'BSD-3-Clause',
|
||||
'url' => 'https://raw.githubusercontent.com/appwrite/appwrite/master/LICENSE',
|
||||
],
|
||||
],
|
||||
'host' => \parse_url(App::getEnv('_APP_HOME', Config::getParam('domain')), PHP_URL_HOST),
|
||||
'basePath' => '/v1',
|
||||
'schemes' => ['https'],
|
||||
'consumes' => ['application/json', 'multipart/form-data'],
|
||||
'produces' => ['application/json'],
|
||||
'securityDefinitions' => $keys[$platform],
|
||||
'paths' => [],
|
||||
'definitions' => [
|
||||
// 'Pet' => [
|
||||
// 'required' => ['id', 'name'],
|
||||
// 'properties' => [
|
||||
// 'id' => [
|
||||
// 'type' => 'integer',
|
||||
// 'format' => 'int64',
|
||||
// ],
|
||||
// 'name' => [
|
||||
// 'type' => 'string',
|
||||
// ],
|
||||
// 'tag' => [
|
||||
// 'type' => 'string',
|
||||
$desc = (!empty($route->getLabel('sdk.description', ''))) ? \realpath('../'.$route->getLabel('sdk.description', '')) : null;
|
||||
|
||||
$temp = [
|
||||
'summary' => $route->getDesc(),
|
||||
'operationId' => $route->getLabel('sdk.method', \uniqid()),
|
||||
'consumes' => [],
|
||||
'tags' => [$route->getLabel('sdk.namespace', 'default')],
|
||||
'description' => ($desc) ? \file_get_contents($desc) : '',
|
||||
|
||||
// 'responses' => [
|
||||
// 200 => [
|
||||
// 'description' => 'An paged array of pets',
|
||||
// 'schema' => [
|
||||
// '$ref' => '#/definitions/Pet',
|
||||
// ],
|
||||
// ],
|
||||
// ],
|
||||
// 'Pets' => array(
|
||||
// 'type' => 'array',
|
||||
// 'items' => array(
|
||||
// '$ref' => '#/definitions/Pet',
|
||||
// ),
|
||||
// ),
|
||||
'Error' => array(
|
||||
'required' => array(
|
||||
0 => 'code',
|
||||
1 => 'message',
|
||||
),
|
||||
'properties' => array(
|
||||
'code' => array(
|
||||
'type' => 'integer',
|
||||
'format' => 'int32',
|
||||
),
|
||||
'message' => array(
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
'externalDocs' => [
|
||||
'description' => 'Full API docs, specs and tutorials',
|
||||
'url' => Config::getParam('protocol').'://'.Config::getParam('domain').'/docs',
|
||||
],
|
||||
];
|
||||
];
|
||||
|
||||
if ($extensions) {
|
||||
if (isset($output['securityDefinitions']['Project'])) {
|
||||
$output['securityDefinitions']['Project']['extensions'] = ['demo' => '5df5acd0d48c2'];
|
||||
}
|
||||
|
||||
if (isset($output['securityDefinitions']['Key'])) {
|
||||
$output['securityDefinitions']['Key']['extensions'] = ['demo' => '919c2d18fb5d4...a2ae413da83346ad2'];
|
||||
}
|
||||
|
||||
if (isset($output['securityDefinitions']['Locale'])) {
|
||||
$output['securityDefinitions']['Locale']['extensions'] = ['demo' => 'en'];
|
||||
}
|
||||
if ($extensions) {
|
||||
$platformList = $route->getLabel('sdk.platform', []);
|
||||
|
||||
if (isset($output['securityDefinitions']['Mode'])) {
|
||||
$output['securityDefinitions']['Mode']['extensions'] = ['demo' => ''];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($utopia->getRoutes() as $key => $method) {
|
||||
foreach ($method as $route) { /* @var $route \Utopia\Route */
|
||||
if (!$route->getLabel('docs', true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (empty($route->getLabel('sdk.namespace', null))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($platform !== APP_PLATFORM_CONSOLE && !\in_array($platforms[$platform], $route->getLabel('sdk.platform', []))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$url = \str_replace('/v1', '', $route->getURL());
|
||||
$scope = $route->getLabel('scope', '');
|
||||
$hide = $route->getLabel('sdk.hide', false);
|
||||
$consumes = ['application/json'];
|
||||
|
||||
if ($hide) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$desc = (!empty($route->getLabel('sdk.description', ''))) ? \realpath('../'.$route->getLabel('sdk.description', '')) : null;
|
||||
|
||||
$temp = [
|
||||
'summary' => $route->getDesc(),
|
||||
'operationId' => $route->getLabel('sdk.method', \uniqid()),
|
||||
'consumes' => [],
|
||||
'tags' => [$route->getLabel('sdk.namespace', 'default')],
|
||||
'description' => ($desc) ? \file_get_contents($desc) : '',
|
||||
|
||||
// 'responses' => [
|
||||
// 200 => [
|
||||
// 'description' => 'An paged array of pets',
|
||||
// 'schema' => [
|
||||
// '$ref' => '#/definitions/Pet',
|
||||
// ],
|
||||
// ],
|
||||
// ],
|
||||
$temp['extensions'] = [
|
||||
'weight' => $route->getOrder(),
|
||||
'cookies' => $route->getLabel('sdk.cookies', false),
|
||||
'type' => $route->getLabel('sdk.methodType', ''),
|
||||
'demo' => 'docs/examples/'.fromCamelCaseToDash($route->getLabel('sdk.namespace', 'default')).'/'.fromCamelCaseToDash($temp['operationId']).'.md',
|
||||
'edit' => 'https://github.com/appwrite/appwrite/edit/master' . $route->getLabel('sdk.description', ''),
|
||||
'rate-limit' => $route->getLabel('abuse-limit', 0),
|
||||
'rate-time' => $route->getLabel('abuse-time', 3600),
|
||||
'rate-key' => $route->getLabel('abuse-key', 'url:{url},ip:{ip}'),
|
||||
'scope' => $route->getLabel('scope', ''),
|
||||
'platforms' => $platformList,
|
||||
];
|
||||
}
|
||||
|
||||
if ($extensions) {
|
||||
$platformList = $route->getLabel('sdk.platform', []);
|
||||
if ((!empty($scope))) { // && 'public' != $scope
|
||||
$temp['security'][] = $route->getLabel('sdk.security', $security[$platform]);
|
||||
}
|
||||
|
||||
$temp['extensions'] = [
|
||||
'weight' => $route->getOrder(),
|
||||
'cookies' => $route->getLabel('sdk.cookies', false),
|
||||
'type' => $route->getLabel('sdk.methodType', ''),
|
||||
'demo' => 'docs/examples/'.fromCamelCaseToDash($route->getLabel('sdk.namespace', 'default')).'/'.fromCamelCaseToDash($temp['operationId']).'.md',
|
||||
'edit' => 'https://github.com/appwrite/appwrite/edit/master' . $route->getLabel('sdk.description', ''),
|
||||
'rate-limit' => $route->getLabel('abuse-limit', 0),
|
||||
'rate-time' => $route->getLabel('abuse-time', 3600),
|
||||
'rate-key' => $route->getLabel('abuse-key', 'url:{url},ip:{ip}'),
|
||||
'scope' => $route->getLabel('scope', ''),
|
||||
'platforms' => $platformList,
|
||||
];
|
||||
}
|
||||
|
||||
if ((!empty($scope))) { // && 'public' != $scope
|
||||
$temp['security'][] = $route->getLabel('sdk.security', $security[$platform]);
|
||||
}
|
||||
|
||||
$requestBody = [
|
||||
'content' => [
|
||||
'application/x-www-form-urlencoded' => [
|
||||
'schema' => [
|
||||
'type' => 'object',
|
||||
'properties' => [],
|
||||
],
|
||||
'required' => [],
|
||||
$requestBody = [
|
||||
'content' => [
|
||||
'application/x-www-form-urlencoded' => [
|
||||
'schema' => [
|
||||
'type' => 'object',
|
||||
'properties' => [],
|
||||
],
|
||||
'required' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($route->getParams() as $name => $param) {
|
||||
$validator = (\is_callable($param['validator'])) ? call_user_func_array($param['validator'], $utopia->getResources($param['resources'])) : $param['validator']; /* @var $validator \Utopia\Validator */
|
||||
|
||||
$node = [
|
||||
'name' => $name,
|
||||
'description' => $param['description'],
|
||||
'required' => !$param['optional'],
|
||||
];
|
||||
|
||||
foreach ($route->getParams() as $name => $param) {
|
||||
$validator = (\is_callable($param['validator'])) ? $param['validator']() : $param['validator']; /* @var $validator \Utopia\Validator */
|
||||
|
||||
$node = [
|
||||
'name' => $name,
|
||||
'description' => $param['description'],
|
||||
'required' => !$param['optional'],
|
||||
];
|
||||
|
||||
switch ((!empty($validator)) ? \get_class($validator) : '') {
|
||||
case 'Utopia\Validator\Text':
|
||||
$node['type'] = 'string';
|
||||
$node['x-example'] = '['.\strtoupper(fromCamelCase($node['name'])).']';
|
||||
break;
|
||||
case 'Utopia\Validator\Boolean':
|
||||
$node['type'] = 'boolean';
|
||||
$node['x-example'] = false;
|
||||
break;
|
||||
case 'Appwrite\Database\Validator\UID':
|
||||
$node['type'] = 'string';
|
||||
$node['x-example'] = '['.\strtoupper(fromCamelCase($node['name'])).']';
|
||||
break;
|
||||
case 'Utopia\Validator\Email':
|
||||
$node['type'] = 'string';
|
||||
$node['format'] = 'email';
|
||||
$node['x-example'] = 'email@example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\URL':
|
||||
$node['type'] = 'string';
|
||||
$node['format'] = 'url';
|
||||
$node['x-example'] = 'https://example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\JSON':
|
||||
case 'Utopia\Validator\Mock':
|
||||
case 'Utopia\Validator\Assoc':
|
||||
$node['type'] = 'object';
|
||||
$node['type'] = 'object';
|
||||
$node['x-example'] = '{}';
|
||||
//$node['format'] = 'json';
|
||||
break;
|
||||
case 'Appwrite\Storage\Validator\File':
|
||||
$consumes = ['multipart/form-data'];
|
||||
$node['type'] = 'file';
|
||||
break;
|
||||
case 'Utopia\Validator\ArrayList':
|
||||
$node['type'] = 'array';
|
||||
$node['collectionFormat'] = 'multi';
|
||||
$node['items'] = [
|
||||
'type' => 'string',
|
||||
];
|
||||
break;
|
||||
case 'Appwrite\Auth\Validator\Password':
|
||||
$node['type'] = 'string';
|
||||
$node['format'] = 'format';
|
||||
$node['x-example'] = 'password';
|
||||
break;
|
||||
case 'Utopia\Validator\Range': /* @var $validator \Utopia\Validator\Range */
|
||||
$node['type'] = 'integer';
|
||||
$node['format'] = 'int32';
|
||||
$node['x-example'] = $validator->getMin();
|
||||
break;
|
||||
case 'Utopia\Validator\Numeric':
|
||||
$node['type'] = 'integer';
|
||||
$node['format'] = 'int32';
|
||||
break;
|
||||
case 'Utopia\Validator\Length':
|
||||
$node['type'] = 'string';
|
||||
break;
|
||||
case 'Utopia\Validator\Host':
|
||||
$node['type'] = 'string';
|
||||
$node['format'] = 'url';
|
||||
$node['x-example'] = 'https://example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\WhiteList': /* @var $validator \Utopia\Validator\WhiteList */
|
||||
$node['type'] = 'string';
|
||||
$node['x-example'] = $validator->getList()[0];
|
||||
break;
|
||||
default:
|
||||
$node['type'] = 'string';
|
||||
break;
|
||||
}
|
||||
|
||||
if ($param['optional'] && !\is_null($param['default'])) { // Param has default value
|
||||
$node['default'] = $param['default'];
|
||||
}
|
||||
|
||||
if (false !== \strpos($url, ':'.$name)) { // Param is in URL path
|
||||
$node['in'] = 'path';
|
||||
$temp['parameters'][] = $node;
|
||||
} elseif ($key == 'GET') { // Param is in query
|
||||
$node['in'] = 'query';
|
||||
$temp['parameters'][] = $node;
|
||||
} else { // Param is in payload
|
||||
$node['in'] = 'formData';
|
||||
$temp['parameters'][] = $node;
|
||||
$requestBody['content']['application/x-www-form-urlencoded']['schema']['properties'][] = $node;
|
||||
|
||||
if (!$param['optional']) {
|
||||
$requestBody['content']['application/x-www-form-urlencoded']['required'][] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
$url = \str_replace(':'.$name, '{'.$name.'}', $url);
|
||||
switch ((!empty($validator)) ? \get_class($validator) : '') {
|
||||
case 'Utopia\Validator\Text':
|
||||
$node['type'] = 'string';
|
||||
$node['x-example'] = '['.\strtoupper(fromCamelCase($node['name'])).']';
|
||||
break;
|
||||
case 'Utopia\Validator\Boolean':
|
||||
$node['type'] = 'boolean';
|
||||
$node['x-example'] = false;
|
||||
break;
|
||||
case 'Appwrite\Database\Validator\UID':
|
||||
$node['type'] = 'string';
|
||||
$node['x-example'] = '['.\strtoupper(fromCamelCase($node['name'])).']';
|
||||
break;
|
||||
case 'Utopia\Validator\Email':
|
||||
$node['type'] = 'string';
|
||||
$node['format'] = 'email';
|
||||
$node['x-example'] = 'email@example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\URL':
|
||||
$node['type'] = 'string';
|
||||
$node['format'] = 'url';
|
||||
$node['x-example'] = 'https://example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\JSON':
|
||||
case 'Utopia\Validator\Mock':
|
||||
case 'Utopia\Validator\Assoc':
|
||||
$node['type'] = 'object';
|
||||
$node['type'] = 'object';
|
||||
$node['x-example'] = '{}';
|
||||
//$node['format'] = 'json';
|
||||
break;
|
||||
case 'Appwrite\Storage\Validator\File':
|
||||
$consumes = ['multipart/form-data'];
|
||||
$node['type'] = 'file';
|
||||
break;
|
||||
case 'Utopia\Validator\ArrayList':
|
||||
$node['type'] = 'array';
|
||||
$node['collectionFormat'] = 'multi';
|
||||
$node['items'] = [
|
||||
'type' => 'string',
|
||||
];
|
||||
break;
|
||||
case 'Appwrite\Auth\Validator\Password':
|
||||
$node['type'] = 'string';
|
||||
$node['format'] = 'format';
|
||||
$node['x-example'] = 'password';
|
||||
break;
|
||||
case 'Utopia\Validator\Range': /* @var $validator \Utopia\Validator\Range */
|
||||
$node['type'] = 'integer';
|
||||
$node['format'] = 'int32';
|
||||
$node['x-example'] = $validator->getMin();
|
||||
break;
|
||||
case 'Utopia\Validator\Numeric':
|
||||
$node['type'] = 'integer';
|
||||
$node['format'] = 'int32';
|
||||
break;
|
||||
case 'Utopia\Validator\Length':
|
||||
$node['type'] = 'string';
|
||||
break;
|
||||
case 'Utopia\Validator\Host':
|
||||
$node['type'] = 'string';
|
||||
$node['format'] = 'url';
|
||||
$node['x-example'] = 'https://example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\WhiteList': /* @var $validator \Utopia\Validator\WhiteList */
|
||||
$node['type'] = 'string';
|
||||
$node['x-example'] = $validator->getList()[0];
|
||||
break;
|
||||
default:
|
||||
$node['type'] = 'string';
|
||||
break;
|
||||
}
|
||||
|
||||
$temp['consumes'] = $consumes;
|
||||
if ($param['optional'] && !\is_null($param['default'])) { // Param has default value
|
||||
$node['default'] = $param['default'];
|
||||
}
|
||||
|
||||
$output['paths'][$url][\strtolower($route->getMethod())] = $temp;
|
||||
if (false !== \strpos($url, ':'.$name)) { // Param is in URL path
|
||||
$node['in'] = 'path';
|
||||
$temp['parameters'][] = $node;
|
||||
} elseif ($key == 'GET') { // Param is in query
|
||||
$node['in'] = 'query';
|
||||
$temp['parameters'][] = $node;
|
||||
} else { // Param is in payload
|
||||
$node['in'] = 'formData';
|
||||
$temp['parameters'][] = $node;
|
||||
$requestBody['content']['application/x-www-form-urlencoded']['schema']['properties'][] = $node;
|
||||
|
||||
if (!$param['optional']) {
|
||||
$requestBody['content']['application/x-www-form-urlencoded']['required'][] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
$url = \str_replace(':'.$name, '{'.$name.'}', $url);
|
||||
}
|
||||
|
||||
$temp['consumes'] = $consumes;
|
||||
|
||||
$output['paths'][$url][\strtolower($route->getMethod())] = $temp;
|
||||
}
|
||||
|
||||
/*foreach ($consoleDB->getMocks() as $mock) {
|
||||
var_dump($mock['name']);
|
||||
}*/
|
||||
|
||||
\ksort($output['paths']);
|
||||
|
||||
$response
|
||||
->json($output);
|
||||
}
|
||||
);
|
||||
|
||||
/*foreach ($consoleDB->getMocks() as $mock) {
|
||||
var_dump($mock['name']);
|
||||
}*/
|
||||
|
||||
\ksort($output['paths']);
|
||||
|
||||
$response
|
||||
->json($output);
|
||||
}, ['utopia', 'response']);
|
|
@ -222,7 +222,7 @@ Locale::setLanguage('zh-tw', include __DIR__.'/config/locale/translations/zh-tw.
|
|||
'http' => [
|
||||
'method' => 'GET',
|
||||
'user_agent' => \sprintf(APP_USERAGENT,
|
||||
Config::getParam('version'),
|
||||
App::getEnv('_APP_VERSION', 'UNKNOWN'),
|
||||
App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY)),
|
||||
'timeout' => 2,
|
||||
],
|
||||
|
|
|
@ -96,7 +96,7 @@ class TasksV1
|
|||
\curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
\curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
\curl_setopt($ch, CURLOPT_USERAGENT, \sprintf(APP_USERAGENT,
|
||||
Config::getParam('version'),
|
||||
App::getEnv('_APP_VERSION', 'UNKNOWN'),
|
||||
App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY)
|
||||
));
|
||||
\curl_setopt(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\App;
|
||||
|
||||
require_once __DIR__.'/../init.php';
|
||||
|
||||
|
@ -31,7 +31,7 @@ class UsageV1
|
|||
|
||||
$statsd = $register->get('statsd', true);
|
||||
|
||||
$tags = ",project={$projectId},version=".Config::getParam('version').'';
|
||||
$tags = ",project={$projectId},version=".App::getEnv('_APP_VERSION', 'UNKNOWN').'';
|
||||
|
||||
// the global namespace is prepended to every key (optional)
|
||||
$statsd->setNamespace('appwrite.usage');
|
||||
|
|
|
@ -6,7 +6,6 @@ require_once __DIR__.'/../init.php';
|
|||
|
||||
echo APP_NAME.' webhooks worker v1 has started';
|
||||
|
||||
use Utopia\Config\Config;
|
||||
use Appwrite\Database\Database;
|
||||
use Appwrite\Database\Validator\Authorization;
|
||||
use Utopia\App;
|
||||
|
@ -61,7 +60,7 @@ class WebhooksV1
|
|||
\curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
\curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
\curl_setopt($ch, CURLOPT_USERAGENT, \sprintf(APP_USERAGENT,
|
||||
Config::getParam('version'),
|
||||
App::getEnv('_APP_VERSION', 'UNKNOWN'),
|
||||
App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY)
|
||||
));
|
||||
\curl_setopt(
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
"appwrite/php-clamav": "1.0.*",
|
||||
|
||||
"utopia-php/framework": "0.7.1",
|
||||
"utopia-php/framework": "0.7.2",
|
||||
"utopia-php/abuse": "0.2.*",
|
||||
"utopia-php/audit": "0.3.*",
|
||||
"utopia-php/cache": "0.2.*",
|
||||
|
|
22
composer.lock
generated
22
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "b8ee06f97c395bc83a05f92939679724",
|
||||
"content-hash": "2693761ec4a5bb1305ac226bffd1555d",
|
||||
"packages": [
|
||||
{
|
||||
"name": "appwrite/php-clamav",
|
||||
|
@ -1596,16 +1596,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/framework",
|
||||
"version": "0.7.1",
|
||||
"version": "0.7.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/framework.git",
|
||||
"reference": "3810789c1caf16a9ad7811fd38067a35249e75f8"
|
||||
"reference": "e592b7bdea5eeb48a3bf7ae18bc6d3e622e54cf3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/framework/zipball/3810789c1caf16a9ad7811fd38067a35249e75f8",
|
||||
"reference": "3810789c1caf16a9ad7811fd38067a35249e75f8",
|
||||
"url": "https://api.github.com/repos/utopia-php/framework/zipball/e592b7bdea5eeb48a3bf7ae18bc6d3e622e54cf3",
|
||||
"reference": "e592b7bdea5eeb48a3bf7ae18bc6d3e622e54cf3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1636,20 +1636,20 @@
|
|||
"php",
|
||||
"upf"
|
||||
],
|
||||
"time": "2020-06-29T16:02:35+00:00"
|
||||
"time": "2020-06-30T09:43:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/locale",
|
||||
"version": "0.3.0",
|
||||
"version": "0.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/locale.git",
|
||||
"reference": "32c32a3bf5c295f3de93569cead7f412fa29ad13"
|
||||
"reference": "89c488fbff65fc87c048786c3d76b6003fbaa833"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/locale/zipball/32c32a3bf5c295f3de93569cead7f412fa29ad13",
|
||||
"reference": "32c32a3bf5c295f3de93569cead7f412fa29ad13",
|
||||
"url": "https://api.github.com/repos/utopia-php/locale/zipball/89c488fbff65fc87c048786c3d76b6003fbaa833",
|
||||
"reference": "89c488fbff65fc87c048786c3d76b6003fbaa833",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1682,7 +1682,7 @@
|
|||
"upf",
|
||||
"utopia"
|
||||
],
|
||||
"time": "2020-06-29T12:39:35+00:00"
|
||||
"time": "2020-06-29T20:53:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/registry",
|
||||
|
|
Loading…
Reference in a new issue