diff --git a/.gitignore b/.gitignore index f64ffdbba..0494e8fba 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ /storage/uploads/ /tests/resources/storage/ /.idea/ -.DS_Store \ No newline at end of file +.DS_Store +.php_cs.cache \ No newline at end of file diff --git a/CHANGES b/CHANGES deleted file mode 100644 index d4a938244..000000000 --- a/CHANGES +++ /dev/null @@ -1,5 +0,0 @@ -Version 1.0.0 (NOT-RELEASED) -------------- - -Version 0.1.0 (PRE-RELEASE) -------------- diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 000000000..aee5e0eba --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,23 @@ +# Version 0.2.0 (PRE-RELEASE) + +## Features + +* Added option to limit access to the Appwrite console +* Added option to disable abuse check and rate limits +* Added input field with the server API endpoint for easy access +* Added new OAuth providers for Google and Gitlab +* Added 8 new locales for locale service and email templates (no, pt-br, es, ua, ru, id, fi, cat) +* Improved test coverage for the project and synced DEV & CI environments settings + +## Bug Fixes + +* Fixed bug not allowing to update OAuth providers settings +* Fixed some broken API examples in docs +* Fixed bug that caused the Appwrite container to change DB directory file permissions. + +## Breaking Changes + +* Changed auth service 'redirect' param to 'confirm' for better clarity +* Updated all SDKs to sync with API changes + +# Version 0.1.15 (NOT-RELEASED) \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c1ac1ca49..f3685f9f5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,7 +36,7 @@ Appwrite uses PHPs Composer for managing dependencies on the server-side and JS Appwrite is following the PHP-FIG standards. Currently, we are using both PSR-0 and PSR-4 for coding standards and autoloading standards. Soon we will also review the project for support with PSR-12 (Extended Coding Style). -We use prettier for our JS coding standards and for auto-formmating our code. +We use prettier for our JS coding standards and for auto-formatting our code. ## Scalability, Speed and Performance @@ -83,9 +83,9 @@ Adding a new dependency should have vital value on the product with minimum poss ## Introducing New Features -We whould 💖 you to contribute to Appwrite, but we whould also like to make sure Appwrite is as great as possible and loyal to its vision and mission statement 🙏. +We would 💖 you to contribute to Appwrite, but we would also like to make sure Appwrite is as great as possible and loyal to its vision and mission statement 🙏. -For us to find the right balance, please open an issue explaining your ideas before intoducing a new pull requests. +For us to find the right balance, please open an issue explaining your ideas before introducing a new pull requests. This will allow the Appwrite community to have sufficient discussion about the new feature value and how it fits in the product roadmap and vision. @@ -121,6 +121,6 @@ Before running the command make sure you have proper write permissions to Appwri ## Tutorials -From time to time our team will add tutorials that will help contributers find there way in the Appwrite source code. Below is a list of currently available tutorials: +From time to time our team will add tutorials that will help contributors find there way in the Appwrite source code. Below is a list of currently available tutorials: * [Adding Support for a New OAuth Provider](./docs/AddOAuthProvider.md) \ No newline at end of file diff --git a/README.md b/README.md index 2195cf117..b26d78f2d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Appwrite Logo

- Simple Backend Server for your [Vue / Angular / React / iOS / Android / Flutter / *ANY*] Frontend App + Simple Backend Server for your [Vue / Angular / React / iOS / Android / Flutter / *ANY OTHER*] Frontend App

@@ -16,7 +16,7 @@ Appwrite is a simple self-hosted backend server for web and mobile developers with a shiny dashboard and a very easy to use REST API. -Appwrite API services aims to make developers life a lot easier by hiding the complexity of common and repetitve software development tasks. +Appwrite API services aims to make developers life a lot easier by hiding the complexity of common and repetitive software development tasks. Using Appwrite you can easily manage user authentication with multiple sign-in methods, database for storing and querying user and teams data, storage and file management, image manipulation and cropping, scheduled cron tasks and many other features to help you get more results in faster times and with a lot less code. @@ -37,9 +37,9 @@ curl -o docker-compose.yml https://appwrite.io/docker-compose.yml?port=80 && \ docker-compose up -d --remove-orphans ``` -Once the Docker installation completes, go to http://localhost to access the Appwrite console from your browser. Please notice that on non-linux native hosts the server might take a few minutes to start after installation completes. +Once the Docker installation is completed, go to http://localhost to access the Appwrite console from your browser. Please notice that on non-linux native hosts the server might take a few minutes to start after the completion of the installation. -For advanced, production and custon installation check out our Docker [enviornemnt variables](/docs/EnviornementVariables.md) docs. +For advanced, production and custom installation, check out our Docker [environment variables](/docs/EnviornementVariables.md) docs. ### Changing Port Number @@ -50,9 +50,9 @@ In case your port 80 is already taken, change the port number in the command abo Getting started with Appwrite is as easy as creating a new project, choosing your platform and integrating its SDK in your code. You can easily get started with your platform of choice by reading one of our getting started tutorials. * [Getting Started for Web](https://appwrite.io/docs/getting-started-for-web) +* [Getting Started for Server](https://appwrite.io/docs/getting-started-for-server) * Getting Started for Android (soon...) * Getting Started for iOS (soon...) -* [Getting Started for Server](https://appwrite.io/docs/getting-started-for-server) ### Services @@ -69,7 +69,7 @@ For the complete API documentation, visit [https://appwrite.io/docs](https://app ### SDKs -Currently we are supporting a few SDK libraries and we are constantly working on adding new ones. +Currently, we are supporting only a few SDK libraries and are constantly working on including new ones. Below is a list of currently supported platforms and languages. If you wish to help us add support to your platform of choice you can go over to our [SDK Generator](https://github.com/appwrite/sdk-generator) project and view our contribution guide. @@ -82,7 +82,7 @@ Below is a list of currently supported platforms and languages. If you wish to h ## Security -For security issues, please email [security@appwrite.io](mailto:security@appwrite.io) instead of posting a public issue in GitHub. +For security issues, kindly email us [security@appwrite.io](mailto:security@appwrite.io) instead of posting a public issue in GitHub. ## Follow Us @@ -98,8 +98,16 @@ We really ❤️ pull requests! If you wish to help, you can learn more about ho Created by [Eldad Fux](https://twitter.com/eldadfux) with the amazing help of our **amazing contributors:** -* 🇺🇸Justin Dorfman ([Github](https://github.com/jdorfman), [Twitter](https://twitter.com/jdorfman)) -* 🇺🇳0xflotus ([Github](https://github.com/0xflotus)) -* 🇳🇴Petter Charles Redfern ([Github](https://github.com/Chaaarles)) -* 🇧🇷Jessé Souza ([Github](https://github.com/jessescn)) -* 🇪🇸Esther Álvarez Feijoo ([Github](https://github.com/EstherAF)) \ No newline at end of file +* 🇺🇸 Justin Dorfman ([Github](https://github.com/jdorfman), [Twitter](https://twitter.com/jdorfman)) +* 🇺🇳 0xflotus ([Github](https://github.com/0xflotus)) +* 🇳🇴 Petter Charles Redfern ([Github](https://github.com/Chaaarles)) +* 🇧🇷 Jessé Souza ([Github](https://github.com/jessescn)) +* 🇪🇸 Esther Álvarez Feijoo ([Github](https://github.com/EstherAF)) +* 🇮🇳 Christy Jacob ([Github](https://github.com/christyjacob4), [Linkedin](https://www.linkedin.com/in/christyjacob4/)) +* 🇺🇦 Dmitriy Danilov ([Github](https://github.com/daniloff200), [Twitter](https://twitter.com/daniloff200)) +* 🇮🇩 Zeet ([Github](https://github.com/Kiy4h)) +* 🇫🇮 Pessi Päivärinne ([Github](https://github.com/pessip)) +* 🇺🇳 Sergi Vos ([Github](https://github.com/sergivb01), [Twitter](https://twitter.com/sergivb01), [Linkedin](https://www.linkedin.com/in/sergivb01/)) +* 🇮🇱 Tomer Cohen ([Github](https://github.com/tomer), [Twitter](https://twitter.com/tomer)) +* 🇬🇷 Panagiotis Skarlas ([Github](https://github.com/1qk1), [Twitter](https://twitter.com/qktweets)) +* 🇷🇺 Alexey Pyltsyn ([Github](https://github.com/lex111)) diff --git a/app/app.php b/app/app.php index 7acc18e5a..4e4af3987 100644 --- a/app/app.php +++ b/app/app.php @@ -1,7 +1,7 @@ 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', ''); - $origin = $request->getServer('HTTP_ORIGIN', parse_url($referrer, PHP_URL_SCHEME) . '://' . parse_url($referrer, PHP_URL_HOST)); + $referrer = $request->getServer('HTTP_REFERER', ''); + $origin = $request->getServer('HTTP_ORIGIN', parse_url($referrer, PHP_URL_SCHEME).'://'.parse_url($referrer, PHP_URL_HOST)); $refDomain = (in_array($origin, $clients)) ? $origin : 'http://localhost'; - /** + /* * Security Headers * * As recommended at: @@ -67,7 +68,7 @@ $utopia->init(function() use ($utopia, $request, $response, $register, &$user, $ */ $response ->addHeader('Server', 'Appwrite') - ->addHeader('X-XSS-Protection', '1; mode=block; report=/v1/xss?url=' . urlencode($request->getServer('REQUEST_URI'))) + ->addHeader('X-XSS-Protection', '1; mode=block; report=/v1/xss?url='.urlencode($request->getServer('REQUEST_URI'))) //->addHeader('X-Frame-Options', ($refDomain == 'http://localhost') ? 'SAMEORIGIN' : 'ALLOW-FROM ' . $refDomain) ->addHeader('X-Content-Type-Options', 'nosniff') ->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE') @@ -76,19 +77,19 @@ $utopia->init(function() use ($utopia, $request, $response, $register, &$user, $ ->addHeader('Access-Control-Allow-Credentials', 'true') ; - /** + /* * Validate Client Domain - Check to avoid CSRF attack * Adding appwrite api domains to allow XDOMAIN communication */ $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); + throw new Exception('Access from this client host is forbidden. '.$hostValidator->getDescription(), 403); } - /** + /* * ACL Check */ $role = ($user->isEmpty()) ? Auth::USER_ROLE_GUEST : Auth::USER_ROLE_MEMBER; @@ -96,7 +97,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': @@ -112,57 +113,57 @@ $utopia->init(function() use ($utopia, $request, $response, $register, &$user, $ } } - $scope = $route->getLabel('scope', 'none'); // Allowed scope for chosen route - $scopes = $roles[$role]['scopes']; // Allowed scopes for user role + $scope = $route->getLabel('scope', 'none'); // Allowed scope for chosen route + $scopes = $roles[$role]['scopes']; // Allowed scopes for user role // Check if given key match project API keys $key = $project->search('secret', $request->getHeader('X-Appwrite-Key', ''), $project->getAttribute('keys', [])); - /** + /* * 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, - 'email' => 'app.' . $project->getUid() . '@service.' . $domain, - 'password' => '', - 'name' => $project->getAttribute('name', 'Untitled'), + '$uid' => 0, + 'status' => Auth::USER_STATUS_ACTIVATED, + 'email' => 'app.'.$project->getUid().'@service.'.$domain, + 'password' => '', + 'name' => $project->getAttribute('name', 'Untitled'), ]); - $role = Auth::USER_ROLE_APP; + $role = Auth::USER_ROLE_APP; $scopes = array_merge($roles[$role]['scopes'], $key->getAttribute('scopes', [])); Authorization::disable(); // Cancel security segmentation for API keys. } - Authorization::setRole('user:' . $user->getUid()); - Authorization::setRole('role:' . $role); + Authorization::setRole('user:'.$user->getUid()); + Authorization::setRole('role:'.$role); array_map(function ($node) { - if(isset($node['teamId']) && isset($node['roles'])) { - Authorization::setRole('team:' . $node['teamId']); + if (isset($node['teamId']) && isset($node['roles'])) { + Authorization::setRole('team:'.$node['teamId']); foreach ($node['roles'] as $nodeRole) { // Set all team roles - Authorization::setRole('team:' . $node['teamId'] . '/' . $nodeRole); + Authorization::setRole('team:'.$node['teamId'].'/'.$nodeRole); } } }, $user->getAttribute('memberships', [])); - if(!in_array($scope, $scopes)) { - throw new Exception($user->getAttribute('email', 'Guest') . ' (role: ' . strtolower($roles[$role]['label']) . ') missing scope (' . $scope . ')', 401); + 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); } - /** + /* * Background Jobs */ $webhook @@ -183,56 +184,58 @@ $utopia->init(function() use ($utopia, $request, $response, $register, &$user, $ $usage ->setParam('projectId', $project->getUid()) - ->setParam('url', $request->getServer('HTTP_HOST', '') . $request->getServer('REQUEST_URI', '')) + ->setParam('url', $request->getServer('HTTP_HOST', '').$request->getServer('REQUEST_URI', '')) ->setParam('method', $request->getServer('REQUEST_METHOD', 'UNKNOWN')) ->setParam('request', 0) ->setParam('response', 0) ->setParam('storage', 0) ; - /** + /* * 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->setNamespace('app_' . $project->getUid()); + $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()) ->setParam('{userAgent}', $request->getServer('HTTP_USER_AGENT', '')) ->setParam('{ip}', $request->getIP()) - ->setParam('{url}', $request->getServer('HTTP_HOST', '') . $route->getURL()) + ->setParam('{url}', $request->getServer('HTTP_HOST', '').$route->getURL()) ; //TODO make sure we get array here - foreach($request->getParams() as $key => $value) { // Set request params as potential abuse keys - $timeLimit->setParam('{param-' . $key . '}', (is_array($value)) ? json_encode($value) : $value); + 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()) ->addHeader('X-RateLimit-Reset', $timeLimit->time() + $route->getLabel('abuse-time', 3600)) ; } - - 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); } }); $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 +246,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 @@ -252,11 +255,10 @@ $utopia->options(function() use ($request, $response, $domain, $project) { ->addHeader('Access-Control-Allow-Origin', $origin) ->addHeader('Access-Control-Allow-Credentials', 'true') ->send(); - ; }); -$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 @@ -264,27 +266,27 @@ $utopia->error(function($error /* @var $error Exception */) use ($request, $resp case 404: // Error allowed publicly case 412: // Error allowed publicly case 429: // Error allowed publicly - $code = $error->getCode(); - $message = $error->getMessage(); + $code = $error->getCode(); + $message = $error->getMessage(); break; default: - $code = 500; // All other errors get the generic 500 server error status code - $message = 'Server Error'; + $code = 500; // All other errors get the generic 500 server error status code + $message = 'Server Error'; } $_SERVER = []; // Reset before reporting to error log to avoid keys being compromised $output = ((App::ENV_TYPE_DEVELOPMENT == $env)) ? [ - 'message' => $error->getMessage(), - 'code' => $error->getCode(), - 'file' => $error->getFile(), - 'line' => $error->getLine(), - 'trace' => $error->getTrace(), - 'version' => $version, + 'message' => $error->getMessage(), + 'code' => $error->getCode(), + 'file' => $error->getFile(), + 'line' => $error->getLine(), + 'trace' => $error->getTrace(), + 'version' => $version, ] : [ 'message' => $message, - 'code' => $code, - 'version' => $version, + 'code' => $code, + 'version' => $version, ]; $response @@ -294,12 +296,12 @@ $utopia->error(function($error /* @var $error Exception */) use ($request, $resp ->setStatusCode($code) ; - $route = $utopia->match($request); - $template = ($route) ? $route->getLabel('error', null): null; + $route = $utopia->match($request); + $template = ($route) ? $route->getLabel('error', null) : null; - if($template) { - $layout = new View(__DIR__ . '/views/layouts/default.phtml'); - $comp = new View($template); + if ($template) { + $layout = new View(__DIR__.'/views/layouts/default.phtml'); + $comp = new View($template); $comp ->setParam('projectName', $project->getAttribute('name')) @@ -309,7 +311,7 @@ $utopia->error(function($error /* @var $error Exception */) use ($request, $resp ; $layout - ->setParam('title', $project->getAttribute('name') . ' - Error') + ->setParam('title', $project->getAttribute('name').' - Error') ->setParam('description', 'No Description') ->setParam('body', $comp) ->setParam('version', $version) @@ -329,8 +331,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, @@ -344,9 +345,9 @@ $utopia->get('/manifest.json') [ 'src' => 'images/favicon.png', 'sizes' => '256x256', - 'type' => 'image/png' - ] - ] + 'type' => 'image/png', + ], + ], ]); } ); @@ -356,12 +357,11 @@ $utopia->get('/robots.txt') ->label('scope', 'public') ->label('docs', false) ->action( - function() use ($response) { - - $response->text("# robotstxt.org/ + function () use ($response) { + $response->text('# robotstxt.org/ User-agent: * -"); +'); } ); @@ -370,16 +370,15 @@ $utopia->get('/humans.txt') ->label('scope', 'public') ->label('docs', false) ->action( - function() use ($response) { - - $response->text("# humanstxt.org/ + function () use ($response) { + $response->text('# humanstxt.org/ # The humans responsible & technology colophon # TEAM -- -- # THANKS - "); + '); } ); @@ -387,17 +386,17 @@ $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, - 'environment' => $env, - 'time' => date('Y-m-d H:i:s', time()), - 'user' => [ + 'name' => 'API', + 'version' => $version, + 'environment' => $env, + 'time' => date('Y-m-d H:i:s', time()), + 'user' => [ 'id' => $user->getUid(), 'name' => $user->getAttribute('name', ''), ], - 'project' => [ + 'project' => [ 'id' => $project->getUid(), 'name' => $project->getAttribute('name', ''), ], @@ -410,7 +409,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,8 +418,8 @@ $utopia->get('/v1/proxy') ->label('scope', 'public') ->label('docs', false) ->action( - function() use ($response, $console, $clients) { - $view = new View(__DIR__ . '/views/proxy.phtml'); + function () use ($response, $console, $clients) { + $view = new View(__DIR__.'/views/proxy.phtml'); $view ->setParam('routes', '') ->setParam('clients', array_merge($clients, $console->getAttribute('clients', []))) @@ -436,26 +435,32 @@ $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) { $match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match); } + 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']) { + foreach ($services as $service) { /* @noinspection PhpIncludeInspection */ + if (!$service['sdk']) { continue; } @@ -468,7 +473,7 @@ $utopia->get('/v1/open-api-2.json') 'server' => ['Project' => [], 'Key' => []], ]; - /** + /* * Specifications (v3.0.0): * https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md */ @@ -537,30 +542,23 @@ $utopia->get('/v1/open-api-2.json') ], ], ], - 'Pets' => - array ( + 'Pets' => array( 'type' => 'array', - 'items' => - array ( + 'items' => array( '$ref' => '#/definitions/Pet', ), ), - 'Error' => - array ( - 'required' => - array ( + 'Error' => array( + 'required' => array( 0 => 'code', 1 => 'message', ), - 'properties' => - array ( - 'code' => - array ( + 'properties' => array( + 'code' => array( 'type' => 'integer', 'format' => 'int32', ), - 'message' => - array ( + 'message' => array( 'type' => 'string', ), ), @@ -568,26 +566,26 @@ $utopia->get('/v1/open-api-2.json') ], 'externalDocs' => [ 'description' => 'Full API docs, specs and tutorials', - 'url' => $request->getServer('REQUEST_SCHEME', 'https') . '://' . $domain . '/docs' - ] + 'url' => $request->getServer('REQUEST_SCHEME', 'https').'://'.$domain.'/docs', + ], ]; 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; } - $url = str_replace('/v1', '', $route->getURL()); - $scope = $route->getLabel('scope', ''); - $hide = $route->getLabel('sdk.hide', false); - $consumes = []; + $url = str_replace('/v1', '', $route->getURL()); + $scope = $route->getLabel('scope', ''); + $hide = $route->getLabel('sdk.hide', false); + $consumes = []; - if($hide) { + if ($hide) { continue; } @@ -601,22 +599,22 @@ $utopia->get('/v1/open-api-2.json') 200 => [ 'description' => 'An paged array of pets', 'schema' => [ - '$ref' => '#/definitions/Pet' + '$ref' => '#/definitions/Pet', ], ], ], ]; - if($extensions) { + if ($extensions) { $temp['extensions'] = [ 'weight' => $route->getOrder(), 'cookies' => $route->getLabel('sdk.cookies', false), 'location' => $route->getLabel('sdk.location', false), - 'demo' => 'docs/examples/' . fromCamelCaseToDash($route->getLabel('sdk.namespace', 'default')) . '/' . fromCamelCaseToDash($temp['operationId']) . '.md', + 'demo' => 'docs/examples/'.fromCamelCaseToDash($route->getLabel('sdk.namespace', 'default')).'/'.fromCamelCaseToDash($temp['operationId']).'.md', ]; } - if((!empty($scope) && 'public' != $scope)) { + if ((!empty($scope) && 'public' != $scope)) { $temp['security'][] = $route->getLabel('sdk.security', $security[$platform]); } @@ -628,8 +626,8 @@ $utopia->get('/v1/open-api-2.json') 'properties' => [], ], 'required' => [], - ] - ] + ], + ], ]; foreach ($route->getParams() as $name => $param) { @@ -644,11 +642,11 @@ $utopia->get('/v1/open-api-2.json') switch ((!empty($validator)) ? get_class($validator) : '') { case 'Utopia\Validator\Text': $node['type'] = 'string'; - $node['x-example'] = '[' . strtoupper(fromCamelCase($node['name'])) . ']'; + $node['x-example'] = '['.strtoupper(fromCamelCase($node['name'])).']'; break; case 'Database\Validator\UID': $node['type'] = 'string'; - $node['x-example'] = '[' . strtoupper(fromCamelCase($node['name'])) . ']'; + $node['x-example'] = '['.strtoupper(fromCamelCase($node['name'])).']'; break; case 'Utopia\Validator\Email': $node['type'] = 'string'; @@ -675,7 +673,7 @@ $utopia->get('/v1/open-api-2.json') $node['type'] = 'array'; $node['collectionFormat'] = 'multi'; $node['items'] = [ - 'type' => 'string' + 'type' => 'string', ]; break; case 'Auth\Validator\Password': @@ -709,29 +707,27 @@ $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 + 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; } } - $url = str_replace(':' . $name, '{' . $name . '}', $url); + $url = str_replace(':'.$name, '{'.$name.'}', $url); } $temp['consumes'] = $consumes; @@ -752,21 +748,20 @@ $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 { + $name = APP_NAME.' '.ucfirst($services[$service]['name']); +} else { /** @noinspection PhpIncludeInspection */ include_once $services['/']['controller']; } if (extension_loaded('newrelic')) { - $route = $utopia->match($request); - $url = (!empty($route)) ? $route->getURL() : '/error'; + $route = $utopia->match($request); + $url = (!empty($route)) ? $route->getURL() : '/error'; newrelic_set_appname($name); - newrelic_name_transaction($request->getServer('REQUEST_METHOD', 'UNKNOWN') . ': ' . $url); + newrelic_name_transaction($request->getServer('REQUEST_METHOD', 'UNKNOWN').': '.$url); } -$utopia->run($request, $response); \ No newline at end of file +$utopia->run($request, $response); diff --git a/app/config/collections.php b/app/config/collections.php index ac62c1882..524eaaa80 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -38,13 +38,13 @@ $collections = [ '$collection' => Database::SYSTEM_COLLECTION_PLATFORMS, 'name' => 'Localhost (SSL)', 'type' => 'web', - 'url' => 'https://' . $request->getServer('HTTP_HOST'), + 'url' => 'https://'.$request->getServer('HTTP_HOST'), ], [ '$collection' => Database::SYSTEM_COLLECTION_PLATFORMS, 'name' => 'Localhost (Non-SSL)', 'type' => 'web', - 'url' => 'http://' . $request->getServer('HTTP_HOST'), + 'url' => 'http://'.$request->getServer('HTTP_HOST'), ], ], 'legalName' => '', @@ -1076,7 +1076,7 @@ foreach ($providers as $key => $provider) { $collections[Database::SYSTEM_COLLECTION_PROJECTS]['rules'][] = [ '$collection' => Database::SYSTEM_COLLECTION_RULES, 'label' => 'OAuth '.ucfirst($key).' ID', - 'key' => 'usersOauth'.ucfirst($key) . 'Appid', + 'key' => 'usersOauth'.ucfirst($key).'Appid', 'type' => 'text', 'default' => '', 'required' => false, diff --git a/app/config/locale/es.countries.php b/app/config/locale/es.countries.php index b8fec0848..a0c11ae5c 100644 --- a/app/config/locale/es.countries.php +++ b/app/config/locale/es.countries.php @@ -1,4 +1,5 @@ 'Afganistán', 'AO' => 'Angola', @@ -194,4 +195,4 @@ return [ 'ZA' => 'Sudáfrica', 'ZM' => 'Zambia', 'ZW' => 'Zimbabue', -]; \ No newline at end of file +]; diff --git a/app/config/locale/gr.continents.php b/app/config/locale/gr.continents.php new file mode 100644 index 000000000..4655baca9 --- /dev/null +++ b/app/config/locale/gr.continents.php @@ -0,0 +1,11 @@ + 'Αφρική', + 'AN' => 'Ανταρκτική', + 'AS' => 'Ασία', + 'EU' => 'Ευρώπη', + 'NA' => 'Βόρεια Αμερική', + 'OC' => 'Ωκεανία', + 'SA' => 'Νότια Αμερική', +]; diff --git a/app/config/locale/gr.countries.php b/app/config/locale/gr.countries.php new file mode 100644 index 000000000..68a3aa765 --- /dev/null +++ b/app/config/locale/gr.countries.php @@ -0,0 +1,198 @@ + 'Αφγανιστάν', + 'AO' => 'Ανγκόλα', + 'AL' => 'Αλβανία', + 'AD' => 'Ανδόρα', + 'AE' => 'Ηνωμένα Αραβικά Εμιράτα', + 'AR' => 'Αργεντινή', + 'AM' => 'Αρμενία', + 'AG' => 'Αντίγκουα και Μπαρμπούντα', + 'AU' => 'Αυστραλία', + 'AT' => 'Αυστρία', + 'AZ' => 'Αζερμπαϊτζάν', + 'BI' => 'Μπουρούντι', + 'BE' => 'Βέλγιο', + 'BJ' => 'Μπενίν', + 'BF' => 'Μπουρκίνα Φάσο', + 'BD' => 'Μπανγκλαντές', + 'BG' => 'Βουλγαρία', + 'BH' => 'Μπαχρέιν', + 'BS' => 'Μπαχάμες', + 'BA' => 'Βοσνία και Ερζεγοβίνη', + 'BY' => 'Λευκορωσία', + 'BZ' => 'Μπελίζε', + 'BO' => 'Βολιβία', + 'BR' => 'Βραζιλία', + 'BB' => 'Μπαρμπάντος', + 'BN' => 'Μπρουνέι', + 'BT' => 'Μπουτάν', + 'BW' => 'Μποτσουάνα', + 'CF' => 'Κεντροαφρικανική Δημοκρατία', + 'CA' => 'Καναδάς', + 'CH' => 'Ελβετία', + 'CL' => 'Χιλή', + 'CN' => 'Κίνα', + 'CI' => 'Ακτή Ελεφαντοστού', + 'CM' => 'Καμερούν', + 'CD' => 'Λαϊκή Δημοκρατία του Κονγκό', + 'CG' => 'Δημοκρατία του Κονγκό', + 'CO' => 'Κολομβία', + 'KM' => 'Κομόρες', + 'CV' => 'Πράσινο Ακρωτήρι', + 'CR' => 'Κόστα Ρίκα', + 'CU' => 'Κούβα', + 'CY' => 'Κύπρος', + 'CZ' => 'Τσεχία', + 'DE' => 'Γερμανία', + 'DJ' => 'Τζιμπουτί', + 'DM' => 'Ντομίνικα', + 'DK' => 'Δανία', + 'DO' => 'Δομινικανή Δημοκρατία', + 'DZ' => 'Αλγερία', + 'EC' => 'Εκουαδόρ', + 'EG' => 'Αίγυπτος', + 'ER' => 'Ερυθραία', + 'ES' => 'Ισπανία', + 'EE' => 'Εσθονία', + 'ET' => 'Αιθιοπία', + 'FI' => 'Φινλανδία', + 'FJ' => 'Φίτζι', + 'FR' => 'Γαλλία', + 'FM' => 'Μικρονησία', + 'GA' => 'Γκαμπόν', + 'GB' => 'Ηνωμένο Βασίλειο', + 'GE' => 'Γεωργία', + 'GH' => 'Γκάνα', + 'GN' => 'Γουινέα', + 'GM' => 'Γκάμπια', + 'GW' => 'Γουινέα-Μπισσάου', + 'GQ' => 'Ισημερινή Γουινέα', + 'GR' => 'Ελλάδα', + 'GD' => 'Γρενάδα', + 'GT' => 'Γουατεμάλα', + 'GY' => 'Γουιάνα', + 'HN' => 'Ονδούρα', + 'HR' => 'Κροατία', + 'HT' => 'Αϊτή', + 'HU' => 'Ουγγαρία', + 'ID' => 'Ινδονησία', + 'IN' => 'Ινδία', + 'IE' => 'Ιρλανδία', + 'IR' => 'Ιράν', + 'IQ' => 'Ιράκ', + 'IS' => 'Ισλανδία', + 'IL' => 'Ισραήλ', + 'IT' => 'Ιταλία', + 'JM' => 'Τζαμάικα', + 'JO' => 'Ιορδανία', + 'JP' => 'Ιαπωνία', + 'KZ' => 'Καζακστάν', + 'KE' => 'Κένυα', + 'KG' => 'Κιργιζιστάν', + 'KH' => 'Καμπότζη', + 'KI' => 'Κιριμπάτι', + 'KN' => 'Άγιος Χριστόφορος και Νέβις', + 'KR' => 'Νότια Κορέα', + 'KW' => 'Κουβέιτ', + 'LA' => 'Λάος', + 'LB' => 'Λίβανος', + 'LR' => 'Λιβερία', + 'LY' => 'Λιβύη', + 'LC' => 'Αγία Λουδία', + 'LI' => 'Λιχτενστάιν', + 'LK' => 'Σρι Λάνκα', + 'LS' => 'Λεσότο', + 'LT' => 'Λιθουανία', + 'LU' => 'Λουξεμβούργο', + 'LV' => 'Λετονία', + 'MA' => 'Μαρόκο', + 'MC' => 'Μονακό', + 'MD' => 'Μολδαβία', + 'MG' => 'Μαδαγασκάρη', + 'MV' => 'Μαλδίβες', + 'MX' => 'Μεξικό', + 'MH' => 'Νήσοι Μάρσαλ', + 'MK' => 'Μακεδονία', + 'ML' => 'Μάλι', + 'MT' => 'Μάλτα', + 'MM' => 'Μυανμάρ', + 'ME' => 'Μαυροβούνιο', + 'MN' => 'Μογγολία', + 'MZ' => 'Μοζαμβίκη', + 'MR' => 'Μαυριτανία', + 'MU' => 'Μαυρίκιος', + 'MW' => 'Μαλάουι', + 'MY' => 'Μαλαισία', + 'NA' => 'Ναμίμπια', + 'NE' => 'Νίγηρα', + 'NG' => 'Νιγηρία', + 'NI' => 'Νικαράγουα', + 'NL' => 'Ολλανδία', + 'NO' => 'Νορβηγία', + 'NP' => 'Νεπάλ', + 'NR' => 'Ναουρού', + 'NZ' => 'Νέα Ζηλανδία', + 'OM' => 'Ομάν', + 'PK' => 'Πακιστάν', + 'PA' => 'Παναμάς', + 'PE' => 'Περού', + 'PH' => 'Φιλιππίνες', + 'PW' => 'Palau', + 'PG' => 'Παπούα Νέα Γουινέα', + 'PL' => 'Πολωνία', + 'KP' => 'Βόρεια Κορέα', + 'PT' => 'Πορτογαλία', + 'PY' => 'Παραγουάη', + 'QA' => 'Κατάρ', + 'RO' => 'Ρουμανία', + 'RU' => 'Ρωσία', + 'RW' => 'Ρουάντα', + 'SA' => 'Σαουδική Αραβία', + 'SD' => 'Σουδάν', + 'SN' => 'Σενεγάλη', + 'SG' => 'Σιγκαπούρη', + 'SB' => 'Νησιά Σολομώντα', + 'SL' => 'Σιέρα Λεόνε', + 'SV' => 'Ελ Σαλβαδόρ', + 'SM' => 'Σαν Μαρίνο', + 'SO' => 'Σομαλία', + 'RS' => 'Σερβία', + 'SS' => 'Νότια Σουδάν', + 'ST' => 'Σάο Τομέ και Πρινσίπε', + 'SR' => 'Σουρινάμ', + 'SK' => 'Σλοβακία', + 'SI' => 'Σλοβενία', + 'SE' => 'Σουηδία', + 'SZ' => 'Σουαζιλάνδη', + 'SC' => 'Σεϋχέλλες', + 'SY' => 'Συρία', + 'TD' => 'Τσαντ', + 'TG' => 'Τόγκο', + 'TH' => 'Ταϊλάνδη', + 'TJ' => 'Τατζικιστάν', + 'TM' => 'Τουρκμενιστάν', + 'TL' => 'Ανατολικό Τιμόρ', + 'TO' => 'Τόνγκα', + 'TT' => 'Τρινιντάντ και Τομπάγκο', + 'TN' => 'Τυνησία', + 'TR' => 'Τουρκία', + 'TV' => 'Τουβαλού', + 'TZ' => 'Τανζανία', + 'UG' => 'Ουγκάντα', + 'UA' => 'Ουκρανία', + 'UY' => 'Ουρουγουάη', + 'US' => 'Ηνωμένες Πολιτείες', + 'UZ' => 'Ουζμπεκιστάν', + 'VA' => 'Βατικανό', + 'VC' => 'Άγιος Βικέντιος και Γρεναδίνες', + 'VE' => 'Βενεζουέλα', + 'VN' => 'Βιετνάμ', + 'VU' => 'Βανουάτου', + 'WS' => 'Σαμόα', + 'YE' => 'Υεμένη', + 'ZA' => 'Νότια Αφρική', + 'ZM' => 'Ζάμπια', + 'ZW' => 'Ζιμπάμπουε', +]; diff --git a/app/config/locale/gr.php b/app/config/locale/gr.php new file mode 100644 index 000000000..95f24f938 --- /dev/null +++ b/app/config/locale/gr.php @@ -0,0 +1,21 @@ + '"The art of being wise is the art of knowing what to overlook."', // This is the line printed in the homepage and console 'view-source' + 'settings.locale' => 'gr', + 'settings.direction' => 'ltr', + + // Service - Users + 'auth.emails.team' => 'Ομάδα %s', + 'auth.emails.confirm.title' => 'Επιβεβαίωση Λογαριασμού', + 'auth.emails.confirm.body' => 'gr.email.auth.confirm.tpl', + 'auth.emails.recovery.title' => 'Επαναφορά Κωδικού Πρόσβασης', + 'auth.emails.recovery.body' => 'gr.email.auth.recovery.tpl', + 'auth.emails.invitation.title' => 'Πρόσκληση στην ομάδα %s στο %s', + 'auth.emails.invitation.body' => 'gr.email.auth.invitation.tpl', + + 'locale.country.unknown' => 'Άγνωστο', + + 'countries' => include 'gr.countries.php', + 'continents' => include 'gr.continents.php', +]; diff --git a/app/config/locale/he.countries.php b/app/config/locale/he.countries.php index 370dfcd17..3d0d29f4a 100644 --- a/app/config/locale/he.countries.php +++ b/app/config/locale/he.countries.php @@ -7,7 +7,7 @@ return [ 'AU' => 'אוסטרליה', 'UA' => 'אוקראינה', 'UY' => 'אורוגוואי', - 'AZ' => 'אזרבייג\'ן', + 'AZ' => 'אזרבייג׳ן', 'AE' => 'איחוד האמירויות הערביות', 'IT' => 'איטליה', 'BS' => 'איי בהאמה', diff --git a/app/config/locale/he.php b/app/config/locale/he.php index 41ce63ea7..14a3e2cc2 100644 --- a/app/config/locale/he.php +++ b/app/config/locale/he.php @@ -11,7 +11,7 @@ return [ 'auth.emails.confirm.body' => 'he.email.auth.confirm.tpl', 'auth.emails.recovery.title' => 'איפוס סיסמא', 'auth.emails.recovery.body' => 'he.email.auth.recovery.tpl', - 'auth.emails.invitation.title' => 'הזמנה לצוות של %s ב-%s', + 'auth.emails.invitation.title' => 'הזמנה לצוות של %s ב־%s', 'auth.emails.invitation.body' => 'he.email.auth.invitation.tpl', 'locale.country.unknown' => 'לא ידוע', diff --git a/app/config/locale/it.continents.php b/app/config/locale/it.continents.php new file mode 100644 index 000000000..6bd12d370 --- /dev/null +++ b/app/config/locale/it.continents.php @@ -0,0 +1,11 @@ + 'Africa', + 'AN' => 'Antartide', + 'AS' => 'Asia', + 'EU' => 'Europa', + 'NA' => 'Nord America', + 'OC' => 'Oceania', + 'SA' => 'Sud America', +]; diff --git a/app/config/locale/it.countries.php b/app/config/locale/it.countries.php new file mode 100644 index 000000000..cf8a339b1 --- /dev/null +++ b/app/config/locale/it.countries.php @@ -0,0 +1,198 @@ + 'Afghanistan', + 'AO' => 'Angola', + 'AL' => 'Albania', + 'AD' => 'Andorra', + 'AE' => 'Emirati Arabi Uniti', + 'AR' => 'Argentina', + 'AM' => 'Armenia', + 'AG' => 'Antigua e Barbuda', + 'AU' => 'Australia', + 'AT' => 'Austria', + 'AZ' => 'Azerbaigian', + 'BI' => 'Burundi', + 'BE' => 'Belgio', + 'BJ' => 'Benin', + 'BF' => 'Burkina Faso', + 'BD' => 'Bangladesh', + 'BG' => 'Bulgaria', + 'BH' => 'Bahrein', + 'BS' => 'Bahamas', + 'BA' => 'Bosnia ed Erzegovina', + 'BY' => 'Bielorussia', + 'BZ' => 'Belize', + 'BO' => 'Bolivia', + 'BR' => 'Brasile', + 'BB' => 'Barbados', + 'BN' => 'Brunei', + 'BT' => 'Bhutan', + 'BW' => 'Botswana', + 'CF' => 'Repubblica centrafricana', + 'CA' => 'Canada', + 'CH' => 'Svizzera', + 'CL' => 'Cile', + 'CN' => 'Cina', + 'CI' => 'Costa d\'Avorio', + 'CM' => 'Camerun', + 'CD' => 'DR Congo', + 'CG' => 'Repubblica del Congo', + 'CO' => 'Colombia', + 'KM' => 'Comore', + 'CV' => 'Capo Verde', + 'CR' => 'Costa Rica', + 'CU' => 'Cuba', + 'CY' => 'Cipro', + 'CZ' => 'Czechia', + 'DE' => 'Germania', + 'DJ' => 'Gibuti', + 'DM' => 'Dominica', + 'DK' => 'Danimarca', + 'DO' => 'Repubblica Dominicana', + 'DZ' => 'Algeria', + 'EC' => 'Ecuador', + 'EG' => 'Egitto', + 'ER' => 'Eritrea', + 'ES' => 'Spagna', + 'EE' => 'Estonia', + 'ET' => 'Etiopia', + 'FI' => 'Finlandia', + 'FJ' => 'Figi', + 'FR' => 'France', + 'FM' => 'Micronesia', + 'GA' => 'Gabon', + 'GB' => 'Regno Unito', + 'GE' => 'Georgia', + 'GH' => 'Ghana', + 'GN' => 'Guinea', + 'GM' => 'Gambia', + 'GW' => 'Guinea-Bissau', + 'GQ' => 'Guinea equatoriale', + 'GR' => 'Grecia', + 'GD' => 'Grenada', + 'GT' => 'Guatemala', + 'GY' => 'Guyana', + 'HN' => 'Honduras', + 'HR' => 'Croazia', + 'HT' => 'Haiti', + 'HU' => 'Ungheria', + 'ID' => 'Indonesia', + 'IN' => 'India', + 'IE' => 'Irlanda', + 'IR' => 'Iran', + 'IQ' => 'Iraq', + 'IS' => 'Islanda', + 'IL' => 'Israele', + 'IT' => 'Italia', + 'JM' => 'Giamaica', + 'JO' => 'Jordan', + 'JP' => 'Giappone', + 'KZ' => 'Kazakistan', + 'KE' => 'Kenya', + 'KG' => 'Kirghizistan', + 'KH' => 'Cambogia', + 'KI' => 'Kiribati', + 'KN' => 'Saint Kitts e Nevis', + 'KR' => 'Corea del Sud', + 'KW' => 'Kuwait', + 'LA' => 'Laos', + 'LB' => 'Libano', + 'LR' => 'Liberia', + 'LY' => 'Libia', + 'LC' => 'Santa Lucia', + 'LI' => 'Liechtenstein', + 'LK' => 'Sri Lanka', + 'LS' => 'Lesotho', + 'LT' => 'Lituania', + 'LU' => 'Lussemburgo', + 'LV' => 'Lettonia', + 'MA' => 'Marocco', + 'MC' => 'Monaco', + 'MD' => 'Moldavia', + 'MG' => 'Madagascar', + 'MV' => 'Maldive', + 'MX' => 'Messico', + 'MH' => 'Isole Marshall', + 'MK' => 'Macedonia', + 'ML' => 'Mali', + 'MT' => 'Malta', + 'MM' => 'Myanmar', + 'ME' => 'Montenegro', + 'MN' => 'Mongolia', + 'MZ' => 'Mozambico', + 'MR' => 'Mauritania', + 'MU' => 'Mauritius', + 'MW' => 'Malawi', + 'MY' => 'Malaysia', + 'NA' => 'Namibia', + 'NE' => 'Niger', + 'NG' => 'Nigeria', + 'NI' => 'Nicaragua', + 'NL' => 'Paesi Bassi', + 'NO' => 'Norvegia', + 'NP' => 'Nepal', + 'NR' => 'Nauru', + 'NZ' => 'Nuova Zelanda', + 'OM' => 'Oman', + 'PK' => 'Pakistan', + 'PA' => 'Panama', + 'PE' => 'Perù', + 'PH' => 'Filippine', + 'PW' => 'Palau', + 'PG' => 'Papua New Guinea', + 'PL' => 'Polonia', + 'KP' => 'Corea del Nord', + 'PT' => 'Portogallo', + 'PY' => 'Paraguay', + 'QA' => 'Qatar', + 'RO' => 'Romania', + 'RU' => 'Russia', + 'RW' => 'Ruanda', + 'SA' => 'Arabia Saudita', + 'SD' => 'Sudan', + 'SN' => 'Senegal', + 'SG' => 'Singapore', + 'SB' => 'Isole Salomone', + 'SL' => 'Sierra Leone', + 'SV' => 'El Salvador', + 'SM' => 'San Marino', + 'SO' => 'Somalia', + 'RS' => 'Serbia', + 'SS' => 'Sudan del Sud', + 'ST' => 'São Tomé and Príncipe', + 'SR' => 'Suriname', + 'SK' => 'Slovacchia', + 'SI' => 'Slovenia', + 'SE' => 'Svezia', + 'SZ' => 'Swaziland', + 'SC' => 'Seychelles', + 'SY' => 'Siria', + 'TD' => 'Chad', + 'TG' => 'Togo', + 'TH' => 'Thailand', + 'TJ' => 'Tagikistan', + 'TM' => 'Turkmenistan', + 'TL' => 'Timor Est', + 'TO' => 'Tonga', + 'TT' => 'Trinidad e Tobago', + 'TN' => 'Tunisia', + 'TR' => 'Turchia', + 'TV' => 'Tuvalu', + 'TZ' => 'Tanzania', + 'UG' => 'Uganda', + 'UA' => 'Ucraina', + 'UY' => 'Uruguay', + 'US' => 'Stati Uniti', + 'UZ' => 'Uzbekistan', + 'VA' => 'Città del Vaticano', + 'VC' => 'Saint Vincent e Grenadine', + 'VE' => 'Venezuela', + 'VN' => 'Vietnam', + 'VU' => 'Vanuatu', + 'WS' => 'Samoa', + 'YE' => 'Yemen', + 'ZA' => 'Sudafrica', + 'ZM' => 'Zambia', + 'ZW' => 'Zimbabwe', +]; diff --git a/app/config/locale/it.php b/app/config/locale/it.php new file mode 100644 index 000000000..dfc8d1197 --- /dev/null +++ b/app/config/locale/it.php @@ -0,0 +1,18 @@ + '"L\'arte di essere saggi è l\'arte di sapere cosa trascurare."', // Questa è la riga stampata nella homepage e nella console 'view-source' + 'settings.locale' => 'it', + 'settings.direction' => 'ltr', + // Servizio - Utenti + 'auth.emails.team' => '%s Squadra', + 'auth.emails.confirm.title' => 'Conferma dell\'account', + 'auth.emails.confirm.body' => 'en.email.auth.confirm.tpl', + 'auth.emails.recovery.title' => 'Reimpostazione della password', + 'auth.emails.recovery.body' => 'en.email.auth.recovery.tpl', + 'auth.emails.invitation.title' => 'Invito a %s squadra %s', + 'auth.emails.invitation.body' => 'en.email.auth.invitation.tpl', + 'locale.country.unknown' => 'Sconosciuto', + 'countries' => include 'it.countries.php', + 'continents' => include 'it.continents.php', +]; diff --git a/app/config/locale/no.continents.php b/app/config/locale/no.continents.php new file mode 100644 index 000000000..27664083b --- /dev/null +++ b/app/config/locale/no.continents.php @@ -0,0 +1,11 @@ + 'Afrika', + 'AN' => 'Antarktis', + 'AS' => 'Asia', + 'EU' => 'Europa', + 'NA' => 'Nord-Amerika', + 'OC' => 'Oseania', + 'SA' => 'Sør-Amerika', +]; diff --git a/app/config/locale/no.countries.php b/app/config/locale/no.countries.php new file mode 100644 index 000000000..7f96c0c55 --- /dev/null +++ b/app/config/locale/no.countries.php @@ -0,0 +1,198 @@ + 'Afghanistan', + 'AO' => 'Angola', + 'AL' => 'Albania', + 'AD' => 'Andorra', + 'AE' => 'De forente arabiske emirater', + 'AR' => 'Argentina', + 'AM' => 'Armenia', + 'AG' => 'Antigua og Barbuda', + 'AU' => 'Australia', + 'AT' => 'Østerrike', + 'AZ' => 'Aserbajdsjan', + 'BI' => 'Burundi', + 'BE' => 'Belgia', + 'BJ' => 'Benin', + 'BF' => 'Burkina Faso', + 'BD' => 'Bangladesh', + 'BG' => 'Bulgaria', + 'BH' => 'Bahrain', + 'BS' => 'Bahamas', + 'BA' => 'Bosnia-Hercegovina', + 'BY' => 'Hviterussland', + 'BZ' => 'Belize', + 'BO' => 'Bolivia', + 'BR' => 'Brasil', + 'BB' => 'Barbados', + 'BN' => 'Brunei Darussalam', + 'BT' => 'Bhutan', + 'BW' => 'Botswana', + 'CF' => 'Den sentralafrikanske republikk', + 'CA' => 'Canada', + 'CH' => 'Sveits', + 'CL' => 'Chile', + 'CN' => 'Kina', + 'CI' => 'Elfenbenskysten', + 'CM' => 'Kamerun', + 'CD' => 'Den demokratiske republikken Kongo', + 'CG' => 'Republikken Kongo', + 'CO' => 'Colombia', + 'KM' => 'Komorene', + 'CV' => 'Kapp Verde', + 'CR' => 'Costa Rica', + 'CU' => 'Cuba', + 'CY' => 'Kypros', + 'CZ' => 'Tjekkia', + 'DE' => 'Tyskland', + 'DJ' => 'Djibouti', + 'DM' => 'Dominica', + 'DK' => 'Danmark', + 'DO' => 'Den dominikanske republikk', + 'DZ' => 'Algerie', + 'EC' => 'Ecuador', + 'EG' => 'Egypt', + 'ER' => 'Eritrea', + 'ES' => 'Spania', + 'EE' => 'Estland', + 'ET' => 'Etiopia', + 'FI' => 'Finland', + 'FJ' => 'Fiji', + 'FR' => 'Frankrike', + 'FM' => 'Mikronesia', + 'GA' => 'Gabon', + 'GB' => 'Storbritannia', + 'GE' => 'Georgia', + 'GH' => 'Ghana', + 'GN' => 'Guinea', + 'GM' => 'Gambia', + 'GW' => 'Guinea-Bissau', + 'GQ' => 'Ekvatorial-Guinea', + 'GR' => 'Hellas', + 'GD' => 'Grenada', + 'GT' => 'Guatemala', + 'GY' => 'Guyana', + 'HN' => 'Honduras', + 'HR' => 'Kroatia', + 'HT' => 'Haiti', + 'HU' => 'Ungarn', + 'ID' => 'Indonesia', + 'IN' => 'India', + 'IE' => 'Irland', + 'IR' => 'Iran', + 'IQ' => 'Irak', + 'IS' => 'Island', + 'IL' => 'Israel', + 'IT' => 'Italia', + 'JM' => 'Jamaica', + 'JO' => 'Jordan', + 'JP' => 'Japan', + 'KZ' => 'Kasakhstan', + 'KE' => 'Kenya', + 'KG' => 'Kirgisistan', + 'KH' => 'Kambodsja', + 'KI' => 'Kiribati', + 'KN' => 'Saint Kitts og Nevis', + 'KR' => 'Sør-Korea', + 'KW' => 'Kuwait', + 'LA' => 'Laos', + 'LB' => 'Libanon', + 'LR' => 'Liberia', + 'LY' => 'Libya', + 'LC' => 'Saint Lucia', + 'LI' => 'Liechtenstein', + 'LK' => 'Sri Lanka', + 'LS' => 'Lesotho', + 'LT' => 'Litauen', + 'LU' => 'Luxembourg', + 'LV' => 'Latvia', + 'MA' => 'Marokko', + 'MC' => 'Monaco', + 'MD' => 'Moldova', + 'MG' => 'Madagaskar', + 'MV' => 'Maldivene', + 'MX' => 'Mexico', + 'MH' => 'Marshalløyene', + 'MK' => 'Nord-Makedonia', + 'ML' => 'Mali', + 'MT' => 'Malta', + 'MM' => 'Myanmar', + 'ME' => 'Montenegro', + 'MN' => 'Mongolia', + 'MZ' => 'Mozambik', + 'MR' => 'Mauritania', + 'MU' => 'Mauritius', + 'MW' => 'Malawi', + 'MY' => 'Malaysia', + 'NA' => 'Namibia', + 'NE' => 'Niger', + 'NG' => 'Nigeria', + 'NI' => 'Nicaragua', + 'NL' => 'Nederland', + 'NO' => 'Norge', + 'NP' => 'Nepal', + 'NR' => 'Nauru', + 'NZ' => 'New Zealand', + 'OM' => 'Oman', + 'PK' => 'Pakistan', + 'PA' => 'Panama', + 'PE' => 'Peru', + 'PH' => 'Filippinene', + 'PW' => 'Palau', + 'PG' => 'Papua Ny-Guinea', + 'PL' => 'Polen', + 'KP' => 'Nord-Korea', + 'PT' => 'Portugal', + 'PY' => 'Paraguay', + 'QA' => 'Qatar', + 'RO' => 'Romania', + 'RU' => 'Russland', + 'RW' => 'Rwanda', + 'SA' => 'Saudi-Arabia', + 'SD' => 'Sudan', + 'SN' => 'Senegal', + 'SG' => 'Singapore', + 'SB' => 'Solomonøyene', + 'SL' => 'Sierra Leone', + 'SV' => 'El Salvador', + 'SM' => 'San Marino', + 'SO' => 'Somalia', + 'RS' => 'Serbia', + 'SS' => 'Sør-Sudan', + 'ST' => 'São Tomé og Príncipe', + 'SR' => 'Surinam', + 'SK' => 'Slovakia', + 'SI' => 'Slovenia', + 'SE' => 'Sverige', + 'SZ' => 'Swaziland', + 'SC' => 'Seychellene', + 'SY' => 'Syria', + 'TD' => 'Tsjad', + 'TG' => 'Togo', + 'TH' => 'Thailand', + 'TJ' => 'Tajikistan', + 'TM' => 'Turkmenistan', + 'TL' => 'Øst-Timor', + 'TO' => 'Tonga', + 'TT' => 'Trinidad og Tobago', + 'TN' => 'Tunisia', + 'TR' => 'Tyrkia', + 'TV' => 'Tuvalu', + 'TZ' => 'Tanzania', + 'UG' => 'Uganda', + 'UA' => 'Ukraina', + 'UY' => 'Uruguay', + 'US' => 'Amerikas forente stater', + 'UZ' => 'Usbekistan', + 'VA' => 'Vatikanstaten', + 'VC' => 'Saint Vincent og Grenadinene', + 'VE' => 'Venezuela', + 'VN' => 'Vietnam', + 'VU' => 'Vanuatu', + 'WS' => 'Samoa', + 'YE' => 'Jemen', + 'ZA' => 'Sør-Africa', + 'ZM' => 'Zambia', + 'ZW' => 'Zimbabwe', +]; diff --git a/app/config/locale/templates/en.email.auth.invitation.tpl b/app/config/locale/templates/en.email.auth.invitation.tpl index a71d72ebb..fda2bbcce 100644 --- a/app/config/locale/templates/en.email.auth.invitation.tpl +++ b/app/config/locale/templates/en.email.auth.invitation.tpl @@ -10,7 +10,7 @@ Hello,

- This mail was sent to you because {{owner}} wanted to invite to become a team member at the {{team}} team over at {{project}}. + This mail was sent to you because {{owner}} wanted to invite you to become a team member at the {{team}} team over at {{project}}.

Follow this link to join the {{team}} team: diff --git a/app/config/locale/templates/gr.email.auth.confirm.tpl b/app/config/locale/templates/gr.email.auth.confirm.tpl new file mode 100644 index 000000000..a62445476 --- /dev/null +++ b/app/config/locale/templates/gr.email.auth.confirm.tpl @@ -0,0 +1,24 @@ + + +
+ Γεια σου {{name}}, +
+
+ Ακολούθησε αυτό τον σύνδεσμο για να επιβεβαιώσεις τη διεύθυνση email σου. +
+ {{redirect}} +
+
+ Αν δεν ζήτησες να επιβεβαιώσεις αυτή τη διεύθυνση, μπορείς να αγνοήσεις αυτό το μήνυμα. +
+
+ Ευχαριστούμε, +
+ Η ομάδα του {{project}} +
\ No newline at end of file diff --git a/app/config/locale/templates/gr.email.auth.invitation.tpl b/app/config/locale/templates/gr.email.auth.invitation.tpl new file mode 100644 index 000000000..101a1c673 --- /dev/null +++ b/app/config/locale/templates/gr.email.auth.invitation.tpl @@ -0,0 +1,27 @@ + + +
+ Γεια, +
+
+ Έλαβες αυτό το email επειδή ο {{owner}} σε προσκάλεσε να γίνεις μέλος της ομάδας {{team}} στο {{project}}. +
+
+ Ακολούθησε αυτό τον σύνδεσμο για να γίνεις μέλος της ομάδας {{team}}: +
+ {{redirect}} +
+
+ Άν δεν ενδιαφέρεσαι, μπορείς να αγνοήσεις αυτό το μήνυμα. +
+
+ Ευχαριστούμε, +
+ Η ομάδα του {{project}} +
diff --git a/app/config/locale/templates/gr.email.auth.recovery.tpl b/app/config/locale/templates/gr.email.auth.recovery.tpl new file mode 100644 index 000000000..cae164df2 --- /dev/null +++ b/app/config/locale/templates/gr.email.auth.recovery.tpl @@ -0,0 +1,24 @@ + + +
+ Γεια σου {{name}}, +
+
+ Ακολούθησε αυτό τον σύνδεσμο για να επαναφέρεις τον κωδικό πρόσβασής σου για το {{project}}. +
+ {{redirect}} +
+
+ Άν δεν ζήτησες αλλαγή κωδικού πρόσβασης, μπορείς να αγνοήσεις αυτο το μήνυμα. +
+
+ Ευχαριστούμε, +
+ Η ομάδα του {{project}} +
diff --git a/app/config/locale/templates/he.email.auth.confirm.tpl b/app/config/locale/templates/he.email.auth.confirm.tpl index ba18e2a06..bc9189a16 100644 --- a/app/config/locale/templates/he.email.auth.confirm.tpl +++ b/app/config/locale/templates/he.email.auth.confirm.tpl @@ -10,15 +10,15 @@ שלום {{name}},

- לחץ\י על הלינק הבא על מנת לאמת את החשבון שלך. + נא ללחוץ על הקישור שלהלן כדי לאמת את החשבון שלך.
{{redirect}}

- במידה ולא ביקשת לאמת את כתובת המייל הזאת, את\ה יכול\ה להתעלם ממייל זה. + אם לא ביקשת לאמת את כתובת הדוא״ל, ניתן להתעלם מההודעה זו.

- תודה, + בברכה,
צוות {{project}} \ No newline at end of file diff --git a/app/config/locale/templates/he.email.auth.invitation.tpl b/app/config/locale/templates/he.email.auth.invitation.tpl index ca204cb4c..a7514affd 100644 --- a/app/config/locale/templates/he.email.auth.invitation.tpl +++ b/app/config/locale/templates/he.email.auth.invitation.tpl @@ -10,18 +10,18 @@ שלום,

- מייל זה נשלח אליך בגלל ש-{{owner}} רוצה להזמין אותך להפוך לחבר\ת צוות בצוות {{team}} ב-{{project}}. + הודעת דוא״ל זו נשלחה אליך כי {{owner}} ביקש להזמינך להצטרף לצוות {{team}} ב־{{project}}.

- בכדי להצטרף לצוות {{team}}, לחץ על הלינק: + כדי להצטרף לצוות {{team}}, נא ללחוץ על הקישור:
{{redirect}}

- במידה ואינך מעוניין\ת, אנא התעלם\י ממייל זה. + אם איך לך עניין להצטרף לצוות, ניתן להתעלם מהודעת דוא״ל זו.

- תודה, + בברכה,
צוות {{project}} diff --git a/app/config/locale/templates/he.email.auth.recovery.tpl b/app/config/locale/templates/he.email.auth.recovery.tpl index 71f7015d3..e349365f0 100644 --- a/app/config/locale/templates/he.email.auth.recovery.tpl +++ b/app/config/locale/templates/he.email.auth.recovery.tpl @@ -10,15 +10,15 @@ שלום {{name}},

- לחץ\י על הלינק בכדי לאפס את הסיסמא שלך ב-{{project}}. + נא ללחוץ על הקישור שלהלן כדי לאפס את הסיסמה שלך ב־{{project}}.
{{redirect}}

- במידה ולא ביקשת לאפס את סיסמתך, את\ה יכול\ה להתעלם ממייל זה. + אם לא ביקשת לאפס את סיסמתך, ניתן להתעלם מהודעת דוא״ל זו.

- תודה, + בברכה,
צוות {{project}} diff --git a/app/config/locale/templates/it.email.auth.confirm.tpl b/app/config/locale/templates/it.email.auth.confirm.tpl new file mode 100644 index 000000000..8106722d8 --- /dev/null +++ b/app/config/locale/templates/it.email.auth.confirm.tpl @@ -0,0 +1,25 @@ + + + +
+ Ciao {{name}}, +
+
+ Segui questo link per verificare il tuo indirizzo email. +
+ {{redirect}} +
+
+ Se non hai chiesto di verificare questo indirizzo, puoi ignorare questo messaggio. +
+
+ Grazie, +
+ {{project}} squadra +
\ No newline at end of file diff --git a/app/config/locale/templates/it.email.auth.invitation.tpl b/app/config/locale/templates/it.email.auth.invitation.tpl new file mode 100644 index 000000000..be7becac4 --- /dev/null +++ b/app/config/locale/templates/it.email.auth.invitation.tpl @@ -0,0 +1,28 @@ + + + +
+ Ciao, +
+
+ Questa mail ti stata inviata perch {{owner}} volevo invitarti a diventare un membro del team al {{team}} squadra a {{project}}. +
+
+ Segui questo link per unirti a {{team}} squadra: +
+ {{redirect}} +
+
+ Se non sei interessato, puoi ignorare questo messaggio. +
+
+ Grazie, +
+ {{project}} squadra +
\ No newline at end of file diff --git a/app/config/locale/templates/it.email.auth.recovery.tpl b/app/config/locale/templates/it.email.auth.recovery.tpl new file mode 100644 index 000000000..6a5adb5cb --- /dev/null +++ b/app/config/locale/templates/it.email.auth.recovery.tpl @@ -0,0 +1,24 @@ + + +
+ Ciao {{name}}, +
+
+ Segui questo link per reimpostare la tua {{project}} password. +
+ {{redirect}} +
+
+ Se non hai chiesto di reimpostare la password, puoi ignorare questo messaggio. +
+
+ Grazie, +
+ {{project}} squadra +
\ No newline at end of file diff --git a/app/config/locale/templates/no.email.auth.confirm.tpl b/app/config/locale/templates/no.email.auth.confirm.tpl new file mode 100644 index 000000000..abe17ff65 --- /dev/null +++ b/app/config/locale/templates/no.email.auth.confirm.tpl @@ -0,0 +1,24 @@ + + +
+ Hei {{name}}, +
+
+ Følg denne lenken for å verifisere din e-postadresse. +
+ {{redirect}} +
+
+ Hvis du ikke har spurt om å verifisere din e-post, kan du ignorere denne meldingen. +
+
+ Hilsen, +
+ {{project}}-teamet +
\ No newline at end of file diff --git a/app/config/locale/templates/no.email.auth.invitation.tpl b/app/config/locale/templates/no.email.auth.invitation.tpl new file mode 100644 index 000000000..c56e913d3 --- /dev/null +++ b/app/config/locale/templates/no.email.auth.invitation.tpl @@ -0,0 +1,28 @@ + + +
+ Hei, +
+
+ Denne mailen ble sendt til deg fordi {{owner}} har invitert deg til å bli medlem av {{team}}-teamet på {{project}}. +
+
+ Follow this link to join the {{team}} team: + Følg denne lenken for å bli med på {{team}}-teamet: +
+ {{redirect}} +
+
+ Hvis du ikke er interresert kan du ignorere denne meldingen. +
+
+ Hilsen, +
+ {{project}}-teamet +
diff --git a/app/config/locale/templates/no.email.auth.recovery.tpl b/app/config/locale/templates/no.email.auth.recovery.tpl new file mode 100644 index 000000000..75b8be0e9 --- /dev/null +++ b/app/config/locale/templates/no.email.auth.recovery.tpl @@ -0,0 +1,25 @@ + + +
+ Hei {{name}}, +
+
+ Follow this link to reset your {{project}} password. + Følg denne lenken for å tilbakestille ditt {{project}}-passord. +
+ {{redirect}} +
+
+ Hvis du ikke har spurt om å tilbakestille passordet ditt, kan du ignorere denne meldingen. +
+
+ Hilsen, +
+ {{project}}-teamet +
diff --git a/app/config/providers.php b/app/config/providers.php index 7dc70c92f..9e5f329eb 100644 --- a/app/config/providers.php +++ b/app/config/providers.php @@ -19,12 +19,12 @@ return [ 'gitlab' => [ 'developers' => 'https://docs.gitlab.com/ee/api/', 'icon' => 'icon-gitlab', - 'enabled' => false, + 'enabled' => true, ], 'google' => [ 'developers' => 'https://developers.google.com/', 'icon' => 'icon-google', - 'enabled' => false, + 'enabled' => true, ], 'instagram' => [ 'developers' => 'https://www.instagram.com/developer/', diff --git a/app/config/version.php b/app/config/version.php index 0d2a19c09..4f8cb07ea 100644 --- a/app/config/version.php +++ b/app/config/version.php @@ -1,4 +1,5 @@ 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) { diff --git a/app/controllers/auth.php b/app/controllers/auth.php index 4f93ebd2d..68ea25885 100644 --- a/app/controllers/auth.php +++ b/app/controllers/auth.php @@ -28,32 +28,44 @@ $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()) { - $whitlistEmails = $project->getAttribute('authWhitelistEmails'); - $whitlistIPs = $project->getAttribute('authWhitelistIPs'); - $whitlistDomains = $project->getAttribute('authWhitelistDomains'); + 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); } } - + $profile = $projectDB->getCollection([ // Get user by email address 'limit' => 1, 'first' => true, @@ -65,7 +77,7 @@ $utopia->post('/v1/auth/register') if (!empty($profile)) { if ($failure) { - $response->redirect($failure . '?message=User already registered'); + $response->redirect($failure.'?message=User already registered'); return; } @@ -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(); @@ -636,14 +682,23 @@ $utopia->get('/v1/auth/oauth/callback/:provider/:projectId') ->desc('OAuth Callback') ->label('error', __DIR__.'/../views/general/error.phtml') ->label('scope', 'auth') - ->label('sdk.namespace', 'auth') - ->label('sdk.method', 'oauthCallback') + //->label('sdk.namespace', 'auth') + //->label('sdk.method', 'oauthCallback') ->label('abuse-limit', 50) ->label('abuse-key', 'ip:{ip}') - ->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) + ->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) ->action( function ($projectId, $provider, $code, $state) use ($response, $request, $domain) { $response->redirect($request->getServer('REQUEST_SCHEME', 'https').'://'.$domain.'/v1/auth/oauth/'.$provider.'/redirect?' @@ -656,14 +711,20 @@ $utopia->get('/v1/auth/oauth/:provider/redirect') ->label('error', __DIR__.'/../views/general/error.phtml') ->label('webhook', 'auth.oauth') ->label('scope', 'auth') - ->label('sdk.namespace', 'auth') - ->label('sdk.method', 'oauthRedirect') + //->label('sdk.namespace', 'auth') + //->label('sdk.method', 'oauthRedirect') ->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(); diff --git a/app/controllers/avatars.php b/app/controllers/avatars.php index 039fb430d..77580a59b 100644 --- a/app/controllers/avatars.php +++ b/app/controllers/avatars.php @@ -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)) ; - } ); diff --git a/app/controllers/console.php b/app/controllers/console.php index d8caebe4c..ef36ba9e0 100644 --- a/app/controllers/console.php +++ b/app/controllers/console.php @@ -5,7 +5,6 @@ include_once 'shared/web.php'; global $utopia, $response, $request, $layout, $version, $providers; use Utopia\View; -use Utopia\Locale\Locale; use Database\Database; use Database\Validator\UID; @@ -83,7 +82,7 @@ $utopia->get('/console/account') ; $layout - ->setParam('title', 'Account - ' . APP_NAME) + ->setParam('title', 'Account - '.APP_NAME) ->setParam('body', $page); }); @@ -175,7 +174,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); diff --git a/app/controllers/database.php b/app/controllers/database.php index e330bd117..e27d1feff 100644 --- a/app/controllers/database.php +++ b/app/controllers/database.php @@ -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,24 +104,32 @@ $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' => [ 'read' => $read, 'write' => $write, - ] + ], ], $rule); } - + try { $data = $projectDB->createDocument([ '$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS, @@ -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); @@ -173,16 +201,16 @@ $utopia->put('/v1/database/:collectionId') if (empty($collection->getUid()) || Database::SYSTEM_COLLECTION_COLLECTIONS != $collection->getCollection()) { throw new Exception('Collection not found', 404); } - + $parsedRules = []; - - foreach($rules as &$rule) { + + foreach ($rules as &$rule) { $parsedRules[] = array_merge([ '$collection' => Database::SYSTEM_COLLECTION_RULES, '$permissions' => [ 'read' => $read, 'write' => $write, - ] + ], ], $rule); } @@ -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); diff --git a/app/controllers/health.php b/app/controllers/health.php index 99b496f10..72a630006 100644 --- a/app/controllers/health.php +++ b/app/controllers/health.php @@ -115,11 +115,11 @@ $utopia->get('/v1/health/storage/local') function () use ($response) { $device = new Local(); - if (!is_readable($device->getRoot(). '/..')) { + if (!is_readable($device->getRoot().'/..')) { throw new Exception('Device is not readable'); } - if (!is_writable($device->getRoot(). '/..')) { + if (!is_writable($device->getRoot().'/..')) { throw new Exception('Device is not writable'); } diff --git a/app/controllers/home.php b/app/controllers/home.php index 58f5b7e1d..b2a17de98 100644 --- a/app/controllers/home.php +++ b/app/controllers/home.php @@ -5,7 +5,6 @@ include_once 'shared/web.php'; global $utopia, $response, $request, $layout, $version, $providers, $sdks; use Utopia\View; -use Utopia\Locale\Locale; $layout ->setParam('title', APP_NAME) diff --git a/app/controllers/projects.php b/app/controllers/projects.php index 2a861fcb6..a3d0703ff 100644 --- a/app/controllers/projects.php +++ b/app/controllers/projects.php @@ -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); diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 87ec3e57d..4da090a84 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -1,4 +1,5 @@ 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); diff --git a/app/controllers/teams.php b/app/controllers/teams.php index 5e09b2242..27a5fbe31 100644 --- a/app/controllers/teams.php +++ b/app/controllers/teams.php @@ -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); diff --git a/app/controllers/users.php b/app/controllers/users.php index f2c01ca51..522bdfe8e 100644 --- a/app/controllers/users.php +++ b/app/controllers/users.php @@ -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); diff --git a/app/init.php b/app/init.php index 014e131dc..dd41573be 100644 --- a/app/init.php +++ b/app/init.php @@ -1,8 +1,8 @@ getServer('_APP_ENV', App::ENV_TYPE_PRODUCTION); -$domain = $request->getServer('HTTP_HOST', ''); -$version = include __DIR__ . '/../app/config/version.php'; -$providers = include __DIR__ . '/../app/config/providers.php'; // OAuth providers list -$collections = include __DIR__ . '/../app/config/collections.php'; // OAuth providers list -$redisHost = $request->getServer('_APP_REDIS_HOST', ''); -$redisPort = $request->getServer('_APP_REDIS_PORT', ''); -$utopia = new App('Asia/Tel_Aviv', $env); -$port = (string)(isset($_SERVER['HTTP_HOST'])) ? parse_url($_SERVER['HTTP_HOST'], PHP_URL_PORT) : ''; +$env = $request->getServer('_APP_ENV', App::ENV_TYPE_PRODUCTION); +$domain = $request->getServer('HTTP_HOST', ''); +$version = include __DIR__.'/../app/config/version.php'; +$providers = include __DIR__.'/../app/config/providers.php'; // OAuth providers list +$collections = include __DIR__.'/../app/config/collections.php'; // OAuth providers list +$redisHost = $request->getServer('_APP_REDIS_HOST', ''); +$redisPort = $request->getServer('_APP_REDIS_PORT', ''); +$utopia = new App('Asia/Tel_Aviv', $env); +$port = (string) (isset($_SERVER['HTTP_HOST'])) ? parse_url($_SERVER['HTTP_HOST'], PHP_URL_PORT) : ''; -Resque::setBackend($redisHost . ':' . $redisPort); +Resque::setBackend($redisHost.':'.$redisPort); -define('COOKIE_DOMAIN', ($request->getServer('HTTP_HOST', null) === 'localhost' || $request->getServer('HTTP_HOST', null) === 'localhost:' . $port) ? false : '.' . $request->getServer('HTTP_HOST', false)); +define('COOKIE_DOMAIN', ($request->getServer('HTTP_HOST', null) === 'localhost' || $request->getServer('HTTP_HOST', null) === 'localhost:'.$port) ? false : '.'.$request->getServer('HTTP_HOST', false)); -/** +/* * Registry */ -$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', ''); - $dbScheme = $request->getServer('_APP_DB_SCHEMA', ''); +$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', ''); + $dbScheme = $request->getServer('_APP_DB_SCHEMA', ''); $pdo = new PDO("mysql:host={$dbHost};dbname={$dbScheme};charset=utf8mb4", $dbUser, $dbPass, array( PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4', - PDO::ATTR_TIMEOUT => 5 // Seconds + PDO::ATTR_TIMEOUT => 5, // Seconds )); // Connection settings @@ -68,19 +68,19 @@ $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)) { - return null; + if (empty($host) || empty($port)) { + return; } $client = new InfluxDB\Client($host, $port, '', '', false, false, 5); 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,14 @@ $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(); @@ -103,23 +104,23 @@ $register->set('smtp', function() use ($request) { $username = $request->getServer('_APP_SMTP_USERNAME', ''); $password = $request->getServer('_APP_SMTP_PASSWORD', ''); - $mail->XMailer = 'Appwrite Mailer'; - $mail->Host = $request->getServer('_APP_SMTP_HOST', 'smtp'); - $mail->Port = $request->getServer('_APP_SMTP_PORT', 25); - $mail->SMTPAuth = (!empty($username) && !empty($password)); - $mail->Username = $username; - $mail->Password = $password; + $mail->XMailer = 'Appwrite Mailer'; + $mail->Host = $request->getServer('_APP_SMTP_HOST', 'smtp'); + $mail->Port = $request->getServer('_APP_SMTP_PORT', 25); + $mail->SMTPAuth = (!empty($username) && !empty($password)); + $mail->Username = $username; + $mail->Password = $password; $mail->SMTPSecure = $request->getServer('_APP_SMTP_SECURE', ''); - $mail->setFrom('team@appwrite.io', APP_NAME . ' Team'); - $mail->addReplyTo('team@appwrite.io', APP_NAME . ' Team'); + $mail->setFrom('team@appwrite.io', APP_NAME.' Team'); + $mail->addReplyTo('team@appwrite.io', APP_NAME.' Team'); $mail->isHTML(true); - + return $mail; }); -/** +/* * Localization */ $locale = $request->getParam('locale', $request->getHeader('X-Appwrite-Locale', null)); @@ -132,7 +133,7 @@ Locale::setLanguage('ua', include __DIR__ . '/config/locale/ua.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); } @@ -140,11 +141,11 @@ stream_context_set_default([ // Set global user agent and http settings 'http' => [ 'method' => 'GET', 'user_agent' => sprintf(APP_USERAGENT, $version), - 'timeout' => 2 - ] + 'timeout' => 2, + ], ]); -/** +/* * Auth & Project Scope */ $consoleDB = new Database(); @@ -160,51 +161,50 @@ 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; } $mode = $request->getParam('mode', $request->getHeader('X-Appwrite-Mode', 'default')); -Auth::setCookieName('a-session-' . $project->getUid()); +Auth::setCookieName('a-session-'.$project->getUid()); -if(APP_MODE_ADMIN === $mode) { - Auth::setCookieName('a-session-' . $console->getUid()); +if (APP_MODE_ADMIN === $mode) { + Auth::setCookieName('a-session-'.$console->getUid()); } -$session = Auth::decodeSession($request->getCookie(Auth::$cookieName, $request->getHeader('X-Appwrite-Key', ''))); -Auth::$unique = $session['id']; -Auth::$secret = $session['secret']; +$session = Auth::decodeSession($request->getCookie(Auth::$cookieName, $request->getHeader('X-Appwrite-Key', ''))); +Auth::$unique = $session['id']; +Auth::$secret = $session['secret']; $projectDB = new Database(); $projectDB->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register)); -$projectDB->setNamespace('app_' . $project->getUid()); +$projectDB->setNamespace('app_'.$project->getUid()); $projectDB->setMocks($collections); $user = $projectDB->getDocument(Auth::$unique); -if(APP_MODE_ADMIN === $mode) { +if (APP_MODE_ADMIN === $mode) { $user = $consoleDB->getDocument(Auth::$unique); $user - ->setAttribute('$uid', 'admin-' . $user->getAttribute('$uid')) + ->setAttribute('$uid', 'admin-'.$user->getAttribute('$uid')) ; } -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'))); \ No newline at end of file +$register->get('smtp')->setFrom(APP_EMAIL_TEAM, sprintf(Locale::getText('auth.emails.team'), $project->getAttribute('name'))); diff --git a/app/sdks/php/docs/locale.md b/app/sdks/php/docs/locale.md index 763554648..e977fa99c 100644 --- a/app/sdks/php/docs/locale.md +++ b/app/sdks/php/docs/locale.md @@ -38,5 +38,5 @@ GET https://appwrite.test/v1/locale/countries/phones GET https://appwrite.test/v1/locale/currencies ``` -** List of all currencies, including currency symol, name, plural, and decimal digits for all major and minor currencies. You can use the locale header to get the data in supported language. ** +** List of all currencies, including currency symbol, name, plural, and decimal digits for all major and minor currencies. You can use the locale header to get the data in supported language. ** diff --git a/app/sdks/php/src/Appwrite/Client.php b/app/sdks/php/src/Appwrite/Client.php index 1ce0b3f53..edd8ec667 100644 --- a/app/sdks/php/src/Appwrite/Client.php +++ b/app/sdks/php/src/Appwrite/Client.php @@ -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; } } diff --git a/app/sdks/php/src/Appwrite/Service.php b/app/sdks/php/src/Appwrite/Service.php index ea3ad92e2..4eabee9e7 100644 --- a/app/sdks/php/src/Appwrite/Service.php +++ b/app/sdks/php/src/Appwrite/Service.php @@ -16,4 +16,4 @@ abstract class Service { $this->client = $client; } -} \ No newline at end of file +} diff --git a/app/sdks/php/src/Appwrite/Services/Account.php b/app/sdks/php/src/Appwrite/Services/Account.php index a1df7cb1e..90650d4b5 100644 --- a/app/sdks/php/src/Appwrite/Services/Account.php +++ b/app/sdks/php/src/Appwrite/Services/Account.php @@ -188,5 +188,4 @@ class Account extends Service return $this->client->call(Client::METHOD_GET, $path, [ ], $params); } - -} \ No newline at end of file +} diff --git a/app/sdks/php/src/Appwrite/Services/Auth.php b/app/sdks/php/src/Appwrite/Services/Auth.php index 7b7495936..d19cd05e9 100644 --- a/app/sdks/php/src/Appwrite/Services/Auth.php +++ b/app/sdks/php/src/Appwrite/Services/Auth.php @@ -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); } - -} \ No newline at end of file +} diff --git a/app/sdks/php/src/Appwrite/Services/Avatars.php b/app/sdks/php/src/Appwrite/Services/Avatars.php index 8ee781814..9a6dbedca 100644 --- a/app/sdks/php/src/Appwrite/Services/Avatars.php +++ b/app/sdks/php/src/Appwrite/Services/Avatars.php @@ -165,5 +165,4 @@ class Avatars extends Service return $this->client->call(Client::METHOD_GET, $path, [ ], $params); } - -} \ No newline at end of file +} diff --git a/app/sdks/php/src/Appwrite/Services/Database.php b/app/sdks/php/src/Appwrite/Services/Database.php index 1310909a5..b0e056551 100644 --- a/app/sdks/php/src/Appwrite/Services/Database.php +++ b/app/sdks/php/src/Appwrite/Services/Database.php @@ -267,5 +267,4 @@ class Database extends Service return $this->client->call(Client::METHOD_DELETE, $path, [ ], $params); } - -} \ No newline at end of file +} diff --git a/app/sdks/php/src/Appwrite/Services/Locale.php b/app/sdks/php/src/Appwrite/Services/Locale.php index 1ae5ae042..e11104c75 100644 --- a/app/sdks/php/src/Appwrite/Services/Locale.php +++ b/app/sdks/php/src/Appwrite/Services/Locale.php @@ -106,5 +106,4 @@ class Locale extends Service return $this->client->call(Client::METHOD_GET, $path, [ ], $params); } - -} \ No newline at end of file +} diff --git a/app/sdks/php/src/Appwrite/Services/Projects.php b/app/sdks/php/src/Appwrite/Services/Projects.php index af68cf4e9..f1cf92cc0 100644 --- a/app/sdks/php/src/Appwrite/Services/Projects.php +++ b/app/sdks/php/src/Appwrite/Services/Projects.php @@ -610,5 +610,4 @@ class Projects extends Service return $this->client->call(Client::METHOD_DELETE, $path, [ ], $params); } - -} \ No newline at end of file +} diff --git a/app/sdks/php/src/Appwrite/Services/Storage.php b/app/sdks/php/src/Appwrite/Services/Storage.php index e22622ebe..26b771a67 100644 --- a/app/sdks/php/src/Appwrite/Services/Storage.php +++ b/app/sdks/php/src/Appwrite/Services/Storage.php @@ -205,5 +205,4 @@ class Storage extends Service return $this->client->call(Client::METHOD_GET, $path, [ ], $params); } - -} \ No newline at end of file +} diff --git a/app/sdks/php/src/Appwrite/Services/Teams.php b/app/sdks/php/src/Appwrite/Services/Teams.php index 2c331b4c7..8b4f5c81a 100644 --- a/app/sdks/php/src/Appwrite/Services/Teams.php +++ b/app/sdks/php/src/Appwrite/Services/Teams.php @@ -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); } - -} \ No newline at end of file +} diff --git a/app/sdks/php/src/Appwrite/Services/Users.php b/app/sdks/php/src/Appwrite/Services/Users.php index 3b893c0e9..9159719e9 100644 --- a/app/sdks/php/src/Appwrite/Services/Users.php +++ b/app/sdks/php/src/Appwrite/Services/Users.php @@ -195,5 +195,4 @@ class Users extends Service return $this->client->call(Client::METHOD_PATCH, $path, [ ], $params); } - -} \ No newline at end of file +} diff --git a/app/tasks/sdks.php b/app/tasks/sdks.php index f47564e40..ce7e6fe96 100644 --- a/app/tasks/sdks.php +++ b/app/tasks/sdks.php @@ -19,7 +19,6 @@ $cli = new CLI(); $cli ->task('generate') ->action(function () { - function getSSLPage($url) { $ch = curl_init(); @@ -98,9 +97,9 @@ $cli ]; foreach ($clients as $name => $client) { - Console::info('Fetching API Spec for ' . $name . ' (' . $client['platform'] . ')'); - $spec = getSSLPage('https://appwrite.io/v1/open-api-2.json?extensions=1&platform=' . $client['platform']); - $spec = getSSLPage('https://appwrite.test/v1/open-api-2.json?extensions=1&platform=' . $client['platform']); + Console::info('Fetching API Spec for '.$name.' ('.$client['platform'].')'); + $spec = getSSLPage('https://appwrite.io/v1/open-api-2.json?extensions=1&platform='.$client['platform']); + $spec = getSSLPage('https://appwrite.test/v1/open-api-2.json?extensions=1&platform='.$client['platform']); switch ($name) { case 'php': @@ -211,4 +210,4 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND } }); -$cli->run(); \ No newline at end of file +$cli->run(); diff --git a/app/views/console/database/collection.phtml b/app/views/console/database/collection.phtml index df0584562..46f1d2fc3 100644 --- a/app/views/console/database/collection.phtml +++ b/app/views/console/database/collection.phtml @@ -86,11 +86,11 @@ $collection = $this->getParam('collection', []); - + @@ -101,9 +101,9 @@ $collection = $this->getParam('collection', []); - +
- +
- diff --git a/app/views/console/users/index.phtml b/app/views/console/users/index.phtml index 0ee7c32be..cf84d0f5e 100644 --- a/app/views/console/users/index.phtml +++ b/app/views/console/users/index.phtml @@ -315,7 +315,7 @@ $providers = $this->getParam('providers', []); data-param-project-id="{{router.params.project}}" data-scope="console">
    - $data): if(isset($data['enabled']) && !$data['enabled']) { continue; } ?> + $data): if (isset($data['enabled']) && !$data['enabled']) { continue; } ?>