1
0
Fork 0
mirror of synced 2024-05-20 20:52:36 +12:00

refactor: code refactoring using php-cs-fixer

This commit is contained in:
Christy Jacob 2019-09-30 11:43:40 +05:30
parent 04ea008fc8
commit 4158c3ea21
43 changed files with 1053 additions and 485 deletions

1
.php_cs.cache Normal file

File diff suppressed because one or more lines are too long

View file

@ -31,26 +31,25 @@ $webhook = new Event('v1-webhooks', 'WebhooksV1');
$audit = new Event('v1-audits', 'AuditsV1');
$usage = new Event('v1-usage', 'UsageV1');
$clientsConsole = array_map(function($node) {
$clientsConsole = array_map(function ($node) {
return $node['url'];
}, array_filter($console->getAttribute('platforms', []), function($node) {
if(isset($node['type']) && $node['type'] === 'web' && isset($node['url']) && !empty($node['url'])) {
}, array_filter($console->getAttribute('platforms', []), function ($node) {
if (isset($node['type']) && $node['type'] === 'web' && isset($node['url']) && !empty($node['url'])) {
return true;
}
return false;
}));
$clients = array_merge($clientsConsole, array_map(function($node) {
$clients = array_merge($clientsConsole, array_map(function ($node) {
return $node['url'];
}, array_filter($project->getAttribute('platforms', []), function($node) {
if(isset($node['type']) && $node['type'] === 'web' && isset($node['url']) && !empty($node['url'])) {
}, array_filter($project->getAttribute('platforms', []), function ($node) {
if (isset($node['type']) && $node['type'] === 'web' && isset($node['url']) && !empty($node['url'])) {
return true;
}
return false;
})));
$utopia->init(function() use ($utopia, $request, $response, $register, &$user, $project, $roles, $webhook, $audit, $usage, $domain, $clients) {
$utopia->init(function () use ($utopia, $request, $response, $register, &$user, $project, $roles, $webhook, $audit, $usage, $domain, $clients) {
$route = $utopia->match($request);
$referrer = $request->getServer('HTTP_REFERER', '');
@ -82,7 +81,7 @@ $utopia->init(function() use ($utopia, $request, $response, $register, &$user, $
*/
$hostValidator = new Host($clients);
if(!$hostValidator->isValid($request->getServer('HTTP_ORIGIN', $request->getServer('HTTP_REFERER', '')))
if (!$hostValidator->isValid($request->getServer('HTTP_ORIGIN', $request->getServer('HTTP_REFERER', '')))
&& in_array($request->getMethod(), [Request::METHOD_POST, Request::METHOD_PUT, Request::METHOD_PATCH, Request::METHOD_DELETE])
&& empty($request->getHeader('X-Appwrite-Key', ''))) {
throw new Exception('Access from this client host is forbidden. ' . $hostValidator->getDescription(), 403);
@ -96,7 +95,7 @@ $utopia->init(function() use ($utopia, $request, $response, $register, &$user, $
// Add user roles
$membership = $user->search('teamId', $project->getAttribute('teamId', null), $user->getAttribute('memberships', []));
if($membership) {
if ($membership) {
foreach ($membership->getAttribute('roles', []) as $memberRole) {
switch ($memberRole) {
case 'owner':
@ -122,7 +121,7 @@ $utopia->init(function() use ($utopia, $request, $response, $register, &$user, $
* Try app auth when we have project key and no user
* Mock user to app and grant API key scopes in addition to default app scopes
*/
if(null !== $key && $user->isEmpty()) {
if (null !== $key && $user->isEmpty()) {
$user = new Document([
'$uid' => 0,
'status' => Auth::USER_STATUS_ACTIVATED,
@ -141,7 +140,7 @@ $utopia->init(function() use ($utopia, $request, $response, $register, &$user, $
Authorization::setRole('role:' . $role);
array_map(function ($node) {
if(isset($node['teamId']) && isset($node['roles'])) {
if (isset($node['teamId']) && isset($node['roles'])) {
Authorization::setRole('team:' . $node['teamId']);
foreach ($node['roles'] as $nodeRole) { // Set all team roles
@ -150,15 +149,15 @@ $utopia->init(function() use ($utopia, $request, $response, $register, &$user, $
}
}, $user->getAttribute('memberships', []));
if(!in_array($scope, $scopes)) {
if (!in_array($scope, $scopes)) {
throw new Exception($user->getAttribute('email', 'Guest') . ' (role: ' . strtolower($roles[$role]['label']) . ') missing scope (' . $scope . ')', 401);
}
if(Auth::USER_STATUS_BLOCKED == $user->getAttribute('status')) { // Account has not been activated
if (Auth::USER_STATUS_BLOCKED == $user->getAttribute('status')) { // Account has not been activated
throw new Exception('Invalid credentials. User is blocked', 401); // User is in status blocked
}
if($user->getAttribute('reset')) {
if ($user->getAttribute('reset')) {
throw new Exception('Password reset is required', 412);
}
@ -193,7 +192,9 @@ $utopia->init(function() use ($utopia, $request, $response, $register, &$user, $
/**
* Abuse Check
*/
$timeLimit = new TimeLimit($route->getLabel('abuse-key', 'url:{url},ip:{ip}'), $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), function () use ($register) {return $register->get('db');});
$timeLimit = new TimeLimit($route->getLabel('abuse-key', 'url:{url},ip:{ip}'), $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), function () use ($register) {
return $register->get('db');
});
$timeLimit->setNamespace('app_' . $project->getUid());
$timeLimit
->setParam('{userId}', $user->getUid())
@ -204,13 +205,13 @@ $utopia->init(function() use ($utopia, $request, $response, $register, &$user, $
//TODO make sure we get array here
foreach($request->getParams() as $key => $value) { // Set request params as potential abuse keys
foreach ($request->getParams() as $key => $value) { // Set request params as potential abuse keys
$timeLimit->setParam('{param-' . $key . '}', (is_array($value)) ? json_encode($value) : $value);
}
$abuse = new Abuse($timeLimit);
if($timeLimit->limit()) {
if ($timeLimit->limit()) {
$response
->addHeader('X-RateLimit-Limit', $timeLimit->limit())
->addHeader('X-RateLimit-Remaining', $timeLimit->remaining())
@ -218,7 +219,7 @@ $utopia->init(function() use ($utopia, $request, $response, $register, &$user, $
;
}
if($abuse->check() && $request->getServer('_APP_OPTIONS_ABUSE', 'enabled') !== 'disabled') {
if ($abuse->check() && $request->getServer('_APP_OPTIONS_ABUSE', 'enabled') !== 'disabled') {
throw new Exception('Too many requests', 429);
}
});
@ -228,11 +229,11 @@ $utopia->shutdown(function () use ($response, $request, $webhook, $audit, $usage
/**
* Trigger Events for background jobs
*/
if(!empty($webhook->getParam('event'))) {
if (!empty($webhook->getParam('event'))) {
$webhook->trigger();
}
if(!empty($audit->getParam('event'))) {
if (!empty($audit->getParam('event'))) {
$audit->trigger();
}
@ -243,7 +244,7 @@ $utopia->shutdown(function () use ($response, $request, $webhook, $audit, $usage
;
});
$utopia->options(function() use ($request, $response, $domain, $project) {
$utopia->options(function () use ($request, $response, $domain, $project) {
$origin = $request->getServer('HTTP_ORIGIN');
$response
@ -255,8 +256,8 @@ $utopia->options(function() use ($request, $response, $domain, $project) {
;
});
$utopia->error(function($error /* @var $error Exception */) use ($request, $response, $utopia, $project, $env, $version, $sentry, $user) {
switch($error->getCode()) {
$utopia->error(function ($error /* @var $error Exception */) use ($request, $response, $utopia, $project, $env, $version, $sentry, $user) {
switch ($error->getCode()) {
case 400: // Error allowed publicly
case 401: // Error allowed publicly
case 402: // Error allowed publicly
@ -297,7 +298,7 @@ $utopia->error(function($error /* @var $error Exception */) use ($request, $resp
$route = $utopia->match($request);
$template = ($route) ? $route->getLabel('error', null): null;
if($template) {
if ($template) {
$layout = new View(__DIR__ . '/views/layouts/default.phtml');
$comp = new View($template);
@ -329,8 +330,7 @@ $utopia->get('/manifest.json')
->label('scope', 'public')
->label('docs', false)
->action(
function() use ($response) {
function () use ($response) {
$response->json([
'name' => APP_NAME,
'short_name' => APP_NAME,
@ -356,8 +356,7 @@ $utopia->get('/robots.txt')
->label('scope', 'public')
->label('docs', false)
->action(
function() use ($response) {
function () use ($response) {
$response->text("# robotstxt.org/
User-agent: *
@ -370,8 +369,7 @@ $utopia->get('/humans.txt')
->label('scope', 'public')
->label('docs', false)
->action(
function() use ($response) {
function () use ($response) {
$response->text("# humanstxt.org/
# The humans responsible & technology colophon
@ -387,7 +385,7 @@ $utopia->get('/v1/info') // This is only visible to gods
->label('scope', 'god')
->label('docs', false)
->action(
function() use ($response, $user, $project, $version, $env) { //TODO CONSIDER BLOCKING THIS ACTION TO ROLE GOD
function () use ($response, $user, $project, $version, $env) { //TODO CONSIDER BLOCKING THIS ACTION TO ROLE GOD
$response->json([
'name' => 'API',
'version' => $version,
@ -410,7 +408,7 @@ $utopia->get('/v1/xss')
->label('scope', 'public')
->label('docs', false)
->action(
function() {
function () {
throw new Exception('XSS detected and reported by a browser client', 500);
}
);
@ -419,7 +417,7 @@ $utopia->get('/v1/proxy')
->label('scope', 'public')
->label('docs', false)
->action(
function() use ($response, $console, $clients) {
function () use ($response, $console, $clients) {
$view = new View(__DIR__ . '/views/proxy.phtml');
$view
->setParam('routes', '')
@ -436,12 +434,16 @@ $utopia->get('/v1/proxy')
$utopia->get('/v1/open-api-2.json')
->label('scope', 'public')
->label('docs', false)
->param('platform', 'client' , function () {return new WhiteList(['client', 'server']);}, 'Choose target platform.', true)
->param('extensions', 0 , function () {return new Range(0, 1);}, 'Show extra data.', true)
->param('platform', 'client', function () {
return new WhiteList(['client', 'server']);
}, 'Choose target platform.', true)
->param('extensions', 0, function () {
return new Range(0, 1);
}, 'Show extra data.', true)
->action(
function($platform, $extensions) use ($response, $request, $utopia, $domain, $version, $services) {
function fromCamelCase($input) {
function ($platform, $extensions) use ($response, $request, $utopia, $domain, $version, $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) {
@ -450,12 +452,13 @@ $utopia->get('/v1/open-api-2.json')
return implode('_', $ret);
}
function fromCamelCaseToDash($input) {
function fromCamelCaseToDash($input)
{
return str_replace([' ', '_'], '-', strtolower(preg_replace('/([a-zA-Z])(?=[A-Z])/', '$1-', $input)));
}
foreach ($services as $service) { /** @noinspection PhpIncludeInspection */
if(!$service['sdk']) {
if (!$service['sdk']) {
continue;
}
@ -538,29 +541,29 @@ $utopia->get('/v1/open-api-2.json')
],
],
'Pets' =>
array (
array(
'type' => 'array',
'items' =>
array (
array(
'$ref' => '#/definitions/Pet',
),
),
'Error' =>
array (
array(
'required' =>
array (
array(
0 => 'code',
1 => 'message',
),
'properties' =>
array (
array(
'code' =>
array (
array(
'type' => 'integer',
'format' => 'int32',
),
'message' =>
array (
array(
'type' => 'string',
),
),
@ -574,11 +577,11 @@ $utopia->get('/v1/open-api-2.json')
foreach ($utopia->getRoutes() as $key => $method) {
foreach ($method as $route) { /* @var $route \Utopia\Route */
if(!$route->getLabel('docs', true)) {
if (!$route->getLabel('docs', true)) {
continue;
}
if(empty($route->getLabel('sdk.namespace', null))) {
if (empty($route->getLabel('sdk.namespace', null))) {
continue;
}
@ -587,7 +590,7 @@ $utopia->get('/v1/open-api-2.json')
$hide = $route->getLabel('sdk.hide', false);
$consumes = [];
if($hide) {
if ($hide) {
continue;
}
@ -607,7 +610,7 @@ $utopia->get('/v1/open-api-2.json')
],
];
if($extensions) {
if ($extensions) {
$temp['extensions'] = [
'weight' => $route->getOrder(),
'cookies' => $route->getLabel('sdk.cookies', false),
@ -616,7 +619,7 @@ $utopia->get('/v1/open-api-2.json')
];
}
if((!empty($scope) && 'public' != $scope)) {
if ((!empty($scope) && 'public' != $scope)) {
$temp['security'][] = $route->getLabel('sdk.security', $security[$platform]);
}
@ -709,24 +712,22 @@ $utopia->get('/v1/open-api-2.json')
break;
}
if($param['optional'] && !is_null($param['default'])) { // Param has default value
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
} elseif ($key == 'GET') { // Param is in query
$node['in'] = 'query';
$temp['parameters'][] = $node;
}
else { // Param is in payload
} else { // Param is in payload
$node['in'] = 'formData';
$temp['parameters'][] = $node;
$requestBody['content']['application/x-www-form-urlencoded']['schema']['properties'][] = $node;
if(!$param['optional']) {
if (!$param['optional']) {
$requestBody['content']['application/x-www-form-urlencoded']['required'][] = $name;
}
}
@ -752,11 +753,10 @@ $utopia->get('/v1/open-api-2.json')
$name = APP_NAME;
if(array_key_exists($service, $services)) { /** @noinspection PhpIncludeInspection */
if (array_key_exists($service, $services)) { /** @noinspection PhpIncludeInspection */
include_once $services[$service]['controller'];
$name = APP_NAME . ' ' . ucfirst($services[$service]['name']);
}
else {
} else {
/** @noinspection PhpIncludeInspection */
include_once $services['/']['controller'];
}
@ -769,4 +769,4 @@ if (extension_loaded('newrelic')) {
newrelic_name_transaction($request->getServer('REQUEST_METHOD', 'UNKNOWN') . ': ' . $url);
}
$utopia->run($request, $response);
$utopia->run($request, $response);

View file

@ -194,4 +194,4 @@ return [
'ZA' => 'Sudáfrica',
'ZM' => 'Zambia',
'ZW' => 'Zimbabue',
];
];

View file

@ -39,7 +39,8 @@ $utopia->get('/v1/account')
'registration',
'confirm',
'name',
], $oauthKeys
],
$oauthKeys
)), ['roles' => Authorization::getRoles()]));
}
);
@ -133,7 +134,6 @@ $utopia->get('/v1/account/security')
->label('sdk.description', 'Get currently logged in user list of latest security activity logs. Each log returns user IP address, location and date and time of log.')
->action(
function () use ($response, $register, $project, $user) {
$ad = new \Audit\Adapter\MySQL($register->get('db'));
$ad->setNamespace('app_'.$project->getUid());
$au = new \Audit\Audit($ad, $user->getUid(), $user->getAttribute('type'), '', '', '');
@ -202,7 +202,9 @@ $utopia->patch('/v1/account/name')
->label('sdk.namespace', 'account')
->label('sdk.method', 'updateName')
->label('sdk.description', 'Update currently logged in user account name.')
->param('name', '', function () {return new Text(100);}, 'User name')
->param('name', '', function () {
return new Text(100);
}, 'User name')
->action(
function ($name) use ($response, $user, $projectDB, $audit) {
$user = $projectDB->updateDocument(array_merge($user->getArrayCopy(), [
@ -226,8 +228,12 @@ $utopia->patch('/v1/account/password')
->label('sdk.namespace', 'account')
->label('sdk.method', 'updatePassword')
->label('sdk.description', 'Update currently logged in user password. For validation, user is required to pass the password twice.')
->param('password', '', function () {return new Password();}, 'New password')
->param('old-password', '', function () {return new Password();}, 'Old password')
->param('password', '', function () {
return new Password();
}, 'New password')
->param('old-password', '', function () {
return new Password();
}, 'Old password')
->action(
function ($password, $oldPassword) use ($response, $user, $projectDB, $audit) {
if (!Auth::passwordVerify($oldPassword, $user->getAttribute('password'))) { // Double check user password
@ -255,8 +261,12 @@ $utopia->patch('/v1/account/email')
->label('sdk.namespace', 'account')
->label('sdk.method', 'updateEmail')
->label('sdk.description', 'Update currently logged in user account email address. After changing user address, user confirmation status is being reset and a new confirmation mail is sent. For security measures, user password is required to complete this request.')
->param('email', '', function () {return new Email();}, 'Email Address')
->param('password', '', function () {return new Password();}, 'User Password')
->param('email', '', function () {
return new Email();
}, 'Email Address')
->param('password', '', function () {
return new Password();
}, 'User Password')
->action(
function ($email, $password) use ($response, $user, $projectDB, $audit) {
if (!Auth::passwordVerify($password, $user->getAttribute('password'))) { // Double check user password
@ -298,7 +308,9 @@ $utopia->patch('/v1/account/prefs')
->label('scope', 'account')
->label('sdk.namespace', 'account')
->label('sdk.method', 'updatePrefs')
->param('prefs', '', function () {return new \Utopia\Validator\Mock();}, 'Prefs key-value JSON object string.')
->param('prefs', '', function () {
return new \Utopia\Validator\Mock();
}, 'Prefs key-value JSON object string.')
->label('sdk.description', 'Update currently logged in user account preferences. You can pass only the specific settings you wish to update.')
->action(
function ($prefs) use ($response, $user, $projectDB, $audit) {

View file

@ -28,28 +28,40 @@ $utopia->post('/v1/auth/register')
->label('sdk.description', "Use this endpoint to allow a new user to register an account in your project. Use the success and failure URL's to redirect users back to your application after signup completes.\n\nIf registration completes successfully user will be sent with a confirmation email in order to confirm he is the owner of the account email address. Use the confirmation parameter to redirect the user from the confirmation email back to your app. When the user is redirected, use the /auth/confirm endpoint to complete the account confirmation.\n\nPlease notice that in order to avoid a [Redirect Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URL's are the once from domains you have set when added your platforms in the console interface.\n\nWhen accessing this route using Javascript from the browser, success and failure parameter URLs are required. Appwrite server will respond with a 301 redirect status code and will set the user session cookie. This behavior is enforced because modern browsers are limiting 3rd party cookies in XHR of fetch requests to protect user privacy.")
->label('sdk.cookies', true)
->label('abuse-limit', 10)
->param('email', '', function () {return new Email();}, 'Account email')
->param('password', '', function () {return new Password();}, 'User password')
->param('confirm', '', function () use ($clients) {return new Host($clients);}, 'Confirmation URL to redirect user after confirm token has been sent to user email') // TODO add our own built-in confirm page
->param('success', null, function () use ($clients) {return new Host($clients);}, 'Redirect when registration succeed', true)
->param('failure', null, function () use ($clients) {return new Host($clients);}, 'Redirect when registration failed', true)
->param('name', '', function () {return new Text(100);}, 'User name', true)
->param('email', '', function () {
return new Email();
}, 'Account email')
->param('password', '', function () {
return new Password();
}, 'User password')
->param('confirm', '', function () use ($clients) {
return new Host($clients);
}, 'Confirmation URL to redirect user after confirm token has been sent to user email') // TODO add our own built-in confirm page
->param('success', null, function () use ($clients) {
return new Host($clients);
}, 'Redirect when registration succeed', true)
->param('failure', null, function () use ($clients) {
return new Host($clients);
}, 'Redirect when registration failed', true)
->param('name', '', function () {
return new Text(100);
}, 'User name', true)
->action(
function ($email, $password, $confirm, $success, $failure, $name) use ($request, $response, $register, $audit, $projectDB, $project, $webhook) {
if('console' === $project->getUid()) {
if ('console' === $project->getUid()) {
$whitlistEmails = $project->getAttribute('authWhitelistEmails');
$whitlistIPs = $project->getAttribute('authWhitelistIPs');
$whitlistDomains = $project->getAttribute('authWhitelistDomains');
if(!empty($whitlistEmails) && !in_array($email, $whitlistEmails)) {
if (!empty($whitlistEmails) && !in_array($email, $whitlistEmails)) {
throw new Exception('Console registration is restricted to specific emails. Contact your administrator for more information.', 401);
}
if(!empty($whitlistIPs) && !in_array($request->getIP(), $whitlistIPs)) {
if (!empty($whitlistIPs) && !in_array($request->getIP(), $whitlistIPs)) {
throw new Exception('Console registration is restricted to specific IPs. Contact your administrator for more information.', 401);
}
if(!empty($whitlistDomains) && !in_array(substr(strrchr($email, "@"), 1), $whitlistDomains)) {
if (!empty($whitlistDomains) && !in_array(substr(strrchr($email, "@"), 1), $whitlistDomains)) {
throw new Exception('Console registration is restricted to specific domains. Contact your administrator for more information.', 401);
}
}
@ -194,8 +206,12 @@ $utopia->post('/v1/auth/register/confirm')
->label('sdk.description', 'Use this endpoint to complete the confirmation of the user account email address. Both the **userId** and **token** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the /auth/register endpoint.')
->label('abuse-limit', 10)
->label('abuse-key', 'url:{url},userId:{param-userId}')
->param('userId', '', function () {return new UID();}, 'User unique ID')
->param('token', '', function () {return new Text(256);}, 'Confirmation secret token')
->param('userId', '', function () {
return new UID();
}, 'User unique ID')
->param('token', '', function () {
return new Text(256);
}, 'Confirmation secret token')
->action(
function ($userId, $token) use ($response, $request, $projectDB, $audit) {
$profile = $projectDB->getCollection([ // Get user by email address
@ -244,7 +260,9 @@ $utopia->post('/v1/auth/register/confirm/resend')
->label('sdk.description', "This endpoint allows the user to request your app to resend him his email confirmation message. The redirect arguments acts the same way as in /auth/register endpoint.\n\nPlease notice that in order to avoid a [Redirect Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URL's are the once from domains you have set when added your platforms in the console interface.")
->label('abuse-limit', 10)
->label('abuse-key', 'url:{url},userId:{param-userId}')
->param('confirm', '', function () use ($clients) {return new Host($clients);}, 'Confirmation URL to redirect user to your app after confirm token has been sent to user email.')
->param('confirm', '', function () use ($clients) {
return new Host($clients);
}, 'Confirmation URL to redirect user to your app after confirm token has been sent to user email.')
->action(
function ($confirm) use ($response, $request, $projectDB, $user, $register, $project) {
if ($user->getAttribute('confirm', false)) {
@ -309,10 +327,18 @@ $utopia->post('/v1/auth/login')
->label('sdk.cookies', true)
->label('abuse-limit', 10)
->label('abuse-key', 'url:{url},email:{param-email}')
->param('email', '', function () {return new Email();}, 'User account email address')
->param('password', '', function () {return new Password();}, 'User account password')
->param('success', null, function () use ($clients) {return new Host($clients);}, 'URL to redirect back to your app after a successful login attempt.')
->param('failure', null, function () use ($clients) {return new Host($clients);}, 'URL to redirect back to your app after a failed login attempt.')
->param('email', '', function () {
return new Email();
}, 'User account email address')
->param('password', '', function () {
return new Password();
}, 'User account password')
->param('success', null, function () use ($clients) {
return new Host($clients);
}, 'URL to redirect back to your app after a successful login attempt.')
->param('failure', null, function () use ($clients) {
return new Host($clients);
}, 'URL to redirect back to your app after a failed login attempt.')
->action(
function ($email, $password, $success, $failure) use ($response, $request, $projectDB, $audit, $webhook) {
$profile = $projectDB->getCollection([ // Get user by email address
@ -423,7 +449,9 @@ $utopia->delete('/v1/auth/logout/:id')
->label('sdk.method', 'logoutBySession')
->label('sdk.description', 'Use this endpoint to log out the currently logged in user from all his account sessions across all his different devices. When using the option id argument, only the session unique ID provider will be deleted.')
->label('abuse-limit', 100)
->param('id', null, function () {return new UID();}, 'User specific session unique ID number. if 0 delete all sessions.')
->param('id', null, function () {
return new UID();
}, 'User specific session unique ID number. if 0 delete all sessions.')
->action(
function ($id) use ($response, $request, $user, $projectDB, $audit) {
$tokens = $user->getAttribute('tokens', []);
@ -457,8 +485,12 @@ $utopia->post('/v1/auth/recovery')
->label('sdk.description', 'Sends the user an email with a temporary secret token for password reset. When the user clicks the confirmation link he is redirected back to your app password reset redirect URL with a secret token and email address values attached to the URL query string. Use the query string params to submit a request to the /auth/password/reset endpoint to complete the process.')
->label('abuse-limit', 10)
->label('abuse-key', 'url:{url},email:{param-email}')
->param('email', '', function () {return new Email();}, 'User account email address.')
->param('reset', '', function () use ($clients) {return new Host($clients);}, 'Reset URL in your app to redirect the user after the reset token has been sent to the user email.')
->param('email', '', function () {
return new Email();
}, 'User account email address.')
->param('reset', '', function () use ($clients) {
return new Host($clients);
}, 'Reset URL in your app to redirect the user after the reset token has been sent to the user email.')
->action(
function ($email, $reset) use ($request, $response, $projectDB, $register, $audit, $project) {
$profile = $projectDB->getCollection([ // Get user by email address
@ -537,10 +569,18 @@ $utopia->put('/v1/auth/recovery/reset')
->label('sdk.description', "Use this endpoint to complete the user account password reset. Both the **userId** and **token** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the /auth/recovery endpoint.\n\nPlease notice that in order to avoid a [Redirect Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URL's are the once from domains you have set when added your platforms in the console interface.")
->label('abuse-limit', 10)
->label('abuse-key', 'url:{url},userId:{param-userId}')
->param('userId', '', function () {return new UID();}, 'User account email address.')
->param('token', '', function () {return new Text(256);}, 'Valid reset token.')
->param('password-a', '', function () {return new Password();}, 'New password.')
->param('password-b', '', function () {return new Password();}, 'New password again.')
->param('userId', '', function () {
return new UID();
}, 'User account email address.')
->param('token', '', function () {
return new Text(256);
}, 'Valid reset token.')
->param('password-a', '', function () {
return new Password();
}, 'New password.')
->param('password-b', '', function () {
return new Password();
}, 'New password again.')
->action(
function ($userId, $token, $passwordA, $passwordB) use ($response, $projectDB, $audit) {
if ($passwordA !== $passwordB) {
@ -600,9 +640,15 @@ $utopia->get('/v1/auth/oauth/:provider')
->label('sdk.location', true)
->label('abuse-limit', 50)
->label('abuse-key', 'ip:{ip}')
->param('provider', '', function () use ($providers) {return new WhiteList(array_keys($providers));}, 'OAuth Provider')
->param('success', '', function () use ($clients) {return new Host($clients);}, 'URL to redirect back to your app after a successful login attempt.', true)
->param('failure', '', function () use ($clients) {return new Host($clients);}, 'URL to redirect back to your app after a failed login attempt.', true)
->param('provider', '', function () use ($providers) {
return new WhiteList(array_keys($providers));
}, 'OAuth Provider')
->param('success', '', function () use ($clients) {
return new Host($clients);
}, 'URL to redirect back to your app after a successful login attempt.', true)
->param('failure', '', function () use ($clients) {
return new Host($clients);
}, 'URL to redirect back to your app after a failed login attempt.', true)
->action(
function ($provider, $success, $failure) use ($response, $request, $project) {
$callback = $request->getServer('REQUEST_SCHEME', 'https').'://'.$request->getServer('HTTP_HOST').'/v1/auth/oauth/callback/'.$provider.'/'.$project->getUid();
@ -641,10 +687,18 @@ $utopia->get('/v1/auth/oauth/callback/:provider/:projectId')
->label('abuse-limit', 50)
->label('abuse-key', 'ip:{ip}')
->label('docs', false)
->param('projectId', '', function () {return new Text(1024);}, 'Project unique ID')
->param('provider', '', function () use ($providers) {return new WhiteList(array_keys($providers));}, 'OAuth provider')
->param('code', '', function () {return new Text(1024);}, 'OAuth code')
->param('state', '', function () {return new Text(2048);}, 'Login state params', true)
->param('projectId', '', function () {
return new Text(1024);
}, 'Project unique ID')
->param('provider', '', function () use ($providers) {
return new WhiteList(array_keys($providers));
}, 'OAuth provider')
->param('code', '', function () {
return new Text(1024);
}, 'OAuth code')
->param('state', '', function () {
return new Text(2048);
}, 'Login state params', true)
->action(
function ($projectId, $provider, $code, $state) use ($response, $request, $domain) {
$response->redirect($request->getServer('REQUEST_SCHEME', 'https').'://'.$domain.'/v1/auth/oauth/'.$provider.'/redirect?'
@ -662,9 +716,15 @@ $utopia->get('/v1/auth/oauth/:provider/redirect')
->label('abuse-limit', 50)
->label('abuse-key', 'ip:{ip}')
->label('docs', false)
->param('provider', '', function () use ($providers) {return new WhiteList(array_keys($providers));}, 'OAuth provider')
->param('code', '', function () {return new Text(1024);}, 'OAuth code')
->param('state', '', function () {return new Text(2048);}, 'OAuth state params', true)
->param('provider', '', function () use ($providers) {
return new WhiteList(array_keys($providers));
}, 'OAuth provider')
->param('code', '', function () {
return new Text(1024);
}, 'OAuth code')
->param('state', '', function () {
return new Text(2048);
}, 'OAuth state params', true)
->action(
function ($provider, $code, $state) use ($response, $request, $user, $projectDB, $project, $audit) {
$callback = $request->getServer('REQUEST_SCHEME', 'https').'://'.$request->getServer('HTTP_HOST').'/v1/auth/oauth/callback/'.$provider.'/'.$project->getUid();

View file

@ -87,45 +87,81 @@ $avatarCallback = function ($type, $code, $width, $height, $quality) use ($types
$utopia->get('/v1/avatars/credit-cards/:code')
->desc('Get Credit Card Icon')
->param('code', '', function () use ($types) {return new WhiteList(array_keys($types['credit-cards'])); }, 'Credit Card Code. Possible values: '.implode(', ', array_keys($types['credit-cards'])).'.')
->param('width', 100, function () {return new Range(0, 2000);}, 'Image width. Pass an integer between 0 to 2000. Defaults to 100', true)
->param('height', 100, function () {return new Range(0, 2000);}, 'Image height. Pass an integer between 0 to 2000. Defaults to 100', true)
->param('quality', 100, function () {return new Range(0, 100);}, 'Image quality. Pass an integer between 0 to 100. Defaults to 100', true)
->param('code', '', function () use ($types) {
return new WhiteList(array_keys($types['credit-cards']));
}, 'Credit Card Code. Possible values: '.implode(', ', array_keys($types['credit-cards'])).'.')
->param('width', 100, function () {
return new Range(0, 2000);
}, 'Image width. Pass an integer between 0 to 2000. Defaults to 100', true)
->param('height', 100, function () {
return new Range(0, 2000);
}, 'Image height. Pass an integer between 0 to 2000. Defaults to 100', true)
->param('quality', 100, function () {
return new Range(0, 100);
}, 'Image quality. Pass an integer between 0 to 100. Defaults to 100', true)
->label('scope', 'avatars.read')
->label('sdk.namespace', 'avatars')
->label('sdk.method', 'getCreditCard')
->label('sdk.description', 'Need to display your users with your billing method or there payment methods? The credit card endpoint will return you the icon of the credit card provider you need. Use width, height and quality arguments to change the output settings.')
->action(function ($code, $width, $height, $quality) use ($avatarCallback) {return $avatarCallback('credit-cards', $code, $width, $height, $quality);});
->action(function ($code, $width, $height, $quality) use ($avatarCallback) {
return $avatarCallback('credit-cards', $code, $width, $height, $quality);
});
$utopia->get('/v1/avatars/browsers/:code')
->desc('Get Browser Icon')
->param('code', '', function () use ($types) {return new WhiteList(array_keys($types['browsers'])); }, 'Browser Code.')
->param('width', 100, function () {return new Range(0, 2000);}, 'Image width. Pass an integer between 0 to 2000. Defaults to 100', true)
->param('height', 100, function () {return new Range(0, 2000);}, 'Image height. Pass an integer between 0 to 2000. Defaults to 100', true)
->param('quality', 100, function () {return new Range(0, 100);}, 'Image quality. Pass an integer between 0 to 100. Defaults to 100', true)
->param('code', '', function () use ($types) {
return new WhiteList(array_keys($types['browsers']));
}, 'Browser Code.')
->param('width', 100, function () {
return new Range(0, 2000);
}, 'Image width. Pass an integer between 0 to 2000. Defaults to 100', true)
->param('height', 100, function () {
return new Range(0, 2000);
}, 'Image height. Pass an integer between 0 to 2000. Defaults to 100', true)
->param('quality', 100, function () {
return new Range(0, 100);
}, 'Image quality. Pass an integer between 0 to 100. Defaults to 100', true)
->label('scope', 'avatars.read')
->label('sdk.namespace', 'avatars')
->label('sdk.method', 'getBrowser')
->label('sdk.description', 'You can use this endpoint to show different browser icons to your users, The code argument receives the browser code as appear in your user /account/sessions endpoint. Use width, height and quality arguments to change the output settings.')
->action(function ($code, $width, $height, $quality) use ($avatarCallback) {return $avatarCallback('browsers', $code, $width, $height, $quality);});
->action(function ($code, $width, $height, $quality) use ($avatarCallback) {
return $avatarCallback('browsers', $code, $width, $height, $quality);
});
$utopia->get('/v1/avatars/flags/:code')
->desc('Get Country Flag')
->param('code', '', function () use ($types) {return new WhiteList(array_keys($types['flags'])); }, 'Country Code. ISO Alpha-2 country code format.')
->param('width', 100, function () {return new Range(0, 2000);}, 'Image width. Pass an integer between 0 to 2000. Defaults to 100', true)
->param('height', 100, function () {return new Range(0, 2000);}, 'Image height. Pass an integer between 0 to 2000. Defaults to 100', true)
->param('quality', 100, function () {return new Range(0, 100);}, 'Image quality. Pass an integer between 0 to 100. Defaults to 100', true)
->param('code', '', function () use ($types) {
return new WhiteList(array_keys($types['flags']));
}, 'Country Code. ISO Alpha-2 country code format.')
->param('width', 100, function () {
return new Range(0, 2000);
}, 'Image width. Pass an integer between 0 to 2000. Defaults to 100', true)
->param('height', 100, function () {
return new Range(0, 2000);
}, 'Image height. Pass an integer between 0 to 2000. Defaults to 100', true)
->param('quality', 100, function () {
return new Range(0, 100);
}, 'Image quality. Pass an integer between 0 to 100. Defaults to 100', true)
->label('scope', 'avatars.read')
->label('sdk.namespace', 'avatars')
->label('sdk.method', 'getFlag')
->label('sdk.description', 'You can use this endpoint to show different country flags icons to your users, The code argument receives the a 2 letter country code. Use width, height and quality arguments to change the output settings.')
->action(function ($code, $width, $height, $quality) use ($avatarCallback) {return $avatarCallback('flags', $code, $width, $height, $quality);});
->action(function ($code, $width, $height, $quality) use ($avatarCallback) {
return $avatarCallback('flags', $code, $width, $height, $quality);
});
$utopia->get('/v1/avatars/image')
->desc('Get Image from URL')
->param('url', '', function () {return new URL();}, 'Image URL which you want to crop.')
->param('width', 400, function () {return new Range(0, 2000);}, 'Resize preview image width, Pass an integer between 0 to 4000', true)
->param('height', 400, function () {return new Range(0, 2000);}, 'Resize preview image height, Pass an integer between 0 to 4000', true)
->param('url', '', function () {
return new URL();
}, 'Image URL which you want to crop.')
->param('width', 400, function () {
return new Range(0, 2000);
}, 'Resize preview image width, Pass an integer between 0 to 4000', true)
->param('height', 400, function () {
return new Range(0, 2000);
}, 'Resize preview image height, Pass an integer between 0 to 4000', true)
->label('scope', 'avatars.read')
->label('sdk.namespace', 'avatars')
->label('sdk.method', 'getImage')
@ -190,7 +226,9 @@ $utopia->get('/v1/avatars/image')
$utopia->get('/v1/avatars/favicon')
->desc('Get Favicon')
->param('url', '', function () {return new URL();}, 'Website URL which you want to fetch the favicon from.')
->param('url', '', function () {
return new URL();
}, 'Website URL which you want to fetch the favicon from.')
->label('scope', 'avatars.read')
->label('sdk.namespace', 'avatars')
->label('sdk.method', 'getFavicon')
@ -339,10 +377,18 @@ $utopia->get('/v1/avatars/favicon')
$utopia->get('/v1/avatars/qr')
->desc('Text to QR Generator')
->param('text', '', function () {return new Text(512);}, 'Plain text to be converted to QR code image')
->param('size', 400, function () {return new Range(0, 1000);}, 'QR code size. Pass an integer between 0 to 1000. Defaults to 400.', true)
->param('margin', 1, function () {return new Range(0, 10);}, 'Margin From Edge. Pass an integer between 0 to 10. Defaults to 1.', true)
->param('download', 0, function () {return new Range(0, 1);}, 'Return resulting image with \'Content-Disposition: attachment \' headers for the browser to start downloading it. Pass 0 for no header, or 1 for otherwise. Default value is set to 0.', true)
->param('text', '', function () {
return new Text(512);
}, 'Plain text to be converted to QR code image')
->param('size', 400, function () {
return new Range(0, 1000);
}, 'QR code size. Pass an integer between 0 to 1000. Defaults to 400.', true)
->param('margin', 1, function () {
return new Range(0, 10);
}, 'Margin From Edge. Pass an integer between 0 to 10. Defaults to 1.', true)
->param('download', 0, function () {
return new Range(0, 1);
}, 'Return resulting image with \'Content-Disposition: attachment \' headers for the browser to start downloading it. Pass 0 for no header, or 1 for otherwise. Default value is set to 0.', true)
->label('scope', 'avatars.read')
->label('sdk.namespace', 'avatars')
->label('sdk.method', 'getQR')
@ -365,7 +411,6 @@ $utopia->get('/v1/avatars/qr')
->setContentType('image/png')
->send('', $writer->writeString($text))
;
}
);

View file

@ -175,7 +175,9 @@ $utopia->get('/console/database/collection')
->desc('Platform console project settings')
->label('permission', 'public')
->label('scope', 'console')
->param('id', '', function () {return new UID();}, 'Collection unique ID.')
->param('id', '', function () {
return new UID();
}, 'Collection unique ID.')
->action(function ($id) use ($layout, $projectDB) {
$collection = $projectDB->getDocument($id, false);

View file

@ -27,10 +27,18 @@ $utopia->get('/v1/database')
->label('sdk.namespace', 'database')
->label('sdk.method', 'listCollections')
->label('sdk.description', 'Get a list of all the user collections. You can use the query params to filter your results. On admin mode, this endpoint will return a list of all of the project collections. [Learn more about different API modes](/docs/modes).')
->param('search', '', function () {return new Text(256);}, 'Search term to filter your list results.', true)
->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, 40000);}, '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)
->param('search', '', function () {
return new Text(256);
}, 'Search term to filter your list results.', true)
->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, 40000);
}, '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) {
/*$vl = new Structure($projectDB);
@ -74,7 +82,9 @@ $utopia->get('/v1/database/:collectionId')
->label('sdk.namespace', 'database')
->label('sdk.method', 'getCollection')
->label('sdk.description', 'Get collection by its unique ID. This endpoint response returns a JSON object with the collection metadata.')
->param('collectionId', '', function () {return new UID();}, 'Collection unique ID.')
->param('collectionId', '', function () {
return new UID();
}, 'Collection unique ID.')
->action(
function ($collectionId) use ($response, $projectDB) {
$collection = $projectDB->getDocument($collectionId, false);
@ -94,15 +104,23 @@ $utopia->post('/v1/database')
->label('sdk.namespace', 'database')
->label('sdk.method', 'createCollection')
->label('sdk.description', 'Create a new Collection.')
->param('name', '', function () {return new Text(256);}, 'Collection name.')
->param('read', [], function () {return new ArrayList(new Text(64));}, 'An array of strings with read permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('write', [], function () {return new ArrayList(new Text(64));}, 'An array of strings with write permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('rules', [], function () use ($projectDB) {return new ArrayList(new Collection($projectDB, [Database::SYSTEM_COLLECTION_RULES], ['$collection' => Database::SYSTEM_COLLECTION_RULES, '$permissions' => ['read' => [], 'write' => []]]));}, 'Array of [rule objects](/docs/rules). Each rule define a collection field name, data type and validation', true)
->param('name', '', function () {
return new Text(256);
}, 'Collection name.')
->param('read', [], function () {
return new ArrayList(new Text(64));
}, 'An array of strings with read permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('write', [], function () {
return new ArrayList(new Text(64));
}, 'An array of strings with write permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('rules', [], function () use ($projectDB) {
return new ArrayList(new Collection($projectDB, [Database::SYSTEM_COLLECTION_RULES], ['$collection' => Database::SYSTEM_COLLECTION_RULES, '$permissions' => ['read' => [], 'write' => []]]));
}, 'Array of [rule objects](/docs/rules). Each rule define a collection field name, data type and validation', true)
->action(
function ($name, $read, $write, $rules) use ($response, $projectDB, $webhook, $audit) {
$parsedRules = [];
foreach($rules as &$rule) {
foreach ($rules as &$rule) {
$parsedRules[] = array_merge([
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'$permissions' => [
@ -161,11 +179,21 @@ $utopia->put('/v1/database/:collectionId')
->label('sdk.namespace', 'database')
->label('sdk.method', 'updateCollection')
->label('sdk.description', 'Update collection by its unique ID.')
->param('collectionId', '', function () {return new UID();}, 'Collection unique ID.')
->param('name', null, function () {return new Text(256);}, 'Collection name.')
->param('read', [], function () {return new ArrayList(new Text(64));}, 'An array of strings with read permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('write', [], function () {return new ArrayList(new Text(64));}, 'An array of strings with write permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('rules', [], function () use ($projectDB) {return new ArrayList(new Collection($projectDB, [Database::SYSTEM_COLLECTION_RULES], ['$collection' => Database::SYSTEM_COLLECTION_RULES, '$permissions' => ['read' => [], 'write' => []]]));}, 'Array of [rule objects](/docs/rules). Each rule define a collection field name, data type and validation', true)
->param('collectionId', '', function () {
return new UID();
}, 'Collection unique ID.')
->param('name', null, function () {
return new Text(256);
}, 'Collection name.')
->param('read', [], function () {
return new ArrayList(new Text(64));
}, 'An array of strings with read permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('write', [], function () {
return new ArrayList(new Text(64));
}, 'An array of strings with write permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('rules', [], function () use ($projectDB) {
return new ArrayList(new Collection($projectDB, [Database::SYSTEM_COLLECTION_RULES], ['$collection' => Database::SYSTEM_COLLECTION_RULES, '$permissions' => ['read' => [], 'write' => []]]));
}, 'Array of [rule objects](/docs/rules). Each rule define a collection field name, data type and validation', true)
->action(
function ($collectionId, $name, $read, $write, $rules) use ($response, $projectDB) {
$collection = $projectDB->getDocument($collectionId, false);
@ -176,7 +204,7 @@ $utopia->put('/v1/database/:collectionId')
$parsedRules = [];
foreach($rules as &$rule) {
foreach ($rules as &$rule) {
$parsedRules[] = array_merge([
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'$permissions' => [
@ -211,7 +239,9 @@ $utopia->delete('/v1/database/:collectionId')
->label('sdk.namespace', 'database')
->label('sdk.method', 'deleteCollection')
->label('sdk.description', 'Delete a collection by its unique ID. Only users with write permissions have access to delete this resource.')
->param('collectionId', '', function () {return new UID();}, 'Collection unique ID.')
->param('collectionId', '', function () {
return new UID();
}, 'Collection unique ID.')
->action(
function ($collectionId) use ($response, $projectDB, $audit) {
$collection = $projectDB->getDocument($collectionId, false);
@ -240,16 +270,36 @@ $utopia->get('/v1/database/:collectionId/documents')
->label('sdk.namespace', 'database')
->label('sdk.method', 'listDocuments')
->label('sdk.description', 'Get a list of all the user documents. You can use the query params to filter your results. On admin mode, this endpoint will return a list of all of the project documents. [Learn more about different API modes](/docs/modes).')
->param('collectionId', null, function () {return new UID();}, 'Collection unique ID.')
->param('filters', [], function () {return new ArrayList(new Text(128));}, 'Array of filter strings. Each filter is constructed from a key name, comparison operator (=, !=, >, <, <=, >=) and a value. You can also use a dot (.) separator in attribute names to filter by child document attributes. Examples: \'name=John Doe\' or \'category.$uid>=5bed2d152c362\'', true)
->param('offset', 0, function () {return new Range(0, 900000000);}, 'Offset value. Use this value to manage pagination.', true)
->param('limit', 50, function () {return new Range(0, 1000);}, 'Maximum number of documents to return in response. Use this value to manage pagination.', true)
->param('order-field', '$uid', function () {return new Text(128);}, 'Document field that results will be sorted by.', true)
->param('order-type', 'ASC', function () {return new WhiteList(array('DESC', 'ASC'));}, 'Order direction. Possible values are DESC for descending order, or ASC for ascending order.', true)
->param('order-cast', 'string', function () {return new WhiteList(array('int', 'string', 'date', 'time', 'datetime'));}, 'Order field type casting. Possible values are int, string, date, time or datetime. The database will attempt to cast the order field to the value you pass here. The default value is a string.', true)
->param('search', '', function () {return new Text(256);}, 'Search query. Enter any free text search. The database will try to find a match against all document attributes and children.', true)
->param('first', 0, function () {return new Range(0, 1);}, 'Return only first document. Pass 1 for true or 0 for false. The default value is 0.', true)
->param('last', 0, function () {return new Range(0, 1);}, 'Return only last document. Pass 1 for true or 0 for false. The default value is 0.', true)
->param('collectionId', null, function () {
return new UID();
}, 'Collection unique ID.')
->param('filters', [], function () {
return new ArrayList(new Text(128));
}, 'Array of filter strings. Each filter is constructed from a key name, comparison operator (=, !=, >, <, <=, >=) and a value. You can also use a dot (.) separator in attribute names to filter by child document attributes. Examples: \'name=John Doe\' or \'category.$uid>=5bed2d152c362\'', true)
->param('offset', 0, function () {
return new Range(0, 900000000);
}, 'Offset value. Use this value to manage pagination.', true)
->param('limit', 50, function () {
return new Range(0, 1000);
}, 'Maximum number of documents to return in response. Use this value to manage pagination.', true)
->param('order-field', '$uid', function () {
return new Text(128);
}, 'Document field that results will be sorted by.', true)
->param('order-type', 'ASC', function () {
return new WhiteList(array('DESC', 'ASC'));
}, 'Order direction. Possible values are DESC for descending order, or ASC for ascending order.', true)
->param('order-cast', 'string', function () {
return new WhiteList(array('int', 'string', 'date', 'time', 'datetime'));
}, 'Order field type casting. Possible values are int, string, date, time or datetime. The database will attempt to cast the order field to the value you pass here. The default value is a string.', true)
->param('search', '', function () {
return new Text(256);
}, 'Search query. Enter any free text search. The database will try to find a match against all document attributes and children.', true)
->param('first', 0, function () {
return new Range(0, 1);
}, 'Return only first document. Pass 1 for true or 0 for false. The default value is 0.', true)
->param('last', 0, function () {
return new Range(0, 1);
}, 'Return only last document. Pass 1 for true or 0 for false. The default value is 0.', true)
->action(
function ($collectionId, $filters, $offset, $limit, $orderField, $orderType, $orderCast, $search, $first, $last) use ($response, $projectDB, $isDev) {
$collection = $projectDB->getDocument($collectionId, $isDev);
@ -306,8 +356,12 @@ $utopia->get('/v1/database/:collectionId/documents/:documentId')
->label('sdk.namespace', 'database')
->label('sdk.method', 'getDocument')
->label('sdk.description', 'Get document by its unique ID. This endpoint response returns a JSON object with the document data.')
->param('collectionId', null, function () {return new UID();}, 'Collection unique ID')
->param('documentId', null, function () {return new UID();}, 'Document unique ID')
->param('collectionId', null, function () {
return new UID();
}, 'Collection unique ID')
->param('documentId', null, function () {
return new UID();
}, 'Document unique ID')
->action(
function ($collectionId, $documentId) use ($response, $request, $projectDB, $isDev) {
$document = $projectDB->getDocument($documentId, $isDev);
@ -351,13 +405,27 @@ $utopia->post('/v1/database/:collectionId/documents')
->label('sdk.namespace', 'database')
->label('sdk.method', 'createDocument')
->label('sdk.description', 'Create a new Document.')
->param('collectionId', null, function () {return new UID();}, 'Collection unique ID.')
->param('data', [], function () {return new \Utopia\Validator\Mock();}, 'Document data as JSON string.')
->param('read', [], function () {return new ArrayList(new Text(64));}, 'An array of strings with read permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('write', [], function () {return new ArrayList(new Text(64));}, 'An array of strings with write permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('parentDocument', '', function () {return new UID();}, 'Parent document unique ID. Use when you want your new document to be a child of a parent document.', true)
->param('parentProperty', '', function () {return new Key();}, 'Parent document property name. Use when you want your new document to be a child of a parent document.', true)
->param('parentPropertyType', Document::SET_TYPE_ASSIGN, function () {return new WhiteList([Document::SET_TYPE_ASSIGN, Document::SET_TYPE_APPEND, Document::SET_TYPE_PREPEND]);}, 'Parent document property connection type. You can set this value to **assign**, **append** or **prepend**, default value is assign. Use when you want your new document to be a child of a parent document.', true)
->param('collectionId', null, function () {
return new UID();
}, 'Collection unique ID.')
->param('data', [], function () {
return new \Utopia\Validator\Mock();
}, 'Document data as JSON string.')
->param('read', [], function () {
return new ArrayList(new Text(64));
}, 'An array of strings with read permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('write', [], function () {
return new ArrayList(new Text(64));
}, 'An array of strings with write permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('parentDocument', '', function () {
return new UID();
}, 'Parent document unique ID. Use when you want your new document to be a child of a parent document.', true)
->param('parentProperty', '', function () {
return new Key();
}, 'Parent document property name. Use when you want your new document to be a child of a parent document.', true)
->param('parentPropertyType', Document::SET_TYPE_ASSIGN, function () {
return new WhiteList([Document::SET_TYPE_ASSIGN, Document::SET_TYPE_APPEND, Document::SET_TYPE_PREPEND]);
}, 'Parent document property connection type. You can set this value to **assign**, **append** or **prepend**, default value is assign. Use when you want your new document to be a child of a parent document.', true)
->action(
function ($collectionId, $data, $read, $write, $parentDocument, $parentProperty, $parentPropertyType) use ($response, $projectDB, $webhook, $audit) {
if (empty($data)) {
@ -454,11 +522,21 @@ $utopia->patch('/v1/database/:collectionId/documents/:documentId')
->label('scope', 'documents.write')
->label('sdk.namespace', 'database')
->label('sdk.method', 'updateDocument')
->param('collectionId', null, function () {return new UID();}, 'Collection unique ID')
->param('documentId', null, function () {return new UID();}, 'Document unique ID')
->param('data', [], function () {return new \Utopia\Validator\Mock();}, 'Document data as JSON string')
->param('read', [], function () {return new ArrayList(new Text(64));}, 'An array of strings with read permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('write', [], function () {return new ArrayList(new Text(64));}, 'An array of strings with write permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('collectionId', null, function () {
return new UID();
}, 'Collection unique ID')
->param('documentId', null, function () {
return new UID();
}, 'Document unique ID')
->param('data', [], function () {
return new \Utopia\Validator\Mock();
}, 'Document data as JSON string')
->param('read', [], function () {
return new ArrayList(new Text(64));
}, 'An array of strings with read permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('write', [], function () {
return new ArrayList(new Text(64));
}, 'An array of strings with write permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->action(
function ($collectionId, $documentId, $data, $read, $write) use ($response, $projectDB, &$output, $webhook, $audit, $isDev) {
$collection = $projectDB->getDocument($collectionId/*, $isDev*/);
@ -531,11 +609,14 @@ $utopia->delete('/v1/database/:collectionId/documents/:documentId')
->label('sdk.namespace', 'database')
->label('sdk.method', 'deleteDocument')
->label('sdk.description', 'Delete document by its unique ID. This endpoint deletes only the parent documents, his attributes and relations to other documents. Child documents **will not** be deleted.')
->param('collectionId', null, function () {return new UID();}, 'Collection unique ID')
->param('documentId', null, function () {return new UID();}, 'Document unique ID')
->param('collectionId', null, function () {
return new UID();
}, 'Collection unique ID')
->param('documentId', null, function () {
return new UID();
}, 'Document unique ID')
->action(
function ($collectionId, $documentId) use ($response, $projectDB, $audit, $isDev) {
$collection = $projectDB->getDocument($collectionId, $isDev);
$document = $projectDB->getDocument($documentId, $isDev);

View file

@ -67,7 +67,9 @@ $utopia->get('/v1/projects/:projectId')
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getProject')
->param('projectId', '', function () {return new UID();}, 'Project unique ID.')
->param('projectId', '', function () {
return new UID();
}, 'Project unique ID.')
->action(
function ($projectId) use ($request, $response, $providers, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -94,7 +96,9 @@ $utopia->get('/v1/projects/:projectId/usage')
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getProjectUsage')
->param('projectId', '', function () {return new UID();}, 'Project unique ID.')
->param('projectId', '', function () {
return new UID();
}, 'Project unique ID.')
->action(
function ($projectId) use ($response, $consoleDB, $projectDB, $register) {
$project = $consoleDB->getDocument($projectId);
@ -182,11 +186,15 @@ $utopia->get('/v1/projects/:projectId/usage')
$response->json([
'requests' => [
'data' => $requests,
'total' => array_sum(array_map(function ($item) {return $item['value'];}, $requests)),
'total' => array_sum(array_map(function ($item) {
return $item['value'];
}, $requests)),
],
'network' => [
'data' => $network,
'total' => array_sum(array_map(function ($item) {return $item['value'];}, $network)),
'total' => array_sum(array_map(function ($item) {
return $item['value'];
}, $network)),
],
'collections' => [
'data' => $collections,
@ -194,7 +202,9 @@ $utopia->get('/v1/projects/:projectId/usage')
],
'documents' => [
'data' => $documents,
'total' => array_sum(array_map(function ($item) {return $item['total'];}, $documents)),
'total' => array_sum(array_map(function ($item) {
return $item['total'];
}, $documents)),
],
'users' => [
'data' => [],
@ -205,7 +215,8 @@ $utopia->get('/v1/projects/:projectId/usage')
'total' => $tasksTotal,
],
'storage' => [
'total' => $projectDB->getCount([
'total' => $projectDB->getCount(
[
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_FILES,
],
@ -221,17 +232,39 @@ $utopia->post('/v1/projects')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'createProject')
->param('name', null, function () {return new Text(100);}, 'Project name')
->param('teamId', '', function () {return new UID();}, 'Team unique ID.')
->param('description', '', function () {return new Text(255);}, 'Project description', true)
->param('logo', '', function () {return new Text(1024);}, 'Project logo', true)
->param('url', '', function () {return new URL();}, 'Project URL', true)
->param('legalName', '', function () {return new Text(256);}, 'Project Legal Name', true)
->param('legalCountry', '', function () {return new Text(256);}, 'Project Legal Country', true)
->param('legalState', '', function () {return new Text(256);}, 'Project Legal State', true)
->param('legalCity', '', function () {return new Text(256);}, 'Project Legal City', true)
->param('legalAddress', '', function () {return new Text(256);}, 'Project Legal Address', true)
->param('legalTaxId', '', function () {return new Text(256);}, 'Project Legal Tax ID', true)
->param('name', null, function () {
return new Text(100);
}, 'Project name')
->param('teamId', '', function () {
return new UID();
}, 'Team unique ID.')
->param('description', '', function () {
return new Text(255);
}, 'Project description', true)
->param('logo', '', function () {
return new Text(1024);
}, 'Project logo', true)
->param('url', '', function () {
return new URL();
}, 'Project URL', true)
->param('legalName', '', function () {
return new Text(256);
}, 'Project Legal Name', true)
->param('legalCountry', '', function () {
return new Text(256);
}, 'Project Legal Country', true)
->param('legalState', '', function () {
return new Text(256);
}, 'Project Legal State', true)
->param('legalCity', '', function () {
return new Text(256);
}, 'Project Legal City', true)
->param('legalAddress', '', function () {
return new Text(256);
}, 'Project Legal Address', true)
->param('legalTaxId', '', function () {
return new Text(256);
}, 'Project Legal Tax ID', true)
->action(
function ($name, $teamId, $description, $logo, $url, $legalName, $legalCountry, $legalState, $legalCity, $legalAddress, $legalTaxId) use ($response, $user, $consoleDB, $projectDB) {
$team = $projectDB->getDocument($teamId);
@ -260,7 +293,8 @@ $utopia->post('/v1/projects')
'teamId' => $team->getUid(),
'webhooks' => [],
'keys' => [],
]);
]
);
if (false === $project) {
throw new Exception('Failed saving project to DB', 500);
@ -280,17 +314,39 @@ $utopia->patch('/v1/projects/:projectId')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateProject')
->param('projectId', '', function () {return new UID();}, 'Project unique ID.')
->param('name', null, function () {return new Text(100);}, 'Project name')
->param('description', '', function () {return new Text(255);}, 'Project description', true)
->param('logo', '', function () {return new Text(1024);}, 'Project logo', true)
->param('url', '', function () {return new URL();}, 'Project URL', true)
->param('legalName', '', function () {return new Text(256);}, 'Project Legal Name', true)
->param('legalCountry', '', function () {return new Text(256);}, 'Project Legal Country', true)
->param('legalState', '', function () {return new Text(256);}, 'Project Legal State', true)
->param('legalCity', '', function () {return new Text(256);}, 'Project Legal City', true)
->param('legalAddress', '', function () {return new Text(256);}, 'Project Legal Address', true)
->param('legalTaxId', '', function () {return new Text(256);}, 'Project Legal Tax ID', true)
->param('projectId', '', function () {
return new UID();
}, 'Project unique ID.')
->param('name', null, function () {
return new Text(100);
}, 'Project name')
->param('description', '', function () {
return new Text(255);
}, 'Project description', true)
->param('logo', '', function () {
return new Text(1024);
}, 'Project logo', true)
->param('url', '', function () {
return new URL();
}, 'Project URL', true)
->param('legalName', '', function () {
return new Text(256);
}, 'Project Legal Name', true)
->param('legalCountry', '', function () {
return new Text(256);
}, 'Project Legal Country', true)
->param('legalState', '', function () {
return new Text(256);
}, 'Project Legal State', true)
->param('legalCity', '', function () {
return new Text(256);
}, 'Project Legal City', true)
->param('legalAddress', '', function () {
return new Text(256);
}, 'Project Legal Address', true)
->param('legalTaxId', '', function () {
return new Text(256);
}, 'Project Legal Tax ID', true)
->action(
function ($projectId, $name, $description, $logo, $url, $legalName, $legalCountry, $legalState, $legalCity, $legalAddress, $legalTaxId) use ($response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -325,10 +381,18 @@ $utopia->patch('/v1/projects/:projectId/oauth')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateProjectOAuth')
->param('projectId', '', function () {return new UID();}, 'Project unique ID.')
->param('provider', '', function () use ($providers) {return new WhiteList(array_keys($providers));}, 'Provider Name', false)
->param('appId', '', function () {return new Text(256);}, 'Provider App ID', true)
->param('secret', '', function () {return new text(256);}, 'Provider Secret Key', true)
->param('projectId', '', function () {
return new UID();
}, 'Project unique ID.')
->param('provider', '', function () use ($providers) {
return new WhiteList(array_keys($providers));
}, 'Provider Name', false)
->param('appId', '', function () {
return new Text(256);
}, 'Provider App ID', true)
->param('secret', '', function () {
return new text(256);
}, 'Provider Secret Key', true)
->action(
function ($projectId, $provider, $appId, $secret) use ($request, $response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -366,7 +430,9 @@ $utopia->delete('/v1/projects/:projectId')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'deleteProject')
->param('projectId', '', function () {return new UID();}, 'Project unique ID.')
->param('projectId', '', function () {
return new UID();
}, 'Project unique ID.')
->action(
function ($projectId) use ($response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -400,7 +466,9 @@ $utopia->get('/v1/projects/:projectId/webhooks')
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'listWebhooks')
->param('projectId', '', function () {return new UID();}, 'Project unique ID.')
->param('projectId', '', function () {
return new UID();
}, 'Project unique ID.')
->action(
function ($projectId) use ($request, $response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -432,8 +500,12 @@ $utopia->get('/v1/projects/:projectId/webhooks/:webhookId')
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getWebhook')
->param('projectId', null, function () {return new UID();}, 'Project unique ID.')
->param('webhookId', null, function () {return new UID();}, 'Webhook unique ID.')
->param('projectId', null, function () {
return new UID();
}, 'Project unique ID.')
->param('webhookId', null, function () {
return new UID();
}, 'Webhook unique ID.')
->action(
function ($projectId, $webhookId) use ($request, $response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -464,13 +536,27 @@ $utopia->post('/v1/projects/:projectId/webhooks')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'createWebhook')
->param('projectId', null, function () {return new UID();}, 'Project unique ID.')
->param('name', null, function () {return new Text(256);}, 'Webhook name')
->param('events', null, function () {return new ArrayList(new Text(256));}, 'Webhook events list')
->param('url', null, function () {return new Text(2000);}, 'Webhook URL')
->param('security', null, function () {return new Range(0, 1);}, 'Certificate verification, 0 for disabled or 1 for enabled')
->param('httpUser', '', function () {return new Text(256);}, 'Webhook HTTP user', true)
->param('httpPass', '', function () {return new Text(256);}, 'Webhook HTTP password', true)
->param('projectId', null, function () {
return new UID();
}, 'Project unique ID.')
->param('name', null, function () {
return new Text(256);
}, 'Webhook name')
->param('events', null, function () {
return new ArrayList(new Text(256));
}, 'Webhook events list')
->param('url', null, function () {
return new Text(2000);
}, 'Webhook URL')
->param('security', null, function () {
return new Range(0, 1);
}, 'Certificate verification, 0 for disabled or 1 for enabled')
->param('httpUser', '', function () {
return new Text(256);
}, 'Webhook HTTP user', true)
->param('httpPass', '', function () {
return new Text(256);
}, 'Webhook HTTP password', true)
->action(
function ($projectId, $name, $events, $url, $security, $httpUser, $httpPass) use ($request, $response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -528,14 +614,30 @@ $utopia->put('/v1/projects/:projectId/webhooks/:webhookId')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateWebhook')
->param('projectId', null, function () {return new UID();}, 'Project unique ID.')
->param('webhookId', null, function () {return new UID();}, 'Webhook unique ID.')
->param('name', null, function () {return new Text(256);}, 'Webhook name')
->param('events', null, function () {return new ArrayList(new Text(256));}, 'Webhook events list')
->param('url', null, function () {return new Text(2000);}, 'Webhook URL')
->param('security', null, function () {return new Range(0, 1);}, 'Certificate verification, 0 for disabled or 1 for enabled')
->param('httpUser', '', function () {return new Text(256);}, 'Webhook HTTP user', true)
->param('httpPass', '', function () {return new Text(256);}, 'Webhook HTTP password', true)
->param('projectId', null, function () {
return new UID();
}, 'Project unique ID.')
->param('webhookId', null, function () {
return new UID();
}, 'Webhook unique ID.')
->param('name', null, function () {
return new Text(256);
}, 'Webhook name')
->param('events', null, function () {
return new ArrayList(new Text(256));
}, 'Webhook events list')
->param('url', null, function () {
return new Text(2000);
}, 'Webhook URL')
->param('security', null, function () {
return new Range(0, 1);
}, 'Certificate verification, 0 for disabled or 1 for enabled')
->param('httpUser', '', function () {
return new Text(256);
}, 'Webhook HTTP user', true)
->param('httpPass', '', function () {
return new Text(256);
}, 'Webhook HTTP password', true)
->action(
function ($projectId, $webhookId, $name, $events, $url, $security, $httpUser, $httpPass) use ($request, $response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -583,8 +685,12 @@ $utopia->delete('/v1/projects/:projectId/webhooks/:webhookId')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'deleteWebhook')
->param('projectId', null, function () {return new UID();}, 'Project unique ID.')
->param('webhookId', null, function () {return new UID();}, 'Webhook unique ID.')
->param('projectId', null, function () {
return new UID();
}, 'Project unique ID.')
->param('webhookId', null, function () {
return new UID();
}, 'Webhook unique ID.')
->action(
function ($projectId, $webhookId) use ($response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -614,7 +720,9 @@ $utopia->get('/v1/projects/:projectId/keys')
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'listKeys')
->param('projectId', null, function () {return new UID();}, 'Project unique ID.')
->param('projectId', null, function () {
return new UID();
}, 'Project unique ID.')
->action(
function ($projectId) use ($response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -632,8 +740,12 @@ $utopia->get('/v1/projects/:projectId/keys/:keyId')
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getKey')
->param('projectId', null, function () {return new UID();}, 'Project unique ID.')
->param('keyId', null, function () {return new UID();}, 'Key unique ID.')
->param('projectId', null, function () {
return new UID();
}, 'Project unique ID.')
->param('keyId', null, function () {
return new UID();
}, 'Key unique ID.')
->action(
function ($projectId, $keyId) use ($response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -657,9 +769,15 @@ $utopia->post('/v1/projects/:projectId/keys')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'createKey')
->param('projectId', null, function () {return new UID();}, 'Project unique ID.')
->param('name', null, function () {return new Text(256);}, 'Key name')
->param('scopes', null, function () use ($scopes) {return new ArrayList(new WhiteList($scopes));}, 'Key scopes list')
->param('projectId', null, function () {
return new UID();
}, 'Project unique ID.')
->param('name', null, function () {
return new Text(256);
}, 'Key name')
->param('scopes', null, function () use ($scopes) {
return new ArrayList(new WhiteList($scopes));
}, 'Key scopes list')
->action(
function ($projectId, $name, $scopes) use ($response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -703,10 +821,18 @@ $utopia->put('/v1/projects/:projectId/keys/:keyId')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateKey')
->param('projectId', null, function () {return new UID();}, 'Project unique ID.')
->param('keyId', null, function () {return new UID();}, 'Key unique ID.')
->param('name', null, function () {return new Text(256);}, 'Key name')
->param('scopes', null, function () use ($scopes) {return new ArrayList(new WhiteList($scopes));}, 'Key scopes list')
->param('projectId', null, function () {
return new UID();
}, 'Project unique ID.')
->param('keyId', null, function () {
return new UID();
}, 'Key unique ID.')
->param('name', null, function () {
return new Text(256);
}, 'Key name')
->param('scopes', null, function () use ($scopes) {
return new ArrayList(new WhiteList($scopes));
}, 'Key scopes list')
->action(
function ($projectId, $keyId, $name, $scopes) use ($response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -739,8 +865,12 @@ $utopia->delete('/v1/projects/:projectId/keys/:keyId')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'deleteKey')
->param('projectId', null, function () {return new UID();}, 'Project unique ID.')
->param('keyId', null, function () {return new UID();}, 'Key unique ID.')
->param('projectId', null, function () {
return new UID();
}, 'Project unique ID.')
->param('keyId', null, function () {
return new UID();
}, 'Key unique ID.')
->action(
function ($projectId, $keyId) use ($response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -770,7 +900,9 @@ $utopia->get('/v1/projects/:projectId/tasks')
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'listTasks')
->param('projectId', '', function () {return new UID();}, 'Project unique ID.')
->param('projectId', '', function () {
return new UID();
}, 'Project unique ID.')
->action(
function ($projectId) use ($request, $response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -802,8 +934,12 @@ $utopia->get('/v1/projects/:projectId/tasks/:taskId')
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getTask')
->param('projectId', null, function () {return new UID();}, 'Project unique ID.')
->param('taskId', null, function () {return new UID();}, 'Task unique ID.')
->param('projectId', null, function () {
return new UID();
}, 'Project unique ID.')
->param('taskId', null, function () {
return new UID();
}, 'Task unique ID.')
->action(
function ($projectId, $taskId) use ($request, $response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -834,16 +970,36 @@ $utopia->post('/v1/projects/:projectId/tasks')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'createTask')
->param('projectId', null, function () {return new UID();}, 'Project unique ID.')
->param('name', null, function () {return new Text(256);}, 'Task name')
->param('status', null, function () {return new WhiteList(['play', 'pause']);}, 'Task status')
->param('schedule', null, function () {return new Cron();}, 'Task schedule syntax')
->param('security', null, function () {return new Range(0, 1);}, 'Certificate verification, 0 for disabled or 1 for enabled')
->param('httpMethod', '', function () {return new WhiteList(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT']);}, 'Task HTTP method')
->param('httpUrl', '', function () {return new URL();}, 'Task HTTP URL')
->param('httpHeaders', null, function () {return new ArrayList(new Text(256));}, 'Task HTTP headers list', true)
->param('httpUser', '', function () {return new Text(256);}, 'Task HTTP user', true)
->param('httpPass', '', function () {return new Text(256);}, 'Task HTTP password', true)
->param('projectId', null, function () {
return new UID();
}, 'Project unique ID.')
->param('name', null, function () {
return new Text(256);
}, 'Task name')
->param('status', null, function () {
return new WhiteList(['play', 'pause']);
}, 'Task status')
->param('schedule', null, function () {
return new Cron();
}, 'Task schedule syntax')
->param('security', null, function () {
return new Range(0, 1);
}, 'Certificate verification, 0 for disabled or 1 for enabled')
->param('httpMethod', '', function () {
return new WhiteList(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT']);
}, 'Task HTTP method')
->param('httpUrl', '', function () {
return new URL();
}, 'Task HTTP URL')
->param('httpHeaders', null, function () {
return new ArrayList(new Text(256));
}, 'Task HTTP headers list', true)
->param('httpUser', '', function () {
return new Text(256);
}, 'Task HTTP user', true)
->param('httpPass', '', function () {
return new Text(256);
}, 'Task HTTP password', true)
->action(
function ($projectId, $name, $status, $schedule, $security, $httpMethod, $httpUrl, $httpHeaders, $httpUser, $httpPass) use ($request, $response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -916,17 +1072,39 @@ $utopia->put('/v1/projects/:projectId/tasks/:taskId')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateTask')
->param('projectId', null, function () {return new UID();}, 'Project unique ID.')
->param('taskId', null, function () {return new UID();}, 'Task unique ID.')
->param('name', null, function () {return new Text(256);}, 'Task name')
->param('status', null, function () {return new WhiteList(['play', 'pause']);}, 'Task status')
->param('schedule', null, function () {return new Cron();}, 'Task schedule syntax')
->param('security', null, function () {return new Range(0, 1);}, 'Certificate verification, 0 for disabled or 1 for enabled')
->param('httpMethod', '', function () {return new WhiteList(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT']);}, 'Task HTTP method')
->param('httpUrl', '', function () {return new URL();}, 'Task HTTP URL')
->param('httpHeaders', null, function () {return new ArrayList(new Text(256));}, 'Task HTTP headers list', true)
->param('httpUser', '', function () {return new Text(256);}, 'Task HTTP user', true)
->param('httpPass', '', function () {return new Text(256);}, 'Task HTTP password', true)
->param('projectId', null, function () {
return new UID();
}, 'Project unique ID.')
->param('taskId', null, function () {
return new UID();
}, 'Task unique ID.')
->param('name', null, function () {
return new Text(256);
}, 'Task name')
->param('status', null, function () {
return new WhiteList(['play', 'pause']);
}, 'Task status')
->param('schedule', null, function () {
return new Cron();
}, 'Task schedule syntax')
->param('security', null, function () {
return new Range(0, 1);
}, 'Certificate verification, 0 for disabled or 1 for enabled')
->param('httpMethod', '', function () {
return new WhiteList(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT']);
}, 'Task HTTP method')
->param('httpUrl', '', function () {
return new URL();
}, 'Task HTTP URL')
->param('httpHeaders', null, function () {
return new ArrayList(new Text(256));
}, 'Task HTTP headers list', true)
->param('httpUser', '', function () {
return new Text(256);
}, 'Task HTTP user', true)
->param('httpPass', '', function () {
return new Text(256);
}, 'Task HTTP password', true)
->action(
function ($projectId, $taskId, $name, $status, $schedule, $security, $httpMethod, $httpUrl, $httpHeaders, $httpUser, $httpPass) use ($request, $response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -986,8 +1164,12 @@ $utopia->delete('/v1/projects/:projectId/tasks/:taskId')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'deleteTask')
->param('projectId', null, function () {return new UID();}, 'Project unique ID.')
->param('taskId', null, function () {return new UID();}, 'Task unique ID.')
->param('projectId', null, function () {
return new UID();
}, 'Project unique ID.')
->param('taskId', null, function () {
return new UID();
}, 'Task unique ID.')
->action(
function ($projectId, $taskId) use ($response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -1017,7 +1199,9 @@ $utopia->get('/v1/projects/:projectId/platforms')
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'listPlatforms')
->param('projectId', '', function () {return new UID();}, 'Project unique ID.')
->param('projectId', '', function () {
return new UID();
}, 'Project unique ID.')
->action(
function ($projectId) use ($request, $response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -1037,8 +1221,12 @@ $utopia->get('/v1/projects/:projectId/platforms/:platformId')
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getPlatform')
->param('projectId', null, function () {return new UID();}, 'Project unique ID.')
->param('platformId', null, function () {return new UID();}, 'Platform unique ID.')
->param('projectId', null, function () {
return new UID();
}, 'Project unique ID.')
->param('platformId', null, function () {
return new UID();
}, 'Platform unique ID.')
->action(
function ($projectId, $platformId) use ($request, $response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -1062,12 +1250,24 @@ $utopia->post('/v1/projects/:projectId/platforms')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'createPlatform')
->param('projectId', null, function () {return new UID();}, 'Project unique ID.')
->param('type', null, function () {return new WhiteList(['web', 'ios', 'android', 'unity']);}, 'Platform name')
->param('name', null, function () {return new Text(256);}, 'Platform name')
->param('key', '', function () {return new Text(256);}, 'Package name for android or bundle ID for iOS', true)
->param('store', '', function () {return new Text(256);}, 'App store or Google Play store ID', true)
->param('url', '', function () {return new URL();}, 'Platform client URL', true)
->param('projectId', null, function () {
return new UID();
}, 'Project unique ID.')
->param('type', null, function () {
return new WhiteList(['web', 'ios', 'android', 'unity']);
}, 'Platform name')
->param('name', null, function () {
return new Text(256);
}, 'Platform name')
->param('key', '', function () {
return new Text(256);
}, 'Package name for android or bundle ID for iOS', true)
->param('store', '', function () {
return new Text(256);
}, 'App store or Google Play store ID', true)
->param('url', '', function () {
return new URL();
}, 'Platform client URL', true)
->action(
function ($projectId, $type, $name, $key, $store, $url) use ($response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -1115,12 +1315,24 @@ $utopia->put('/v1/projects/:projectId/platforms/:platformId')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updatePlatform')
->param('projectId', null, function () {return new UID();}, 'Project unique ID.')
->param('platformId', null, function () {return new UID();}, 'Platform unique ID.')
->param('name', null, function () {return new Text(256);}, 'Platform name')
->param('key', '', function () {return new Text(256);}, 'Package name for android or bundle ID for iOS', true)
->param('store', '', function () {return new Text(256);}, 'App store or Google Play store ID', true)
->param('url', '', function () {return new URL();}, 'Platform client URL', true)
->param('projectId', null, function () {
return new UID();
}, 'Project unique ID.')
->param('platformId', null, function () {
return new UID();
}, 'Platform unique ID.')
->param('name', null, function () {
return new Text(256);
}, 'Platform name')
->param('key', '', function () {
return new Text(256);
}, 'Package name for android or bundle ID for iOS', true)
->param('store', '', function () {
return new Text(256);
}, 'App store or Google Play store ID', true)
->param('url', '', function () {
return new URL();
}, 'Platform client URL', true)
->action(
function ($projectId, $platformId, $name, $key, $store, $url) use ($response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@ -1156,8 +1368,12 @@ $utopia->delete('/v1/projects/:projectId/platforms/:platformId')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'deletePlatform')
->param('projectId', null, function () {return new UID();}, 'Project unique ID.')
->param('platformId', null, function () {return new UID();}, 'Platform unique ID.')
->param('projectId', null, function () {
return new UID();
}, 'Project unique ID.')
->param('platformId', null, function () {
return new UID();
}, 'Platform unique ID.')
->action(
function ($projectId, $platformId) use ($response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);

View file

@ -119,10 +119,18 @@ $utopia->get('/v1/storage/files')
->label('sdk.namespace', 'storage')
->label('sdk.method', 'listFiles')
->label('sdk.description', 'Get a list of all the user files. You can use the query params to filter your results. On admin mode, this endpoint will return a list of all of the project files. [Learn more about different API modes](/docs/modes).')
->param('search', '', function () {return new Text(256);}, 'Search term to filter your list results.', true)
->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)
->param('search', '', function () {
return new Text(256);
}, 'Search term to filter your list results.', true)
->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([
@ -151,7 +159,9 @@ $utopia->get('/v1/storage/files/:fileId')
->label('sdk.namespace', 'storage')
->label('sdk.method', 'getFile')
->label('sdk.description', 'Get file by its unique ID. This endpoint response returns a JSON object with the file metadata.')
->param('fileId', '', function () {return new UID();}, 'File unique ID.')
->param('fileId', '', function () {
return new UID();
}, 'File unique ID.')
->action(
function ($fileId) use ($response, $projectDB) {
$file = $projectDB->getDocument($fileId);
@ -170,12 +180,24 @@ $utopia->get('/v1/storage/files/:fileId/preview')
->label('sdk.namespace', 'storage')
->label('sdk.method', 'getFilePreview')
->label('sdk.description', 'Get file preview image. Currently, this method supports preview for image files (jpg, png, and gif), other supported formats, like pdf, docs, slides, and spreadsheets will return file icon image. You can also pass query string arguments for cutting and resizing your preview image.')
->param('fileId', '', function () {return new UID();}, 'File unique ID')
->param('width', 0, function () {return new Range(0, 4000);}, 'Resize preview image width, Pass an integer between 0 to 4000', true)
->param('height', 0, function () {return new Range(0, 4000);}, 'Resize preview image height, Pass an integer between 0 to 4000', true)
->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 () use ($outputs) {return new WhiteList(array_merge(array_keys($outputs), [null]));}, 'Output format type (jpeg, jpg, png, gif and webp)', true)
->param('fileId', '', function () {
return new UID();
}, 'File unique ID')
->param('width', 0, function () {
return new Range(0, 4000);
}, 'Resize preview image width, Pass an integer between 0 to 4000', true)
->param('height', 0, function () {
return new Range(0, 4000);
}, 'Resize preview image height, Pass an integer between 0 to 4000', true)
->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 () use ($outputs) {
return new WhiteList(array_merge(array_keys($outputs), [null]));
}, 'Output format type (jpeg, jpg, png, gif and webp)', true)
//->param('storage', 'local', function () {return new WhiteList(array('local'));}, 'Selected storage device. defaults to local')
//->param('token', '', function () {return new Text(128);}, 'Preview token', true)
->action(
@ -282,7 +304,9 @@ $utopia->get('/v1/storage/files/:fileId/download')
->label('sdk.namespace', 'storage')
->label('sdk.method', 'getFileDownload')
->label('sdk.description', 'Get file content by its unique ID. The endpoint response return with a \'Content-Disposition: attachment\' header that tells the browser to start downloading the file to user downloads directory.')
->param('fileId', '', function () {return new UID();}, 'File unique ID.')
->param('fileId', '', function () {
return new UID();
}, 'File unique ID.')
->action(
function ($fileId) use ($response, $request, $projectDB) {
$file = $projectDB->getDocument($fileId);
@ -332,8 +356,12 @@ $utopia->get('/v1/storage/files/:fileId/view')
->label('sdk.namespace', 'storage')
->label('sdk.method', 'getFileView')
->label('sdk.description', 'Get file content by its unique ID. This endpoint is similar to the download method but returns with no \'Content-Disposition: attachment\' header.')
->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)
->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, $request, $projectDB, $mimes) {
$file = $projectDB->getDocument($fileId);
@ -400,10 +428,18 @@ $utopia->post('/v1/storage/files')
->label('sdk.method', 'createFile')
->label('sdk.description', 'Create a new file. The user who creates the file will automatically be assigned to read and write access unless he has passed custom values for read and write arguments.')
->label('sdk.consumes', 'multipart/form-data')
->param('files', [], function () {return new File();}, 'Binary Files.', false)
->param('read', [], function () {return new ArrayList(new Text(64));}, 'An array of strings with read permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('write', [], function () {return new ArrayList(new Text(64));}, 'An array of strings with write permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('folderId', '', function () {return new UID();}, 'Folder to associate files with.', true)
->param('files', [], function () {
return new File();
}, 'Binary Files.', false)
->param('read', [], function () {
return new ArrayList(new Text(64));
}, 'An array of strings with read permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('write', [], function () {
return new ArrayList(new Text(64));
}, 'An array of strings with write permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('folderId', '', function () {
return new UID();
}, 'Folder to associate files with.', true)
->action(
function ($files, $read, $write, $folderId) use ($request, $response, $user, $projectDB, $audit, $usage) {
$files = $request->getFiles('files');
@ -522,10 +558,18 @@ $utopia->put('/v1/storage/files/:fileId')
->label('sdk.namespace', 'storage')
->label('sdk.method', 'updateFile')
->label('sdk.description', 'Update file by its unique ID. Only users with write permissions have access to update this resource.')
->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. [Learn more about permissions and roles](/docs/permissions).', true)
->param('write', [], function () {return new ArrayList(new Text(64));}, 'An array of strings with write permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('folderId', '', function () {return new UID();}, 'Folder to associate files with.', true)
->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. [Learn more about permissions and roles](/docs/permissions).', true)
->param('write', [], function () {
return new ArrayList(new Text(64));
}, 'An array of strings with write permissions. [Learn more about permissions and roles](/docs/permissions).', true)
->param('folderId', '', function () {
return new UID();
}, 'Folder to associate files with.', true)
->action(
function ($fileId, $read, $write, $folderId) use ($response, $projectDB) {
$file = $projectDB->getDocument($fileId);
@ -556,7 +600,9 @@ $utopia->delete('/v1/storage/files/:fileId')
->label('sdk.namespace', 'storage')
->label('sdk.method', 'deleteFile')
->label('sdk.description', 'Delete a file by its unique ID. Only users with write permissions have access to delete this resource.')
->param('fileId', '', function () {return new UID();}, 'File unique ID.')
->param('fileId', '', function () {
return new UID();
}, 'File unique ID.')
->action(
function ($fileId) use ($response, $projectDB, $audit, $usage) {
$file = $projectDB->getDocument($fileId);
@ -592,8 +638,12 @@ $utopia->get('/v1/storage/files/:fileId/scan')
->label('sdk.namespace', 'storage')
->label('sdk.method', 'getFileScan')
->label('sdk.hide', true)
->param('fileId', '', function () {return new UID();}, 'File unique ID.')
->param('storage', 'local', function () {return new WhiteList(['local']);})
->param('fileId', '', function () {
return new UID();
}, 'File unique ID.')
->param('storage', 'local', function () {
return new WhiteList(['local']);
})
->action(
function ($fileId, $storage) use ($response, $request, $projectDB) {
$file = $projectDB->getDocument($fileId);

View file

@ -24,10 +24,18 @@ $utopia->get('/v1/teams')
->label('sdk.namespace', 'teams')
->label('sdk.method', 'listTeams')
->label('sdk.description', 'Get a list of all the current user teams. You can use the query params to filter your results. On admin mode, this endpoint will return a list of all of the project teams. [Learn more about different API modes](/docs/modes).')
->param('search', '', function () {return new Text(256);}, 'Search term to filter your list results.', true)
->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)
->param('search', '', function () {
return new Text(256);
}, 'Search term to filter your list results.', true)
->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([
@ -52,7 +60,9 @@ $utopia->get('/v1/teams/:teamId')
->label('sdk.namespace', 'teams')
->label('sdk.method', 'getTeam')
->label('sdk.description', 'Get team by its unique ID. All team members have read access for this resource.')
->param('teamId', '', function () {return new UID();}, 'Team unique ID.')
->param('teamId', '', function () {
return new UID();
}, 'Team unique ID.')
->action(
function ($teamId) use ($response, $projectDB) {
$team = $projectDB->getDocument($teamId);
@ -71,7 +81,9 @@ $utopia->get('/v1/teams/:teamId/members')
->label('sdk.namespace', 'teams')
->label('sdk.method', 'getTeamMembers')
->label('sdk.description', 'Get team members by the team unique ID. All team members have read access for this list of resources.')
->param('teamId', '', function () {return new UID();}, 'Team unique ID.')
->param('teamId', '', function () {
return new UID();
}, 'Team unique ID.')
->action(
function ($teamId) use ($response, $projectDB) {
$team = $projectDB->getDocument($teamId);
@ -123,8 +135,12 @@ $utopia->post('/v1/teams')
->label('sdk.namespace', 'teams')
->label('sdk.method', 'createTeam')
->label('sdk.description', 'Create a new team. The user who creates the team will automatically be assigned as the owner of the team. The team owner can invite new members, who will be able add new owners and update or delete the team from your project.')
->param('name', null, function () {return new Text(100);}, 'Team name.')
->param('roles', ['owner'], function () {return new ArrayList(new Text(128));}, 'User roles array. Use this param to set the roles in the team for the user who created the team. The default role is **owner**, a role can be any string.', true)
->param('name', null, function () {
return new Text(100);
}, 'Team name.')
->param('roles', ['owner'], function () {
return new ArrayList(new Text(128));
}, 'User roles array. Use this param to set the roles in the team for the user who created the team. The default role is **owner**, a role can be any string.', true)
->action(
function ($name, $roles) use ($response, $projectDB, $user, $mode) {
Authorization::disable();
@ -185,8 +201,12 @@ $utopia->put('/v1/teams/:teamId')
->label('sdk.namespace', 'teams')
->label('sdk.method', 'updateTeam')
->label('sdk.description', 'Update team by its unique ID. Only team owners have write access for this resource.')
->param('teamId', '', function () {return new UID();}, 'Team unique ID.')
->param('name', null, function () {return new Text(100);}, 'Team name.')
->param('teamId', '', function () {
return new UID();
}, 'Team unique ID.')
->param('name', null, function () {
return new Text(100);
}, 'Team name.')
->action(
function ($teamId, $name) use ($response, $projectDB) {
$team = $projectDB->getDocument($teamId);
@ -213,7 +233,9 @@ $utopia->delete('/v1/teams/:teamId')
->label('sdk.namespace', 'teams')
->label('sdk.method', 'deleteTeam')
->label('sdk.description', 'Delete team by its unique ID. Only team owners have write access for this resource.')
->param('teamId', '', function () {return new UID();}, 'Team unique ID.')
->param('teamId', '', function () {
return new UID();
}, 'Team unique ID.')
->action(
function ($teamId) use ($response, $projectDB) {
$team = $projectDB->getDocument($teamId);
@ -253,11 +275,21 @@ $utopia->post('/v1/teams/:teamId/memberships')
->label('sdk.namespace', 'teams')
->label('sdk.method', 'createTeamMembership')
->label('sdk.description', "Use this endpoint to invite a new member to your team. An email with a link to join the team will be sent to the new member email address. If member doesn't exists in the project it will be automatically created.\n\nUse the redirect parameter to redirect the user from the invitation email back to your app. When the user is redirected, use the /teams/{teamId}/memberships/{inviteId}/status endpoint to finally join the user to the team.\n\nPlease notice that in order to avoid a [Redirect Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URL's are the once from domains you have set when added your platforms in the console interface.")
->param('teamId', '', function () {return new UID();}, 'Team unique ID.')
->param('email', '', function () {return new Email();}, 'New team member email address.')
->param('name', '', function () {return new Text(100);}, 'New team member name.', true)
->param('roles', [], function () {return new ArrayList(new Text(128));}, 'Invite roles array. Learn more about [roles and permissions](/docs/permissions).')
->param('redirect', '', function () use ($clients) {return new Host($clients);}, 'Reset page to redirect user back to your app from the invitation email.')
->param('teamId', '', function () {
return new UID();
}, 'Team unique ID.')
->param('email', '', function () {
return new Email();
}, 'New team member email address.')
->param('name', '', function () {
return new Text(100);
}, 'New team member name.', true)
->param('roles', [], function () {
return new ArrayList(new Text(128));
}, 'Invite roles array. Learn more about [roles and permissions](/docs/permissions).')
->param('redirect', '', function () use ($clients) {
return new Host($clients);
}, 'Reset page to redirect user back to your app from the invitation email.')
->action(
function ($teamId, $email, $name, $roles, $redirect) use ($request, $response, $register, $project, $user, $audit, $projectDB) {
$name = (empty($name)) ? $email : $name;
@ -396,9 +428,15 @@ $utopia->post('/v1/teams/:teamId/memberships/:inviteId/resend')
->label('sdk.namespace', 'teams')
->label('sdk.method', 'createTeamMembershipResend')
->label('sdk.description', 'Use this endpoint to resend your invitation email for a user to join a team.')
->param('teamId', '', function () {return new UID();}, 'Team unique ID.')
->param('inviteId', '', function () {return new UID();}, 'Invite unique ID.')
->param('redirect', '', function () use ($clients) {return new Host($clients);}, 'Reset page to redirect user back to your app from the invitation email.')
->param('teamId', '', function () {
return new UID();
}, 'Team unique ID.')
->param('inviteId', '', function () {
return new UID();
}, 'Invite unique ID.')
->param('redirect', '', function () use ($clients) {
return new Host($clients);
}, 'Reset page to redirect user back to your app from the invitation email.')
->action(
function ($teamId, $inviteId, $redirect) use ($response, $register, $project, $user, $audit, $projectDB) {
$membership = $projectDB->getDocument($inviteId);
@ -477,12 +515,24 @@ $utopia->patch('/v1/teams/:teamId/memberships/:inviteId/status')
->label('sdk.method', 'updateTeamMembershipStatus')
->label('sdk.description', "Use this endpoint to let user accept an invitation to join a team after he is being redirect back to your app from the invitation email. Use the success and failure URL's to redirect users back to your application after the request completes.\n\nPlease notice that in order to avoid a [Redirect Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URL's are the once from domains you have set when added your platforms in the console interface.\n\nWhen not using the success or failure redirect arguments this endpoint will result with a 200 status code on success and with 401 status error on failure. This behavior was applied to help the web clients deal with browsers who don't allow to set 3rd party HTTP cookies needed for saving the account session token.")
->label('sdk.cookies', true)
->param('teamId', '', function () {return new UID();}, 'Team unique ID.')
->param('inviteId', '', function () {return new UID();}, 'Invite unique ID')
->param('userId', '', function () {return new UID();}, 'User unique ID')
->param('secret', '', function () {return new Text(256);}, 'Secret Key')
->param('success', null, function () use ($clients) {return new Host($clients);}, 'Redirect when registration succeed', true)
->param('failure', null, function () use ($clients) {return new Host($clients);}, 'Redirect when registration failed', true)
->param('teamId', '', function () {
return new UID();
}, 'Team unique ID.')
->param('inviteId', '', function () {
return new UID();
}, 'Invite unique ID')
->param('userId', '', function () {
return new UID();
}, 'User unique ID')
->param('secret', '', function () {
return new Text(256);
}, 'Secret Key')
->param('success', null, function () use ($clients) {
return new Host($clients);
}, 'Redirect when registration succeed', true)
->param('failure', null, function () use ($clients) {
return new Host($clients);
}, 'Redirect when registration failed', true)
->action(
function ($teamId, $inviteId, $userId, $secret, $success, $failure) use ($response, $request, $user, $audit, $projectDB) {
$invite = $projectDB->getDocument($inviteId);
@ -608,8 +658,12 @@ $utopia->delete('/v1/teams/:teamId/memberships/:inviteId')
->label('sdk.namespace', 'teams')
->label('sdk.method', 'deleteTeamMembership')
->label('sdk.description', 'This endpoint allows a user to leave a team or for a team owner to delete the membership of any other team member.')
->param('teamId', '', function () {return new UID();}, 'Team unique ID.')
->param('inviteId', '', function () {return new UID();}, 'Invite unique ID')
->param('teamId', '', function () {
return new UID();
}, 'Team unique ID.')
->param('inviteId', '', function () {
return new UID();
}, 'Invite unique ID')
->action(
function ($teamId, $inviteId) use ($response, $projectDB, $audit) {
$invite = $projectDB->getDocument($inviteId);

View file

@ -23,10 +23,18 @@ $utopia->get('/v1/users')
->label('sdk.namespace', 'users')
->label('sdk.method', 'listUsers')
->label('sdk.description', 'Get a list of all the project users. You can use the query params to filter your results.')
->param('search', '', function () {return new Text(256);}, 'Search term to filter your list results.', true)
->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)
->param('search', '', function () {
return new Text(256);
}, 'Search term to filter your list results.', true)
->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, $providers) {
$results = $projectDB->getCollection([
@ -60,7 +68,8 @@ $utopia->get('/v1/users')
'registration',
'confirm',
'name',
], $oauthKeys
],
$oauthKeys
));
}, $results);
@ -74,7 +83,9 @@ $utopia->get('/v1/users/:userId')
->label('sdk.namespace', 'users')
->label('sdk.method', 'getUser')
->label('sdk.description', 'Get user by its unique ID.')
->param('userId', '', function () {return new UID();}, 'User unique ID.')
->param('userId', '', function () {
return new UID();
}, 'User unique ID.')
->action(
function ($userId) use ($response, $projectDB, $providers) {
$user = $projectDB->getDocument($userId);
@ -101,7 +112,8 @@ $utopia->get('/v1/users/:userId')
'registration',
'confirm',
'name',
], $oauthKeys
],
$oauthKeys
)), ['roles' => Authorization::getRoles()]));
}
);
@ -112,7 +124,9 @@ $utopia->get('/v1/users/:userId/prefs')
->label('sdk.namespace', 'users')
->label('sdk.method', 'getUserPrefs')
->label('sdk.description', 'Get user preferences by its unique ID.')
->param('userId', '', function () {return new UID();}, 'User unique ID.')
->param('userId', '', function () {
return new UID();
}, 'User unique ID.')
->action(
function ($userId) use ($response, $projectDB) {
$user = $projectDB->getDocument($userId);
@ -143,7 +157,9 @@ $utopia->get('/v1/users/:userId/sessions')
->label('sdk.namespace', 'users')
->label('sdk.method', 'getUserSessions')
->label('sdk.description', 'Get user sessions list by its unique ID.')
->param('userId', '', function () {return new UID();}, 'User unique ID.')
->param('userId', '', function () {
return new UID();
}, 'User unique ID.')
->action(
function ($userId) use ($response, $projectDB) {
$user = $projectDB->getDocument($userId);
@ -205,7 +221,9 @@ $utopia->get('/v1/users/:userId/logs')
->label('sdk.namespace', 'users')
->label('sdk.method', 'getUserLogs')
->label('sdk.description', 'Get user activity logs list by its unique ID.')
->param('userId', '', function () {return new UID();}, 'User unique ID.')
->param('userId', '', function () {
return new UID();
}, 'User unique ID.')
->action(
function ($userId) use ($response, $register, $projectDB, $project) {
$user = $projectDB->getDocument($userId);
@ -266,9 +284,15 @@ $utopia->post('/v1/users')
->label('sdk.namespace', 'users')
->label('sdk.method', 'createUser')
->label('sdk.description', 'Create a new user.')
->param('email', '', function () {return new Email();}, 'User account email.')
->param('password', '', function () {return new Password();}, 'User account password.')
->param('name', '', function () {return new Text(100);}, 'User account name.', true)
->param('email', '', function () {
return new Email();
}, 'User account email.')
->param('password', '', function () {
return new Password();
}, 'User account password.')
->param('name', '', function () {
return new Text(100);
}, 'User account name.', true)
->action(
function ($email, $password, $name) use ($response, $register, $projectDB, $providers) {
$profile = $projectDB->getCollection([ // Get user by email address
@ -330,8 +354,12 @@ $utopia->patch('/v1/users/:userId/status')
->label('sdk.namespace', 'users')
->label('sdk.method', 'updateUserStatus')
->label('sdk.description', 'Update user status by its unique ID.')
->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 blocking the user pass '.Auth::USER_STATUS_BLOCKED.' and for disabling the user pass '.Auth::USER_STATUS_UNACTIVATED)
->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 blocking 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);
@ -360,8 +388,12 @@ $utopia->delete('/v1/users/:userId/sessions/:session')
->label('sdk.method', 'deleteUsersSession')
->label('sdk.description', 'Delete user sessions by its unique ID.')
->label('abuse-limit', 100)
->param('userId', '', function () {return new UID();}, 'User unique ID.')
->param('sessionId', null, function () {return new UID();}, 'User unique session ID.')
->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);
@ -391,7 +423,9 @@ $utopia->delete('/v1/users/:userId/sessions')
->label('sdk.method', 'deleteUserSessions')
->label('sdk.description', 'Delete all user sessions by its unique ID.')
->label('abuse-limit', 100)
->param('userId', '', function () {return new UID();}, 'User unique ID.')
->param('userId', '', function () {
return new UID();
}, 'User unique ID.')
->action(
function ($userId) use ($response, $request, $projectDB) {
$user = $projectDB->getDocument($userId);

View file

@ -1,7 +1,7 @@
<?php
// Init
if(file_exists(__DIR__ . '/../vendor/autoload.php')) {
if (file_exists(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
@ -51,7 +51,7 @@ define('COOKIE_DOMAIN', ($request->getServer('HTTP_HOST', null) === 'localhost'
/**
* Registry
*/
$register->set('db', function() use ($request) { // Register DB connection
$register->set('db', function () use ($request) { // Register DB connection
$dbHost = $request->getServer('_APP_DB_HOST', '');
$dbUser = $request->getServer('_APP_DB_USER', '');
$dbPass = $request->getServer('_APP_DB_PASS', '');
@ -68,11 +68,11 @@ $register->set('db', function() use ($request) { // Register DB connection
return $pdo;
});
$register->set('influxdb', function() use ($request) { // Register DB connection
$register->set('influxdb', function () use ($request) { // Register DB connection
$host = $request->getServer('_APP_INFLUXDB_HOST', '');
$port = $request->getServer('_APP_INFLUXDB_PORT', '');
if(empty($host) || empty($port)) {
if (empty($host) || empty($port)) {
return null;
}
@ -80,7 +80,7 @@ $register->set('influxdb', function() use ($request) { // Register DB connection
return $client;
});
$register->set('statsd', function() use ($request) { // Register DB connection
$register->set('statsd', function () use ($request) { // Register DB connection
$host = $request->getServer('_APP_STATSD_HOST', 'telegraf');
$port = $request->getServer('_APP_STATSD_PORT', 8125);
@ -89,13 +89,13 @@ $register->set('statsd', function() use ($request) { // Register DB connection
return $statsd;
});
$register->set('cache', function() use ($redisHost, $redisPort) { // Register cache connection
$register->set('cache', function () use ($redisHost, $redisPort) { // Register cache connection
$redis = new Redis();
$redis->connect($redisHost, $redisPort);
return $redis;
});
$register->set('smtp', function() use ($request) {
$register->set('smtp', function () use ($request) {
$mail = new PHPMailer(true);
$mail->isSMTP();
@ -131,7 +131,7 @@ Locale::setLanguage('he', include __DIR__ . '/config/locale/he.php');
Locale::setLanguage('pt-br', include __DIR__ . '/config/locale/pt-br.php');
Locale::setLanguage('es', include __DIR__ . '/config/locale/es.php');
if(in_array($locale, APP_LOCALES)) {
if (in_array($locale, APP_LOCALES)) {
Locale::setDefault($locale);
}
@ -159,7 +159,7 @@ Authorization::enable();
$console = $consoleDB->getDocument('console');
if(is_null($project->getUid()) || Database::SYSTEM_COLLECTION_PROJECTS !== $project->getCollection()) {
if (is_null($project->getUid()) || Database::SYSTEM_COLLECTION_PROJECTS !== $project->getCollection()) {
$project = $console;
}
@ -167,7 +167,7 @@ $mode = $request->getParam('mode', $request->getHeader('X-Appwrite-Mode', 'defau
Auth::setCookieName('a-session-' . $project->getUid());
if(APP_MODE_ADMIN === $mode) {
if (APP_MODE_ADMIN === $mode) {
Auth::setCookieName('a-session-' . $console->getUid());
}
@ -182,7 +182,7 @@ $projectDB->setMocks($collections);
$user = $projectDB->getDocument(Auth::$unique);
if(APP_MODE_ADMIN === $mode) {
if (APP_MODE_ADMIN === $mode) {
$user = $consoleDB->getDocument(Auth::$unique);
$user
@ -190,20 +190,19 @@ if(APP_MODE_ADMIN === $mode) {
;
}
if(empty($user->getUid()) // Check a document has been found in the DB
if (empty($user->getUid()) // Check a document has been found in the DB
|| Database::SYSTEM_COLLECTION_USERS !== $user->getCollection() // Validate returned document is really a user document
|| !Auth::tokenVerify($user->getAttribute('tokens', []), Auth::TOKEN_TYPE_LOGIN, Auth::$secret)) { // Validate user has valid login token
$user = new Document(['$uid' => '', '$collection' => Database::SYSTEM_COLLECTION_USERS]);
}
if(APP_MODE_ADMIN === $mode) {
if(!empty($user->search('teamId', $project->getAttribute('teamId'), $user->getAttribute('memberships')))) {
if (APP_MODE_ADMIN === $mode) {
if (!empty($user->search('teamId', $project->getAttribute('teamId'), $user->getAttribute('memberships')))) {
Authorization::disable();
}
else {
} else {
$user = new Document(['$uid' => '', '$collection' => Database::SYSTEM_COLLECTION_USERS]);
}
}
// Set project mail
$register->get('smtp')->setFrom(APP_EMAIL_TEAM, sprintf(Locale::getText('auth.emails.team'), $project->getAttribute('name')));
$register->get('smtp')->setFrom(APP_EMAIL_TEAM, sprintf(Locale::getText('auth.emails.team'), $project->getAttribute('name')));

View file

@ -185,7 +185,7 @@ class Client
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, php_uname('s') . '-' . php_uname('r') . ':php-' . phpversion());
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $header) use (&$responseHeaders) {
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($curl, $header) use (&$responseHeaders) {
$len = strlen($header);
$header = explode(':', strtolower($header), 2);
@ -198,12 +198,12 @@ class Client
return $len;
});
if($method != self::METHOD_GET) {
if ($method != self::METHOD_GET) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
}
// Allow self signed certificates
if($this->selfSigned) {
if ($this->selfSigned) {
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
}
@ -212,7 +212,7 @@ class Client
$responseType = (isset($responseHeaders['content-type'])) ? $responseHeaders['content-type'] : '';
$responseStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
switch(substr($responseType, 0, strpos($responseType, ';'))) {
switch (substr($responseType, 0, strpos($responseType, ';'))) {
case 'application/json':
$responseBody = json_decode($responseBody, true);
break;
@ -234,16 +234,16 @@ class Client
* @param string $prefix
* @return array
*/
protected function flatten(array $data, $prefix = '') {
protected function flatten(array $data, $prefix = '')
{
$output = [];
foreach($data as $key => $value) {
foreach ($data as $key => $value) {
$finalKey = $prefix ? "{$prefix}[{$key}]" : $key;
if (is_array($value)) {
$output += $this->flatten($value, $finalKey); // @todo: handle name collision here if needed
}
else {
} else {
$output[$finalKey] = $value;
}
}

View file

@ -16,4 +16,4 @@ abstract class Service
{
$this->client = $client;
}
}
}

View file

@ -188,5 +188,4 @@ class Account extends Service
return $this->client->call(Client::METHOD_GET, $path, [
], $params);
}
}
}

View file

@ -13,13 +13,13 @@ class Auth extends Service
*
* Allow the user to login into his account by providing a valid email and
* password combination. Use the success and failure arguments to provide a
* redirect URL\'s back to your app when login is completed.
*
* redirect URL\'s back to your app when login is completed.
*
* Please notice that in order to avoid a [Redirect
* Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
* the only valid redirect URL's are the once from domains you have set when
* added your platforms in the console interface.
*
*
* When not using the success or failure redirect arguments this endpoint will
* result with a 200 status code and the user account object on success and
* with 401 status error on failure. This behavior was applied to help the web
@ -165,7 +165,7 @@ class Auth extends Service
* **userId** and **token** arguments will be passed as query parameters to
* the redirect URL you have provided when sending your request to the
* /auth/recovery endpoint.
*
*
* Please notice that in order to avoid a [Redirect
* Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
* the only valid redirect URL's are the once from domains you have set when
@ -198,18 +198,18 @@ class Auth extends Service
* Use this endpoint to allow a new user to register an account in your
* project. Use the success and failure URL's to redirect users back to your
* application after signup completes.
*
*
* If registration completes successfully user will be sent with a
* confirmation email in order to confirm he is the owner of the account email
* address. Use the redirect parameter to redirect the user from the
* confirmation email back to your app. When the user is redirected, use the
* /auth/confirm endpoint to complete the account confirmation.
*
*
* Please notice that in order to avoid a [Redirect
* Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
* the only valid redirect URL's are the once from domains you have set when
* added your platforms in the console interface.
*
*
* When not using the success or failure redirect arguments this endpoint will
* result with a 200 status code and the user account object on success and
* with 401 status error on failure. This behavior was applied to help the web
@ -272,7 +272,7 @@ class Auth extends Service
* This endpoint allows the user to request your app to resend him his email
* confirmation message. The redirect arguments acts the same way as in
* /auth/register endpoint.
*
*
* Please notice that in order to avoid a [Redirect
* Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
* the only valid redirect URL's are the once from domains you have set when
@ -292,5 +292,4 @@ class Auth extends Service
return $this->client->call(Client::METHOD_POST, $path, [
], $params);
}
}
}

View file

@ -165,5 +165,4 @@ class Avatars extends Service
return $this->client->call(Client::METHOD_GET, $path, [
], $params);
}
}
}

View file

@ -267,5 +267,4 @@ class Database extends Service
return $this->client->call(Client::METHOD_DELETE, $path, [
], $params);
}
}
}

View file

@ -106,5 +106,4 @@ class Locale extends Service
return $this->client->call(Client::METHOD_GET, $path, [
], $params);
}
}
}

View file

@ -610,5 +610,4 @@ class Projects extends Service
return $this->client->call(Client::METHOD_DELETE, $path, [
], $params);
}
}
}

View file

@ -205,5 +205,4 @@ class Storage extends Service
return $this->client->call(Client::METHOD_GET, $path, [
], $params);
}
}
}

View file

@ -149,12 +149,12 @@ class Teams extends Service
* Use this endpoint to invite a new member to your team. An email with a link
* to join the team will be sent to the new member email address. If member
* doesn't exists in the project it will be automatically created.
*
*
* Use the redirect parameter to redirect the user from the invitation email
* back to your app. When the user is redirected, use the
* /teams/{teamId}/memberships/{inviteId}/status endpoint to finally join the
* user to the team.
*
*
* Please notice that in order to avoid a [Redirect
* Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
* the only valid redirect URL's are the once from domains you have set when
@ -233,12 +233,12 @@ class Teams extends Service
* is being redirect back to your app from the invitation email. Use the
* success and failure URL's to redirect users back to your application after
* the request completes.
*
*
* Please notice that in order to avoid a [Redirect
* Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
* the only valid redirect URL's are the once from domains you have set when
* added your platforms in the console interface.
*
*
* When not using the success or failure redirect arguments this endpoint will
* result with a 200 status code on success and with 401 status error on
* failure. This behavior was applied to help the web clients deal with
@ -267,5 +267,4 @@ class Teams extends Service
return $this->client->call(Client::METHOD_PATCH, $path, [
], $params);
}
}
}

View file

@ -195,5 +195,4 @@ class Users extends Service
return $this->client->call(Client::METHOD_PATCH, $path, [
], $params);
}
}
}

View file

@ -19,7 +19,6 @@ $cli = new CLI();
$cli
->task('generate')
->action(function () {
function getSSLPage($url)
{
$ch = curl_init();
@ -211,4 +210,4 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
}
});
$cli->run();
$cli->run();

View file

@ -91,7 +91,10 @@ class TasksV1
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, sprintf(APP_USERAGENT, $version));
curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge($headers, [
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
array_merge($headers, [
'X-'.APP_NAME.'-Task-UID: '.$task->getAttribute('$uid', ''),
'X-'.APP_NAME.'-Task-Name: '.$task->getAttribute('name', ''),
])

View file

@ -59,7 +59,10 @@ class WebhooksV1
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, sprintf(APP_USERAGENT, $version));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
[
'Content-Type: application/json',
'Content-Length: '.strlen($payload),
'X-'.APP_NAME.'-Event: '.$event,

View file

@ -31,4 +31,4 @@ switch ($version) { // Switch between API version
$service = $version . '/';
include __DIR__ . '/../app/app.php';
break;
}
}

View file

@ -46,14 +46,14 @@ class MySQL extends Adapter
$data = mb_strcut(json_encode($data), 0, 64000, 'UTF-8'); // Limit data to MySQL 64kb limit
$st->bindValue(':userId', $userId, PDO::PARAM_STR);
$st->bindValue(':userType', $userType, PDO::PARAM_INT);
$st->bindValue(':event', $event, PDO::PARAM_STR);
$st->bindValue(':resource', $resource, PDO::PARAM_STR);
$st->bindValue(':userAgent', $userAgent, PDO::PARAM_STR);
$st->bindValue(':ip', $ip, PDO::PARAM_STR);
$st->bindValue(':location', $location, PDO::PARAM_STR);
$st->bindValue(':data', $data, PDO::PARAM_STR);
$st->bindValue(':userId', $userId, PDO::PARAM_STR);
$st->bindValue(':userType', $userType, PDO::PARAM_INT);
$st->bindValue(':event', $event, PDO::PARAM_STR);
$st->bindValue(':resource', $resource, PDO::PARAM_STR);
$st->bindValue(':userAgent', $userAgent, PDO::PARAM_STR);
$st->bindValue(':ip', $ip, PDO::PARAM_STR);
$st->bindValue(':location', $location, PDO::PARAM_STR);
$st->bindValue(':data', $data, PDO::PARAM_STR);
$st->execute();
@ -69,8 +69,8 @@ class MySQL extends Adapter
ORDER BY `time` DESC LIMIT 10
');
$st->bindValue(':userId', $userId, PDO::PARAM_STR);
$st->bindValue(':userType', $userType, PDO::PARAM_INT);
$st->bindValue(':userId', $userId, PDO::PARAM_STR);
$st->bindValue(':userType', $userType, PDO::PARAM_INT);
$st->execute();
@ -95,8 +95,8 @@ class MySQL extends Adapter
ORDER BY `time` DESC LIMIT 10
');
$st->bindValue(':userId', $userId, PDO::PARAM_STR);
$st->bindValue(':userType', $userType, PDO::PARAM_INT);
$st->bindValue(':userId', $userId, PDO::PARAM_STR);
$st->bindValue(':userType', $userType, PDO::PARAM_INT);
foreach ($actions as $k => $id) {
$st->bindValue(':action_'.$k, $id);

View file

@ -39,7 +39,9 @@ class Facebook extends OAuth
*/
public function getAccessToken(string $code):string
{
$accessToken = $this->request('GET', 'https://graph.facebook.com/'.$this->version.'/oauth/access_token?'.
$accessToken = $this->request(
'GET',
'https://graph.facebook.com/'.$this->version.'/oauth/access_token?'.
'client_id='.urlencode($this->appID).
'&redirect_uri='.urlencode($this->callback).
'&client_secret='.urlencode($this->appSecret).

View file

@ -34,7 +34,10 @@ class Github extends OAuth
*/
public function getAccessToken(string $code):string
{
$accessToken = $this->request('POST', 'https://github.com/login/oauth/access_token', [],
$accessToken = $this->request(
'POST',
'https://github.com/login/oauth/access_token',
[],
'client_id='.urlencode($this->appID).
'&redirect_uri='.urlencode($this->callback).
'&client_secret='.urlencode($this->appSecret).

View file

@ -61,7 +61,10 @@ class LinkedIn extends OAuth
*/
public function getAccessToken(string $code):string
{
$accessToken = $this->request('POST', 'https://www.linkedin.com/oauth/v2/accessToken', ['Content-Type: application/x-www-form-urlencoded'],
$accessToken = $this->request(
'POST',
'https://www.linkedin.com/oauth/v2/accessToken',
['Content-Type: application/x-www-form-urlencoded'],
http_build_query([
'grant_type' => 'authorization_code',
'code' => $code,

View file

@ -189,11 +189,11 @@ class MySQL extends Adapter
$data['$uid'] = $this->getUid();
}
$st1->bindValue(':uid', $data['$uid'], PDO::PARAM_STR);
$st1->bindValue(':revision', $revision, PDO::PARAM_STR);
$st1->bindValue(':signature', $signature, PDO::PARAM_STR);
$st1->bindValue(':createdAt', date('Y-m-d H:i:s', time()), PDO::PARAM_STR);
$st1->bindValue(':updatedAt', date('Y-m-d H:i:s', time()), PDO::PARAM_STR);
$st1->bindValue(':uid', $data['$uid'], PDO::PARAM_STR);
$st1->bindValue(':revision', $revision, PDO::PARAM_STR);
$st1->bindValue(':signature', $signature, PDO::PARAM_STR);
$st1->bindValue(':createdAt', date('Y-m-d H:i:s', time()), PDO::PARAM_STR);
$st1->bindValue(':updatedAt', date('Y-m-d H:i:s', time()), PDO::PARAM_STR);
$st1->bindValue(':permissions', json_encode($data['$permissions']), PDO::PARAM_STR);
$st1->execute();
@ -274,14 +274,14 @@ class MySQL extends Adapter
if (is_array($prop['value'])) {
throw new Exception('Value can\'t be an array: '.json_encode($prop['value']));
}
$st2->bindValue(':documentUid', $data['$uid'], PDO::PARAM_STR);
$st2->bindValue(':documentRevision', $revision, PDO::PARAM_STR);
$st2->bindValue(':documentUid', $data['$uid'], PDO::PARAM_STR);
$st2->bindValue(':documentRevision', $revision, PDO::PARAM_STR);
$st2->bindValue(':key', $prop['key'], PDO::PARAM_STR);
$st2->bindValue(':value', $prop['value'], PDO::PARAM_STR);
$st2->bindValue(':primitive', $prop['type'], PDO::PARAM_STR);
$st2->bindValue(':array', $prop['array'], PDO::PARAM_BOOL);
$st2->bindValue(':order', $prop['order'], PDO::PARAM_STR);
$st2->bindValue(':key', $prop['key'], PDO::PARAM_STR);
$st2->bindValue(':value', $prop['value'], PDO::PARAM_STR);
$st2->bindValue(':primitive', $prop['type'], PDO::PARAM_STR);
$st2->bindValue(':array', $prop['array'], PDO::PARAM_BOOL);
$st2->bindValue(':order', $prop['order'], PDO::PARAM_STR);
$st2->execute();
}
@ -367,12 +367,12 @@ class MySQL extends Adapter
(`revision`, `start`, `end`, `key`, `array`, `order`)
VALUES (:revision, :start, :end, :key, :array, :order)');
$st2->bindValue(':revision', $revision, PDO::PARAM_STR);
$st2->bindValue(':start', $start, PDO::PARAM_STR);
$st2->bindValue(':end', $end, PDO::PARAM_STR);
$st2->bindValue(':key', $key, PDO::PARAM_STR);
$st2->bindValue(':array', $isArray, PDO::PARAM_INT);
$st2->bindValue(':order', $order, PDO::PARAM_INT);
$st2->bindValue(':revision', $revision, PDO::PARAM_STR);
$st2->bindValue(':start', $start, PDO::PARAM_STR);
$st2->bindValue(':end', $end, PDO::PARAM_STR);
$st2->bindValue(':key', $key, PDO::PARAM_STR);
$st2->bindValue(':array', $isArray, PDO::PARAM_INT);
$st2->bindValue(':order', $order, PDO::PARAM_INT);
$st2->execute();

View file

@ -38,7 +38,8 @@ class Collection extends Structure
public function isValid($document)
{
$document = new Document(
array_merge($this->merge, ($document instanceof Document) ? $document->getArrayCopy() : $document));
array_merge($this->merge, ($document instanceof Document) ? $document->getArrayCopy() : $document)
);
if (is_null($document->getCollection())) {
$this->message = 'Missing collection attribute $collection';

View file

@ -188,7 +188,7 @@ class Structure extends Validator
if (empty($validator)) { // Error creating validator for property
$this->message = 'Unknown rule type "' . $ruleType . '" for property "' . htmlspecialchars($key, ENT_QUOTES, 'UTF-8') . '"';
if(empty($ruleType)) {
if (empty($ruleType)) {
$this->message = 'Unknown property "'.$key.'" type'.
'. Make sure to follow '.strtolower($collection->getAttribute('name', 'unknown')).' collection structure';
}

View file

@ -34,9 +34,9 @@ class OpenSSL
*
* @return string
*/
public static function decrypt($data, $method, $password, $options = 1, $iv = '', $tag = '', $aad = '')
public static function decrypt($data, $method, $password, $options = 1, $iv = '', $tag = '', $aad = '')
{
return openssl_decrypt($data, $method, $password, $options, $iv, $tag, $aad);
return openssl_decrypt($data, $method, $password, $options, $iv, $tag, $aad);
}
/**

View file

@ -23,8 +23,8 @@ class BaseConsole extends TestCase
->setEndpoint($this->endpoint)
;
$this->demoEmail = 'user.' . rand(0,1000000) . '@appwrite.io';
$this->demoPassword = 'password.' . rand(0,1000000);
$this->demoEmail = 'user.' . rand(0, 1000000) . '@appwrite.io';
$this->demoPassword = 'password.' . rand(0, 1000000);
}
public function tearDown()
@ -32,7 +32,8 @@ class BaseConsole extends TestCase
$this->client = null;
}
public function register() {
public function register()
{
$response = $this->client->call(Client::METHOD_POST, '/auth/register', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
@ -47,4 +48,4 @@ class BaseConsole extends TestCase
return $response;
}
}
}

View file

@ -16,8 +16,8 @@ class BaseProjects extends BaseConsole
{
parent::setUp();
$this->projectsDemoEmail = 'user.' . rand(0,1000000) . '@appwrite.io';
$this->projectsDemoPassword = 'password.' . rand(0,1000000);
$this->projectsDemoEmail = 'user.' . rand(0, 1000000) . '@appwrite.io';
$this->projectsDemoPassword = 'password.' . rand(0, 1000000);
}
public function tearDown()
@ -44,4 +44,4 @@ class BaseProjects extends BaseConsole
return $response;
}
}
}

View file

@ -185,7 +185,7 @@ class Client
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, php_uname('s') . '-' . php_uname('r') . ':php-' . phpversion());
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $header) use (&$responseHeaders) {
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($curl, $header) use (&$responseHeaders) {
$len = strlen($header);
$header = explode(':', $header, 2);
@ -198,12 +198,12 @@ class Client
return $len;
});
if($method != self::METHOD_GET) {
if ($method != self::METHOD_GET) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
}
// Allow self signed certificates
if($this->selfSigned) {
if ($this->selfSigned) {
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
}
@ -212,7 +212,7 @@ class Client
$responseType = (isset($responseHeaders['content-type'])) ? $responseHeaders['content-type'] : '';
$responseStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
switch(substr($responseType, 0, strpos($responseType, ';'))) {
switch (substr($responseType, 0, strpos($responseType, ';'))) {
case 'application/json':
$responseBody = json_decode($responseBody, true);
break;
@ -254,16 +254,16 @@ class Client
* @param string $prefix
* @return array
*/
protected function flatten(array $data, $prefix = '') {
protected function flatten(array $data, $prefix = '')
{
$output = [];
foreach($data as $key => $value) {
foreach ($data as $key => $value) {
$finalKey = $prefix ? "{$prefix}[{$key}]" : $key;
if (is_array($value)) {
$output += $this->flatten($value, $finalKey); // @todo: handle name collision here if needed
}
else {
} else {
$output[$finalKey] = $value;
}
}

View file

@ -5,7 +5,7 @@ namespace Tests\E2E;
use Tests\E2E\Client;
class ConsoleHealthTest extends BaseConsole
{
{
public function testHTTPSuccess()
{
$response = $this->client->call(Client::METHOD_GET, '/health', [
@ -88,4 +88,4 @@ class ConsoleHealthTest extends BaseConsole
$this->assertEquals('online', $response['body']['status']);
$this->assertStringStartsWith('ClamAV ', $response['body']['version']);
}
}
}

View file

@ -5,7 +5,7 @@ namespace Tests\E2E;
use Tests\E2E\Client;
class ConsoleProjectsTest extends BaseConsole
{
{
public function testRegisterSuccess()
{
$response = $this->register();
@ -25,7 +25,8 @@ class ConsoleProjectsTest extends BaseConsole
/**
* @depends testRegisterSuccess
*/
public function testProjectsList($data) {
public function testProjectsList($data)
{
$response = $this->client->call(Client::METHOD_GET, '/projects', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
@ -39,7 +40,8 @@ class ConsoleProjectsTest extends BaseConsole
/**
* @depends testRegisterSuccess
*/
public function testProjectsCreateSuccess($data) {
public function testProjectsCreateSuccess($data)
{
$team = $this->client->call(Client::METHOD_POST, '/teams', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
@ -81,8 +83,8 @@ class ConsoleProjectsTest extends BaseConsole
/**
* @depends testProjectsCreateSuccess
*/
public function testProjectsUpdateSuccess($data) {
public function testProjectsUpdateSuccess($data)
{
$response = $this->client->call(Client::METHOD_POST, '/projects', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
@ -100,4 +102,4 @@ class ConsoleProjectsTest extends BaseConsole
$this->assertEquals('New Demo Project Description', $response['body']['description']);
$this->assertEquals('https://appwrite.io/new', $response['body']['url']);
}
}
}

View file

@ -95,4 +95,4 @@ class ConsoleTest extends BaseConsole
$this->assertEquals('401', $response['body']['code']);
}
}
}

View file

@ -79,8 +79,8 @@ class ProjectDatabaseTest extends BaseProjects
/**
* @depends testRegisterSuccess
*/
public function testCollectionCreateSuccess($data) {
public function testCollectionCreateSuccess($data)
{
$actors = $this->client->call(Client::METHOD_POST, '/database', [
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectUid'],
@ -170,7 +170,8 @@ class ProjectDatabaseTest extends BaseProjects
/**
* @depends testCollectionCreateSuccess
*/
public function testDocumentCreateSuccess($data) {
public function testDocumentCreateSuccess($data)
{
$document1 = $this->client->call(Client::METHOD_POST, '/database/' . $data['moviesId'] . '/documents', [
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectUid'],
@ -313,7 +314,8 @@ class ProjectDatabaseTest extends BaseProjects
/**
* @depends testDocumentCreateSuccess
*/
public function testDocumentsListSuccessOrderAndCasting($data) {
public function testDocumentsListSuccessOrderAndCasting($data)
{
$documents = $this->client->call(Client::METHOD_GET, '/database/' . $data['moviesId'] . '/documents', [
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectUid'],
@ -348,7 +350,8 @@ class ProjectDatabaseTest extends BaseProjects
/**
* @depends testDocumentCreateSuccess
*/
public function testDocumentsListSuccessLimitAndOffset($data) {
public function testDocumentsListSuccessLimitAndOffset($data)
{
$documents = $this->client->call(Client::METHOD_GET, '/database/' . $data['moviesId'] . '/documents', [
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectUid'],
@ -383,7 +386,8 @@ class ProjectDatabaseTest extends BaseProjects
/**
* @depends testDocumentCreateSuccess
*/
public function testDocumentsListSuccessFirstAndLast($data) {
public function testDocumentsListSuccessFirstAndLast($data)
{
$documents = $this->client->call(Client::METHOD_GET, '/database/' . $data['moviesId'] . '/documents', [
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectUid'],
@ -417,7 +421,8 @@ class ProjectDatabaseTest extends BaseProjects
/**
* @depends testDocumentCreateSuccess
*/
public function testDocumentsListSuccessSerach($data) {
public function testDocumentsListSuccessSerach($data)
{
$documents = $this->client->call(Client::METHOD_GET, '/database/' . $data['moviesId'] . '/documents', [
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectUid'],
@ -456,7 +461,8 @@ class ProjectDatabaseTest extends BaseProjects
/**
* @depends testDocumentCreateSuccess
*/
public function testDocumentsListSuccessFilters($data) {
public function testDocumentsListSuccessFilters($data)
{
$documents = $this->client->call(Client::METHOD_GET, '/database/' . $data['moviesId'] . '/documents', [
'content-type' => 'application/json',
'x-appwrite-project' => $data['projectUid'],
@ -498,4 +504,4 @@ class ProjectDatabaseTest extends BaseProjects
$this->assertEquals('Spider-Man: Far From Home', $documents['body']['documents'][0]['name']);
$this->assertEquals('Spider-Man: Homecoming', $documents['body']['documents'][1]['name']);
}
}
}