From 0dec176bb8de9200111aecb06a35160cd1ab46b2 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 21 Jun 2020 10:40:50 +0300 Subject: [PATCH 01/20] Updated first and last description --- app/controllers/api/database.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index d8ecedab84..c87622a15e 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -477,8 +477,8 @@ $utopia->get('/v1/database/collections/:collectionId/documents') ->param('orderType', 'ASC', function () { return new WhiteList(array('DESC', 'ASC')); }, 'Order direction. Possible values are DESC for descending order, or ASC for ascending order.', true) ->param('orderCast', '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 the 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 the last document. Pass 1 for true or 0 for false. The default value is 0.', true) + ->param('first', 0, function () { return new Range(0, 1); }, 'Return only the first document. Pass 1 for true or 0 for false. The default value is 0. This option refers to the first element in your current documents range (limit/offset), and not the entire collection.', true) + ->param('last', 0, function () { return new Range(0, 1); }, 'Return only the last document. Pass 1 for true or 0 for false. The default value is 0. This option refers to the last element in your current documents range (limit/offset), and not the entire collection.', true) ->action( function ($collectionId, $filters, $offset, $limit, $orderField, $orderType, $orderCast, $search, $first, $last) use ($response, $projectDB, $isDev) { $collection = $projectDB->getDocument($collectionId, $isDev); From 569560d4566f1300bb7c698f7b5987e193eb9308 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 21 Jun 2020 10:41:44 +0300 Subject: [PATCH 02/20] Unused imports --- app/controllers/api/database.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index c87622a15e..96d0b4db93 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -10,9 +10,9 @@ use Utopia\Validator\WhiteList; use Utopia\Validator\Text; use Utopia\Validator\ArrayList; use Utopia\Validator\JSON; -use Utopia\Locale\Locale; -use Utopia\Audit\Audit; -use Utopia\Audit\Adapters\MySQL as AuditAdapter; +// use Utopia\Locale\Locale; +// use Utopia\Audit\Audit; +// use Utopia\Audit\Adapters\MySQL as AuditAdapter; use Appwrite\Database\Database; use Appwrite\Database\Document; use Appwrite\Database\Validator\UID; From 1b549092c4056742146ba3347a885bb6c040b5bc Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 21 Jun 2020 14:56:42 +0300 Subject: [PATCH 03/20] Added support for "loose" boolean in query strings --- app/controllers/api/avatars.php | 5 ++++- app/controllers/api/database.php | 12 ++++++++---- app/controllers/api/projects.php | 15 +++++++++------ app/controllers/web/home.php | 4 ++++ composer.json | 2 +- composer.lock | 22 +++++++++++----------- 6 files changed, 37 insertions(+), 23 deletions(-) diff --git a/app/controllers/api/avatars.php b/app/controllers/api/avatars.php index 4bff678c5d..86c85700e9 100644 --- a/app/controllers/api/avatars.php +++ b/app/controllers/api/avatars.php @@ -11,6 +11,7 @@ use Utopia\Cache\Cache; use Utopia\Cache\Adapter\Filesystem; use Appwrite\Resize\Resize; use Appwrite\URL\URL as URLParse; +use Appwrite\Utopia\Validator\Boolean; use BaconQrCode\Renderer\ImageRenderer; use BaconQrCode\Renderer\Image\ImagickImageBackEnd; use BaconQrCode\Renderer\RendererStyle\RendererStyle; @@ -363,7 +364,7 @@ $utopia->get('/v1/avatars/qr') ->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('download', false, function () { return new Boolean(true); }, '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.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER]) ->label('sdk.namespace', 'avatars') @@ -372,6 +373,8 @@ $utopia->get('/v1/avatars/qr') ->label('sdk.description', '/docs/references/avatars/get-qr.md') ->action( function ($text, $size, $margin, $download) use ($response) { + $download = ($download === '1' || $download === 'true' || $download === 1 || $download === true); + $renderer = new ImageRenderer( new RendererStyle($size, $margin), new ImagickImageBackEnd('png', 100) diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 96d0b4db93..5e5a521461 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -5,6 +5,7 @@ global $utopia, $register, $request, $response, $webhook, $audit, $projectDB; use Utopia\App; use Utopia\Exception; use Utopia\Response; +use Utopia\Validator\Boolean; use Utopia\Validator\Range; use Utopia\Validator\WhiteList; use Utopia\Validator\Text; @@ -22,8 +23,9 @@ use Appwrite\Database\Validator\Collection; use Appwrite\Database\Validator\Authorization; use Appwrite\Database\Exception\Authorization as AuthorizationException; use Appwrite\Database\Exception\Structure as StructureException; -use DeviceDetector\DeviceDetector; -use GeoIp2\Database\Reader; + +// use DeviceDetector\DeviceDetector; +// use GeoIp2\Database\Reader; include_once __DIR__ . '/../shared/api.php'; @@ -477,11 +479,13 @@ $utopia->get('/v1/database/collections/:collectionId/documents') ->param('orderType', 'ASC', function () { return new WhiteList(array('DESC', 'ASC')); }, 'Order direction. Possible values are DESC for descending order, or ASC for ascending order.', true) ->param('orderCast', '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 the first document. Pass 1 for true or 0 for false. The default value is 0. This option refers to the first element in your current documents range (limit/offset), and not the entire collection.', true) - ->param('last', 0, function () { return new Range(0, 1); }, 'Return only the last document. Pass 1 for true or 0 for false. The default value is 0. This option refers to the last element in your current documents range (limit/offset), and not the entire collection.', true) + ->param('first', false, function () { return new Boolean(true); }, 'Return only the first document. Pass 1 for true or 0 for false. The default value is 0. This option refers to the first element in your current documents range (limit/offset), and not the entire collection.', true) + ->param('last', false, function () { return new Boolean(true); }, 'Return only the last document. Pass 1 for true or 0 for false. The default value is 0. This option refers to the last element in your current documents range (limit/offset), and not the entire collection.', true) ->action( function ($collectionId, $filters, $offset, $limit, $orderField, $orderType, $orderCast, $search, $first, $last) use ($response, $projectDB, $isDev) { $collection = $projectDB->getDocument($collectionId, $isDev); + $first = ($first === '1' || $first === 'true' || $first === 1 || $first === true); + $last = ($last === '1' || $last === 'true' || $last === 1 || $last === true); if (\is_null($collection->getId()) || Database::SYSTEM_COLLECTION_COLLECTIONS != $collection->getCollection()) { throw new Exception('Collection not found', 404); diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 4511c34807..10145074c2 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -19,6 +19,7 @@ use Appwrite\Database\Document; use Appwrite\Database\Validator\UID; use Appwrite\OpenSSL\OpenSSL; use Appwrite\Network\Validator\CNAME; +use Appwrite\Utopia\Validator\Boolean; use Cron\CronExpression; include_once __DIR__ . '/../shared/api.php'; @@ -448,7 +449,7 @@ $utopia->post('/v1/projects/:projectId/webhooks') ->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('security', false, function () { return new Boolean(true); }, 'Certificate verification, false for disabled or true 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( @@ -459,6 +460,7 @@ $utopia->post('/v1/projects/:projectId/webhooks') throw new Exception('Project not found', 404); } + $security = ($security === '1' || $security === 'true' || $security === 1 || $security === true); $key = $request->getServer('_APP_OPENSSL_KEY_V1'); $iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM)); $tag = null; @@ -578,8 +580,7 @@ $utopia->put('/v1/projects/:projectId/webhooks/:webhookId') ->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('security', false, function () { return new Boolean(true); }, 'Certificate verification, false for disabled or true 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) { @@ -589,6 +590,7 @@ $utopia->put('/v1/projects/:projectId/webhooks/:webhookId') throw new Exception('Project not found', 404); } + $security = ($security === '1' || $security === 'true' || $security === 1 || $security === true); $key = $request->getServer('_APP_OPENSSL_KEY_V1'); $iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM)); $tag = null; @@ -819,8 +821,7 @@ $utopia->post('/v1/projects/:projectId/tasks') ->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 CRON 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('security', false, function () { return new Boolean(true); }, 'Certificate verification, false for disabled or true 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) @@ -836,6 +837,7 @@ $utopia->post('/v1/projects/:projectId/tasks') $cron = CronExpression::factory($schedule); $next = ($status == 'play') ? $cron->getNextRunDate()->format('U') : null; + $security = ($security === '1' || $security === 'true' || $security === 1 || $security === true); $key = $request->getServer('_APP_OPENSSL_KEY_V1'); $iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM)); $tag = null; @@ -966,7 +968,7 @@ $utopia->put('/v1/projects/:projectId/tasks/:taskId') ->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 CRON syntax.') - ->param('security', null, function () { return new Range(0, 1); }, 'Certificate verification, 0 for disabled or 1 for enabled.') + ->param('security', false, function () { return new Boolean(true); }, 'Certificate verification, false for disabled or true 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) @@ -989,6 +991,7 @@ $utopia->put('/v1/projects/:projectId/tasks/:taskId') $cron = CronExpression::factory($schedule); $next = ($status == 'play') ? $cron->getNextRunDate()->format('U') : null; + $security = ($security === '1' || $security === 'true' || $security === 1 || $security === true); $key = $request->getServer('_APP_OPENSSL_KEY_V1'); $iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM)); $tag = null; diff --git a/app/controllers/web/home.php b/app/controllers/web/home.php index cfec346b91..8dda07111c 100644 --- a/app/controllers/web/home.php +++ b/app/controllers/web/home.php @@ -453,6 +453,10 @@ $utopia->get('/open-api-2.json') $node['type'] = 'string'; $node['x-example'] = '['.\strtoupper(fromCamelCase($node['name'])).']'; break; + case 'Utopia\Validator\Boolean': + $node['type'] = 'boolean'; + $node['x-example'] = false; + break; case 'Appwrite\Database\Validator\UID': $node['type'] = 'string'; $node['x-example'] = '['.\strtoupper(fromCamelCase($node['name'])).']'; diff --git a/composer.json b/composer.json index 8af76121cd..51bf3762da 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "appwrite/php-clamav": "1.0.*", - "utopia-php/framework": "0.3.5", + "utopia-php/framework": "0.3.7", "utopia-php/abuse": "0.2.*", "utopia-php/audit": "0.3.*", "utopia-php/cache": "0.2.*", diff --git a/composer.lock b/composer.lock index 459a9bd325..7c452fe458 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9deec50e5a99197511b5efbcaa9593bd", + "content-hash": "1df9fdb337c6030db4bb5f0e9868f9c3", "packages": [ { "name": "appwrite/php-clamav", @@ -1546,16 +1546,16 @@ }, { "name": "utopia-php/domains", - "version": "0.2.0", + "version": "0.2.1", "source": { "type": "git", "url": "https://github.com/utopia-php/domains.git", - "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73" + "reference": "98e85296867a59c9d712d6ed768a5c5b2b297b43" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/domains/zipball/1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", - "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", + "url": "https://api.github.com/repos/utopia-php/domains/zipball/98e85296867a59c9d712d6ed768a5c5b2b297b43", + "reference": "98e85296867a59c9d712d6ed768a5c5b2b297b43", "shasum": "" }, "require": { @@ -1592,20 +1592,20 @@ "upf", "utopia" ], - "time": "2020-02-23T07:40:02+00:00" + "time": "2020-06-20T11:47:04+00:00" }, { "name": "utopia-php/framework", - "version": "0.3.5", + "version": "0.3.7", "source": { "type": "git", "url": "https://github.com/utopia-php/framework.git", - "reference": "ca2ebe37936983d786f57bae8ee6e006299f4942" + "reference": "23156b3d604fd9586f2e8c6c449b2fc6a82c10bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/framework/zipball/ca2ebe37936983d786f57bae8ee6e006299f4942", - "reference": "ca2ebe37936983d786f57bae8ee6e006299f4942", + "url": "https://api.github.com/repos/utopia-php/framework/zipball/23156b3d604fd9586f2e8c6c449b2fc6a82c10bc", + "reference": "23156b3d604fd9586f2e8c6c449b2fc6a82c10bc", "shasum": "" }, "require": { @@ -1636,7 +1636,7 @@ "php", "upf" ], - "time": "2020-06-20T11:33:46+00:00" + "time": "2020-06-21T11:29:58+00:00" }, { "name": "utopia-php/locale", From a3aeecfd0db1ee8b2efdd719aebda7b828044c00 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 21 Jun 2020 15:12:13 +0300 Subject: [PATCH 04/20] Removed first and last params --- CHANGES.md | 3 +++ app/controllers/api/database.php | 46 +++++++++++++------------------- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 233301df9e..9833893b5d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -32,6 +32,9 @@ - Fixed missing custom scopes param for OAuth2 session create API route - Fixed wrong JSON validation when creating and updating database documnets +## Breaking Changes +- **Deprecated** `first` and `last` query params for documents list route in the database API + ## Security - Access to Health API now requires authentication with an API Key with access to `health.read` scope allowed diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index d8ecedab84..957d90d7b5 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -477,10 +477,8 @@ $utopia->get('/v1/database/collections/:collectionId/documents') ->param('orderType', 'ASC', function () { return new WhiteList(array('DESC', 'ASC')); }, 'Order direction. Possible values are DESC for descending order, or ASC for ascending order.', true) ->param('orderCast', '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 the 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 the 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) { + function ($collectionId, $filters, $offset, $limit, $orderField, $orderType, $orderCast, $search) use ($response, $projectDB, $isDev) { $collection = $projectDB->getDocument($collectionId, $isDev); if (\is_null($collection->getId()) || Database::SYSTEM_COLLECTION_COLLECTIONS != $collection->getCollection()) { @@ -494,38 +492,32 @@ $utopia->get('/v1/database/collections/:collectionId/documents') 'orderType' => $orderType, 'orderCast' => $orderCast, 'search' => $search, - 'first' => (bool) $first, - 'last' => (bool) $last, 'filters' => \array_merge($filters, [ '$collection='.$collectionId, ]), ]); - if ($first || $last) { - $response->json((!empty($list) ? $list->getArrayCopy() : [])); - } else { - if ($isDev) { - $collection - ->setAttribute('debug', $projectDB->getDebug()) - ->setAttribute('limit', $limit) - ->setAttribute('offset', $offset) - ->setAttribute('orderField', $orderField) - ->setAttribute('orderType', $orderType) - ->setAttribute('orderCast', $orderCast) - ->setAttribute('filters', $filters) - ; - } - + if ($isDev) { $collection - ->setAttribute('sum', $projectDB->getSum()) - ->setAttribute('documents', $list) + ->setAttribute('debug', $projectDB->getDebug()) + ->setAttribute('limit', $limit) + ->setAttribute('offset', $offset) + ->setAttribute('orderField', $orderField) + ->setAttribute('orderType', $orderType) + ->setAttribute('orderCast', $orderCast) + ->setAttribute('filters', $filters) ; - - /* - * View - */ - $response->json($collection->getArrayCopy(/*['$id', '$collection', 'name', 'documents']*/[], ['rules'])); } + + $collection + ->setAttribute('sum', $projectDB->getSum()) + ->setAttribute('documents', $list) + ; + + /* + * View + */ + $response->json($collection->getArrayCopy(/*['$id', '$collection', 'name', 'documents']*/[], ['rules'])); } ); From 2bc181a057da8ea94d0faaf87680fb234590e108 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 21 Jun 2020 15:18:00 +0300 Subject: [PATCH 05/20] Fixed tests --- app/controllers/api/avatars.php | 2 +- app/controllers/api/projects.php | 3 +-- public/index.php | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/avatars.php b/app/controllers/api/avatars.php index 86c85700e9..b3486f3583 100644 --- a/app/controllers/api/avatars.php +++ b/app/controllers/api/avatars.php @@ -3,6 +3,7 @@ global $utopia, $request, $response; use Utopia\Exception; +use Utopia\Validator\Boolean; use Utopia\Validator\Text; use Utopia\Validator\WhiteList; use Utopia\Validator\Range; @@ -11,7 +12,6 @@ use Utopia\Cache\Cache; use Utopia\Cache\Adapter\Filesystem; use Appwrite\Resize\Resize; use Appwrite\URL\URL as URLParse; -use Appwrite\Utopia\Validator\Boolean; use BaconQrCode\Renderer\ImageRenderer; use BaconQrCode\Renderer\Image\ImagickImageBackEnd; use BaconQrCode\Renderer\RendererStyle\RendererStyle; diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 10145074c2..799987114b 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -5,10 +5,10 @@ global $utopia, $request, $response, $register, $user, $consoleDB, $projectDB, $ use Utopia\Exception; use Utopia\Response; use Utopia\Validator\ArrayList; +use Utopia\Validator\Boolean; use Utopia\Validator\Domain as DomainValidator; use Utopia\Validator\Text; use Utopia\Validator\WhiteList; -use Utopia\Validator\Range; use Utopia\Validator\URL; use Utopia\Config\Config; use Utopia\Domains\Domain; @@ -19,7 +19,6 @@ use Appwrite\Database\Document; use Appwrite\Database\Validator\UID; use Appwrite\OpenSSL\OpenSSL; use Appwrite\Network\Validator\CNAME; -use Appwrite\Utopia\Validator\Boolean; use Cron\CronExpression; include_once __DIR__ . '/../shared/api.php'; diff --git a/public/index.php b/public/index.php index f6cd63710c..a3f608a7a5 100644 --- a/public/index.php +++ b/public/index.php @@ -11,9 +11,9 @@ error_reporting(0); ini_set('display_errors', 0); -// ini_set('display_errors', 1); -// ini_set('display_startup_errors', 1); -// error_reporting(E_ALL); +ini_set('display_errors', 1); +ini_set('display_startup_errors', 1); +error_reporting(E_ALL); $path = (isset($_GET['q'])) ? explode('/', $_GET['q']) : []; $domain = (isset($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : ''; From 1eb6f43ec90eef1ac7719e522477bb6fb454a48d Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 21 Jun 2020 15:18:53 +0300 Subject: [PATCH 06/20] Fixed debugging --- public/index.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/index.php b/public/index.php index a3f608a7a5..f6cd63710c 100644 --- a/public/index.php +++ b/public/index.php @@ -11,9 +11,9 @@ error_reporting(0); ini_set('display_errors', 0); -ini_set('display_errors', 1); -ini_set('display_startup_errors', 1); -error_reporting(E_ALL); +// ini_set('display_errors', 1); +// ini_set('display_startup_errors', 1); +// error_reporting(E_ALL); $path = (isset($_GET['q'])) ? explode('/', $_GET['q']) : []; $domain = (isset($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : ''; From bd073da05e816a18adfaece67f2f7566a3bf14c0 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 21 Jun 2020 15:23:50 +0300 Subject: [PATCH 07/20] Fixed tests --- tests/e2e/Services/Database/DatabaseBase.php | 35 -------------------- 1 file changed, 35 deletions(-) diff --git a/tests/e2e/Services/Database/DatabaseBase.php b/tests/e2e/Services/Database/DatabaseBase.php index 60dc1f81cc..7e68940104 100644 --- a/tests/e2e/Services/Database/DatabaseBase.php +++ b/tests/e2e/Services/Database/DatabaseBase.php @@ -317,41 +317,6 @@ trait DatabaseBase return []; } - /** - * @depends testCreateDocument - */ - public function testListDocumentsFirstAndLast(array $data):array - { - $documents = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/documents', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'limit' => 1, - 'orderField' => 'releaseYear', - 'orderType' => 'ASC', - 'orderCast' => 'int', - 'first' => true, - ]); - - $this->assertEquals(1944, $documents['body']['releaseYear']); - - $documents = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/documents', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'limit' => 2, - 'offset' => 1, - 'orderField' => 'releaseYear', - 'orderType' => 'ASC', - 'orderCast' => 'int', - 'last' => true, - ]); - - $this->assertEquals(2019, $documents['body']['releaseYear']); - - return []; - } - /** * @depends testCreateDocument */ From 7c2969b967c6f107a3970e56baf7d33eed0236d2 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Fri, 26 Jun 2020 17:41:13 +0300 Subject: [PATCH 08/20] Removed first and last from internal functions --- app/controllers/api/account.php | 24 ++++++++-------------- app/controllers/api/teams.php | 6 ++---- app/controllers/api/users.php | 3 +-- app/workers/certificates.php | 3 +-- src/Appwrite/Database/Database.php | 32 ++++++++++++++++++++---------- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index a7c1c2c534..10665bf740 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -80,9 +80,8 @@ $utopia->post('/v1/account') } } - $profile = $projectDB->getCollection([ // Get user by email address + $profile = $projectDB->getCollectionFirst([ // Get user by email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, 'email='.$email, @@ -163,9 +162,8 @@ $utopia->post('/v1/account/sessions') ->action( function ($email, $password) use ($response, $request, $projectDB, $audit, $webhook) { $protocol = Config::getParam('protocol'); - $profile = $projectDB->getCollection([ // Get user by email address + $profile = $projectDB->getCollectionFirst([ // Get user by email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, 'email='.$email, @@ -414,9 +412,8 @@ $utopia->get('/v1/account/sessions/oauth2/:provider/redirect') $projectDB->deleteDocument($current); //throw new Exception('User already logged in', 401); } - $user = (empty($user->getId())) ? $projectDB->getCollection([ // Get user by provider id + $user = (empty($user->getId())) ? $projectDB->getCollectionFirst([ // Get user by provider id 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, 'oauth2'.\ucfirst($provider).'='.$oauth2ID, @@ -427,9 +424,8 @@ $utopia->get('/v1/account/sessions/oauth2/:provider/redirect') $name = $oauth2->getUserName($accessToken); $email = $oauth2->getUserEmail($accessToken); - $user = $projectDB->getCollection([ // Get user by provider email address + $user = $projectDB->getCollectionFirst([ // Get user by provider email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, 'email='.$email, @@ -797,9 +793,8 @@ $utopia->patch('/v1/account/email') throw new Exception('Invalid credentials', 401); } - $profile = $projectDB->getCollection([ // Get user by email address + $profile = $projectDB->getCollectionFirst([ // Get user by email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, 'email='.$email, @@ -1056,9 +1051,8 @@ $utopia->post('/v1/account/recovery') ->param('url', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the recovery email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.') ->action( function ($email, $url) use ($request, $response, $projectDB, $mail, $audit, $project) { - $profile = $projectDB->getCollection([ // Get user by email address + $profile = $projectDB->getCollectionFirst([ // Get user by email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, 'email='.$email, @@ -1161,9 +1155,8 @@ $utopia->put('/v1/account/recovery') throw new Exception('Passwords must match', 400); } - $profile = $projectDB->getCollection([ // Get user by email address + $profile = $projectDB->getCollectionFirst([ // Get user by email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, '$id='.$userId, @@ -1311,9 +1304,8 @@ $utopia->put('/v1/account/verification') ->param('secret', '', function () { return new Text(256); }, 'Valid verification token.') ->action( function ($userId, $secret) use ($response, $user, $projectDB, $audit) { - $profile = $projectDB->getCollection([ // Get user by email address + $profile = $projectDB->getCollectionFirst([ // Get user by email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, '$id='.$userId, diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index b8e0bf1194..95dad48562 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -232,9 +232,8 @@ $utopia->post('/v1/teams/:teamId/memberships') ], ]); - $invitee = $projectDB->getCollection([ // Get user by email address + $invitee = $projectDB->getCollectionFirst([ // Get user by email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, 'email='.$email, @@ -480,9 +479,8 @@ $utopia->patch('/v1/teams/:teamId/memberships/:inviteId/status') } if (empty($user->getId())) { - $user = $projectDB->getCollection([ // Get user + $user = $projectDB->getCollectionFirst([ // Get user 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, '$id='.$userId, diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index d032cef947..1324c559ac 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -35,9 +35,8 @@ $utopia->post('/v1/users') ->param('name', '', function () { return new Text(100); }, 'User name.', true) ->action( function ($email, $password, $name) use ($response, $projectDB) { - $profile = $projectDB->getCollection([ // Get user by email address + $profile = $projectDB->getCollectionFirst([ // Get user by email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, 'email='.$email, diff --git a/app/workers/certificates.php b/app/workers/certificates.php index b04c7409c0..22c3a14e63 100644 --- a/app/workers/certificates.php +++ b/app/workers/certificates.php @@ -77,7 +77,7 @@ class CertificatesV1 } } - $certificate = $consoleDB->getCollection([ + $certificate = $consoleDB->getCollectionFirst([ 'limit' => 1, 'offset' => 0, 'orderField' => 'id', @@ -87,7 +87,6 @@ class CertificatesV1 '$collection='.Database::SYSTEM_COLLECTION_CERTIFICATES, 'domain='.$domain->get(), ], - 'first' => true, ]); // $condition = ($certificate diff --git a/src/Appwrite/Database/Database.php b/src/Appwrite/Database/Database.php index e75eb01b51..45b61cd089 100644 --- a/src/Appwrite/Database/Database.php +++ b/src/Appwrite/Database/Database.php @@ -130,8 +130,6 @@ class Database 'orderField' => '$id', 'orderType' => 'ASC', 'orderCast' => 'int', - 'first' => false, - 'last' => false, 'filters' => [], ], $options); @@ -141,17 +139,31 @@ class Database $node = new Document($node); } - if ($options['first']) { - $results = \reset($results); - } - - if ($options['last']) { - $results = \end($results); - } - return $results; } + /** + * @param array $options + * + * @return Document + */ + public function getCollectionFirst(array $options) + { + $results = $this->getCollection($options); + return \reset($results); + } + + /** + * @param array $options + * + * @return Document + */ + public function getCollectionLast(array $options) + { + $results = $this->getCollection($options); + return \end($results); + } + /** * @param int $id * @param bool $mock is mocked data allowed? From 0ff3fda3aca3ef21f6bccc05ee29fe69ce07c995 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 28 Jun 2020 00:37:55 +0300 Subject: [PATCH 09/20] Fix for Missing redirect error on redirect from OAuth when using the self-hosted instance success URL #454 --- app/controllers/api/account.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 3bce54eafa..8df3d3993a 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -29,8 +29,8 @@ use DeviceDetector\DeviceDetector; use GeoIp2\Database\Reader; use Utopia\Validator\ArrayList; -$oauthDefaultSuccess = $request->getServer('_APP_HOME').'/auth/oauth2/success'; -$oauthDefaultFailure = $request->getServer('_APP_HOME').'/auth/oauth2/failure'; +$oauthDefaultSuccess = Config::getParam('protocol').'://'.Config::getParam('domain').'/auth/oauth2/success'; +$oauthDefaultFailure = Config::getParam('protocol').'://'.Config::getParam('domain').'/auth/oauth2/failure'; $oauth2Keys = []; @@ -509,7 +509,7 @@ $utopia->get('/v1/account/sessions/oauth2/:provider/redirect') ; } - if ($state['success'] === $oauthDefaultSuccess) { // Add keys for non-web platforms + if (substr($state['success'], 0, strlen($oauthDefaultSuccess) === $oauthDefaultSuccess)) { // Add keys for non-web platforms $state['success'] = URLParser::parse($state['success']); $query = URLParser::parseQuery($state['success']['query']); $query['project'] = $project->getId(); From fbddc7c7eb074532a0f038d68605f9ce9dd14c11 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 28 Jun 2020 01:30:03 +0300 Subject: [PATCH 10/20] Unable to use GitHub OAuth provider Fixes #456 --- src/Appwrite/Auth/OAuth2.php | 2 +- src/Appwrite/Auth/OAuth2/GitHub.php | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Appwrite/Auth/OAuth2.php b/src/Appwrite/Auth/OAuth2.php index 2882746608..5a92049fce 100644 --- a/src/Appwrite/Auth/OAuth2.php +++ b/src/Appwrite/Auth/OAuth2.php @@ -138,7 +138,7 @@ abstract class OAuth2 \curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); \curl_setopt($ch, CURLOPT_HEADER, 0); \curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - \curl_setopt($ch, CURLOPT_USERAGENT, ''); + \curl_setopt($ch, CURLOPT_USERAGENT, 'Appwrite OAuth2'); if (!empty($payload)) { \curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); diff --git a/src/Appwrite/Auth/OAuth2/GitHub.php b/src/Appwrite/Auth/OAuth2/GitHub.php index 882f2d3f2a..73a0793e9e 100644 --- a/src/Appwrite/Auth/OAuth2/GitHub.php +++ b/src/Appwrite/Auth/OAuth2/GitHub.php @@ -15,7 +15,7 @@ class Github extends OAuth2 * @var array */ protected $scopes = [ - 'user:email' + 'user', ]; /** @@ -78,6 +78,7 @@ class Github extends OAuth2 { $user = $this->getUser($accessToken); + var_dump($user); if (isset($user['id'])) { return $user['id']; } @@ -125,7 +126,7 @@ class Github extends OAuth2 * @return array */ protected function getUser(string $accessToken) - { + { if (empty($this->user)) { $this->user = \json_decode($this->request('GET', 'https://api.github.com/user', ['Authorization: token '.\urlencode($accessToken)]), true); } From caefe03bc30e769b14843fa2b3713f073d3b5f20 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 28 Jun 2020 01:39:35 +0300 Subject: [PATCH 11/20] Unable to use GitHub OAuth provider Fixes #456 --- docker-compose.yml | 2 +- src/Appwrite/Auth/OAuth2/GitHub.php | 136 ---------------------------- 2 files changed, 1 insertion(+), 137 deletions(-) delete mode 100644 src/Appwrite/Auth/OAuth2/GitHub.php diff --git a/docker-compose.yml b/docker-compose.yml index 26a2ed016f..2a8265d00d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -50,7 +50,7 @@ services: - ./phpunit.xml:/usr/share/nginx/html/phpunit.xml - ./tests:/usr/share/nginx/html/tests - ./app:/usr/share/nginx/html/app - # - ./vendor:/usr/share/nginx/html/vendor + - ./vendor:/usr/share/nginx/html/vendor - ./docs:/usr/share/nginx/html/docs - ./public:/usr/share/nginx/html/public - ./src:/usr/share/nginx/html/src diff --git a/src/Appwrite/Auth/OAuth2/GitHub.php b/src/Appwrite/Auth/OAuth2/GitHub.php deleted file mode 100644 index 73a0793e9e..0000000000 --- a/src/Appwrite/Auth/OAuth2/GitHub.php +++ /dev/null @@ -1,136 +0,0 @@ - $this->appID, - 'redirect_uri' => $this->callback, - 'scope' => \implode(' ', $this->getScopes()), - 'state' => \json_encode($this->state) - ]); - } - - /** - * @param string $code - * - * @return string - */ - public function getAccessToken(string $code):string - { - $accessToken = $this->request( - 'POST', - 'https://github.com/login/oauth/access_token', - [], - \http_build_query([ - 'client_id' => $this->appID, - 'redirect_uri' => $this->callback, - 'client_secret' => $this->appSecret, - 'code' => $code - ]) - ); - - $output = []; - - \parse_str($accessToken, $output); - - if (isset($output['access_token'])) { - return $output['access_token']; - } - - return ''; - } - - /** - * @param $accessToken - * - * @return string - */ - public function getUserID(string $accessToken):string - { - $user = $this->getUser($accessToken); - - var_dump($user); - if (isset($user['id'])) { - return $user['id']; - } - - return ''; - } - - /** - * @param $accessToken - * - * @return string - */ - public function getUserEmail(string $accessToken):string - { - $emails = \json_decode($this->request('GET', 'https://api.github.com/user/emails', ['Authorization: token '.\urlencode($accessToken)]), true); - - foreach ($emails as $email) { - if ($email['primary'] && $email['verified']) { - return $email['email']; - } - } - - return ''; - } - - /** - * @param $accessToken - * - * @return string - */ - public function getUserName(string $accessToken):string - { - $user = $this->getUser($accessToken); - - if (isset($user['name'])) { - return $user['name']; - } - - return ''; - } - - /** - * @param string $accessToken - * - * @return array - */ - protected function getUser(string $accessToken) - { - if (empty($this->user)) { - $this->user = \json_decode($this->request('GET', 'https://api.github.com/user', ['Authorization: token '.\urlencode($accessToken)]), true); - } - - return $this->user; - } -} From e1387b5e809c02dba67ccbc28975bccffc9c7bc1 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 28 Jun 2020 01:40:36 +0300 Subject: [PATCH 12/20] Fixed capital letter issue --- src/Appwrite/Auth/OAuth2/Github.php | 136 ++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 src/Appwrite/Auth/OAuth2/Github.php diff --git a/src/Appwrite/Auth/OAuth2/Github.php b/src/Appwrite/Auth/OAuth2/Github.php new file mode 100644 index 0000000000..73a0793e9e --- /dev/null +++ b/src/Appwrite/Auth/OAuth2/Github.php @@ -0,0 +1,136 @@ + $this->appID, + 'redirect_uri' => $this->callback, + 'scope' => \implode(' ', $this->getScopes()), + 'state' => \json_encode($this->state) + ]); + } + + /** + * @param string $code + * + * @return string + */ + public function getAccessToken(string $code):string + { + $accessToken = $this->request( + 'POST', + 'https://github.com/login/oauth/access_token', + [], + \http_build_query([ + 'client_id' => $this->appID, + 'redirect_uri' => $this->callback, + 'client_secret' => $this->appSecret, + 'code' => $code + ]) + ); + + $output = []; + + \parse_str($accessToken, $output); + + if (isset($output['access_token'])) { + return $output['access_token']; + } + + return ''; + } + + /** + * @param $accessToken + * + * @return string + */ + public function getUserID(string $accessToken):string + { + $user = $this->getUser($accessToken); + + var_dump($user); + if (isset($user['id'])) { + return $user['id']; + } + + return ''; + } + + /** + * @param $accessToken + * + * @return string + */ + public function getUserEmail(string $accessToken):string + { + $emails = \json_decode($this->request('GET', 'https://api.github.com/user/emails', ['Authorization: token '.\urlencode($accessToken)]), true); + + foreach ($emails as $email) { + if ($email['primary'] && $email['verified']) { + return $email['email']; + } + } + + return ''; + } + + /** + * @param $accessToken + * + * @return string + */ + public function getUserName(string $accessToken):string + { + $user = $this->getUser($accessToken); + + if (isset($user['name'])) { + return $user['name']; + } + + return ''; + } + + /** + * @param string $accessToken + * + * @return array + */ + protected function getUser(string $accessToken) + { + if (empty($this->user)) { + $this->user = \json_decode($this->request('GET', 'https://api.github.com/user', ['Authorization: token '.\urlencode($accessToken)]), true); + } + + return $this->user; + } +} From 8c5ae66b77e1a37720af7dce24dcffd0c5dc33aa Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 28 Jun 2020 01:56:48 +0300 Subject: [PATCH 13/20] Require less permissions by default --- src/Appwrite/Auth/OAuth2/Github.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Auth/OAuth2/Github.php b/src/Appwrite/Auth/OAuth2/Github.php index 73a0793e9e..cd02252092 100644 --- a/src/Appwrite/Auth/OAuth2/Github.php +++ b/src/Appwrite/Auth/OAuth2/Github.php @@ -15,7 +15,7 @@ class Github extends OAuth2 * @var array */ protected $scopes = [ - 'user', + 'user:email', ]; /** From a8848e770fb928619b9a6739c32f1b6ba9ed5649 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 28 Jun 2020 08:58:16 +0300 Subject: [PATCH 14/20] Updated deps --- composer.lock | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/composer.lock b/composer.lock index 595045b9b5..a7d030f06a 100644 --- a/composer.lock +++ b/composer.lock @@ -2141,24 +2141,23 @@ "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "790426f28bfcbfc1a6f1d59ee8c986edfa45395c" + "reference": "664187301bfbc87e686df212094e6817805c3ab8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/790426f28bfcbfc1a6f1d59ee8c986edfa45395c", - "reference": "790426f28bfcbfc1a6f1d59ee8c986edfa45395c", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/664187301bfbc87e686df212094e6817805c3ab8", + "reference": "664187301bfbc87e686df212094e6817805c3ab8", "shasum": "" }, "require": { - "ext-filter": "^7.1", - "php": "^7.2", + "ext-filter": "*", + "php": "^7.2 || ^8.0", "phpdocumentor/reflection-common": "^2.0", "phpdocumentor/type-resolver": "^1.0", "webmozart/assert": "^1" }, "require-dev": { - "doctrine/instantiator": "^1", - "mockery/mockery": "^1" + "mockery/mockery": "1.3.*" }, "type": "library", "extra": { @@ -2186,7 +2185,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2020-06-19T18:58:43+00:00" + "time": "2020-06-27T17:33:53+00:00" }, { "name": "phpdocumentor/type-resolver", From 3a67ccb522a42a4f76ee9b90756da6491ba3cc7b Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 28 Jun 2020 10:59:52 +0300 Subject: [PATCH 15/20] Accept appwrite self hosted instances --- app/controllers/api/account.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 8df3d3993a..516a2a258d 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -29,8 +29,8 @@ use DeviceDetector\DeviceDetector; use GeoIp2\Database\Reader; use Utopia\Validator\ArrayList; -$oauthDefaultSuccess = Config::getParam('protocol').'://'.Config::getParam('domain').'/auth/oauth2/success'; -$oauthDefaultFailure = Config::getParam('protocol').'://'.Config::getParam('domain').'/auth/oauth2/failure'; +$oauthDefaultSuccess = '/auth/oauth2/success'; +$oauthDefaultFailure = '/auth/oauth2/failure'; $oauth2Keys = []; @@ -508,8 +508,9 @@ $utopia->get('/v1/account/sessions/oauth2/:provider/redirect') ->addHeader('X-Fallback-Cookies', \json_encode([Auth::$cookieName => Auth::encodeSession($user->getId(), $secret)])) ; } - - if (substr($state['success'], 0, strlen($oauthDefaultSuccess) === $oauthDefaultSuccess)) { // Add keys for non-web platforms + + // Add keys for non-web platforms - TODO - add verification phase to aviod session sniffing + if (parse_url($state['success'], PHP_URL_PATH) === $oauthDefaultSuccess) { $state['success'] = URLParser::parse($state['success']); $query = URLParser::parseQuery($state['success']['query']); $query['project'] = $project->getId(); From fa5dddb2b94558717badda9e4f91dab03b851dd0 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 28 Jun 2020 11:59:23 +0300 Subject: [PATCH 16/20] Updated change log --- CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 0fd4bc1bca..f9c56062c7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -34,6 +34,8 @@ - Fixed wrong JSON validation when creating and updating database documnets - Fixed bug where max file size was limited to max of 10MB - Fixed bug preventing the deletion of the project logo +- Fixed Bug when trying to overwrite OAuth cookie in the Flutter SDK +- Fixed OAuth redirect when using the self-hosted instance default success URL ([#454](https://github.com/appwrite/appwrite/issues/454)) ## Security From d1587e5ceeaffcc3cdad14941fa3f287da89f474 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 28 Jun 2020 12:00:12 +0300 Subject: [PATCH 17/20] Unable to use GitHub OAuth provider Fixes #456 --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 2a8265d00d..0ec0701b70 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -50,7 +50,7 @@ services: - ./phpunit.xml:/usr/share/nginx/html/phpunit.xml - ./tests:/usr/share/nginx/html/tests - ./app:/usr/share/nginx/html/app - - ./vendor:/usr/share/nginx/html/vendor + # - ./vendor:/usr/share/nginx/html/vendor - ./docs:/usr/share/nginx/html/docs - ./public:/usr/share/nginx/html/public - ./src:/usr/share/nginx/html/src From a6158178346d7f2c1eaf17bad19db69876deb5e6 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 28 Jun 2020 12:04:27 +0300 Subject: [PATCH 18/20] Updated changelog --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index f9c56062c7..ce47a26783 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -36,6 +36,7 @@ - Fixed bug preventing the deletion of the project logo - Fixed Bug when trying to overwrite OAuth cookie in the Flutter SDK - Fixed OAuth redirect when using the self-hosted instance default success URL ([#454](https://github.com/appwrite/appwrite/issues/454)) +- Fixed bug denying authentication with Github OAuth provider ## Security From b2b716048ec72a8dd5ce06124c170fcc1e6a09db Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 28 Jun 2020 21:35:12 +0300 Subject: [PATCH 19/20] Updated deps --- composer.json | 4 ---- composer.lock | 21 --------------------- 2 files changed, 25 deletions(-) diff --git a/composer.json b/composer.json index dbb78bfb17..78b0fd76cc 100644 --- a/composer.json +++ b/composer.json @@ -32,11 +32,7 @@ "appwrite/php-clamav": "1.0.*", -<<<<<<< HEAD - "utopia-php/framework": "0.3.7", -======= "utopia-php/framework": "0.4.0", ->>>>>>> 17b9dc76a60403ef4e680ee92f3c845a5762effd "utopia-php/abuse": "0.2.*", "utopia-php/audit": "0.3.*", "utopia-php/cache": "0.2.*", diff --git a/composer.lock b/composer.lock index 957ddf5d19..a7d030f06a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,11 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], -<<<<<<< HEAD - "content-hash": "1df9fdb337c6030db4bb5f0e9868f9c3", -======= "content-hash": "7f6cbe77fe2e0f8bdff33c37a4d9ca11", ->>>>>>> 17b9dc76a60403ef4e680ee92f3c845a5762effd "packages": [ { "name": "appwrite/php-clamav", @@ -1600,18 +1596,6 @@ }, { "name": "utopia-php/framework", -<<<<<<< HEAD - "version": "0.3.7", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/framework.git", - "reference": "23156b3d604fd9586f2e8c6c449b2fc6a82c10bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/framework/zipball/23156b3d604fd9586f2e8c6c449b2fc6a82c10bc", - "reference": "23156b3d604fd9586f2e8c6c449b2fc6a82c10bc", -======= "version": "0.4.0", "source": { "type": "git", @@ -1622,7 +1606,6 @@ "type": "zip", "url": "https://api.github.com/repos/utopia-php/framework/zipball/30aeb2aeecf8ea2ab83242efad0f5f9fab8d4be5", "reference": "30aeb2aeecf8ea2ab83242efad0f5f9fab8d4be5", ->>>>>>> 17b9dc76a60403ef4e680ee92f3c845a5762effd "shasum": "" }, "require": { @@ -1653,11 +1636,7 @@ "php", "upf" ], -<<<<<<< HEAD - "time": "2020-06-21T11:29:58+00:00" -======= "time": "2020-06-25T18:21:48+00:00" ->>>>>>> 17b9dc76a60403ef4e680ee92f3c845a5762effd }, { "name": "utopia-php/locale", From 8ee9943468c93b2030e4c89d9ddd83b696d52735 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 28 Jun 2020 21:38:16 +0300 Subject: [PATCH 20/20] Updated changelog --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index ce47a26783..49b0f5d1fc 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -19,6 +19,7 @@ - Added container names to docker-compose.yml (@drandell) - Upgraded ClamAV container image to version 1.0.9 - Optimised function execution by using fully-qualified function calls +- Added support for boolean 'true' and 'false' in query strings alongside 1 and 0 ## Bug Fixes