From e1457618002e69258b225276d7544f67486d1eb9 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Tue, 15 Mar 2022 01:02:24 +0400 Subject: [PATCH 001/242] feat: use build timeout when building runtime --- app/executor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/executor.php b/app/executor.php index 1fa32599ab..528591e2c1 100644 --- a/app/executor.php +++ b/app/executor.php @@ -247,7 +247,7 @@ App::post('/v1/runtimes') command: $commands, stdout: $stdout, stderr: $stderr, - timeout: App::getEnv('_APP_FUNCTIONS_TIMEOUT', 900) + timeout: App::getEnv('_APP_FUNCTIONS_BUILD_TIMEOUT', 900) ); if (!$status) { From d17e252f931c115a69088f13e43c43a1281b7acd Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Tue, 15 Mar 2022 15:56:00 +0400 Subject: [PATCH 002/242] feat: handle errros better in the executor --- app/executor.php | 57 +++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 35 deletions(-) diff --git a/app/executor.php b/app/executor.php index 528591e2c1..aca46c17a1 100644 --- a/app/executor.php +++ b/app/executor.php @@ -455,45 +455,32 @@ App::post('/v1/execution') \curl_close($ch); - // If timeout error - if (in_array($errNo, [CURLE_OPERATION_TIMEDOUT, 110])) { - $statusCode = 124; + switch (true) { + /** No Error. */ + case $errNo === 0: break; + /** Connection Refused. Runtime not ready for requests yet . 111 is the swoole error code for Connection Refused */ + case $errNo === 111: + throw new Exception('An internal curl error has occurred within the executor! Error Msg: ' . $error, 406); + /** Every other CURL error */ + default: + throw new Exception('An internal curl error has occurred within the executor! Error Msg: ' . $error, 500); } - - // 110 is the Swoole error code for timeout, see: https://www.swoole.co.uk/docs/swoole-error-code - if ($errNo !== 0 && $errNo !== CURLE_COULDNT_CONNECT && $errNo !== CURLE_OPERATION_TIMEDOUT && $errNo !== 110) { - throw new Exception('An internal curl error has occurred within the executor! Error Msg: ' . $error, 406); + + switch (true) { + case $statusCode >= 500: + $stderr = $executorResponse ?? 'Internal Runtime error.'; + break; + case $statusCode >= 200: + $stdout = $executorResponse; + break; + default: + $stderr = $executorResponse ?? 'Execution failed.'; + break; } - - $executionData = []; - - if (!empty($executorResponse)) { - $executionData = json_decode($executorResponse, true); - } - - if (isset($executionData['code'])) { - $statusCode = $executionData['code']; - } - - if ($statusCode === 500) { - if (isset($executionData['message'])) { - $stderr = $executionData['message']; - } else { - $stderr = 'Internal Runtime error'; - } - } else if ($statusCode === 124) { - $stderr = 'Execution timed out.'; - } else if ($statusCode === 0) { - $stderr = 'Execution failed.'; - } else if ($statusCode >= 200 && $statusCode < 300) { - $stdout = $executorResponse; - } else { - $stderr = 'Execution failed.'; - } - + $executionEnd = \microtime(true); $executionTime = ($executionEnd - $executionStart); - $functionStatus = ($statusCode >= 200 && $statusCode < 300) ? 'completed' : 'failed'; + $functionStatus = ($statusCode >= 500) ? 'failed' : 'completed'; Console::success('Function executed in ' . $executionTime . ' seconds, status: ' . $functionStatus); From 1728833307f71d0eced06096305f597f8a7a04a1 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Tue, 15 Mar 2022 16:04:43 +0400 Subject: [PATCH 003/242] feat: update error message --- app/executor.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/executor.php b/app/executor.php index aca46c17a1..7948a73feb 100644 --- a/app/executor.php +++ b/app/executor.php @@ -458,10 +458,10 @@ App::post('/v1/execution') switch (true) { /** No Error. */ case $errNo === 0: break; - /** Connection Refused. Runtime not ready for requests yet . 111 is the swoole error code for Connection Refused */ + /** Runtime not ready for requests yet. 111 is the swoole error code for Connection Refused - see https://openswoole.com/docs/swoole-error-code */ case $errNo === 111: throw new Exception('An internal curl error has occurred within the executor! Error Msg: ' . $error, 406); - /** Every other CURL error */ + /** Any other CURL error */ default: throw new Exception('An internal curl error has occurred within the executor! Error Msg: ' . $error, 500); } From ee056e582f274403dddddb2518d030de79473eab Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Tue, 15 Mar 2022 17:06:05 +0400 Subject: [PATCH 004/242] feat: function execution time for failed executions --- app/controllers/api/functions.php | 3 +++ app/executor.php | 2 +- app/workers/functions.php | 3 +++ tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 2 +- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index d491b7d75b..8293da16ba 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -960,6 +960,9 @@ App::post('/v1/functions/:functionId/executions') $execution->setAttribute('stderr', $executionResponse['stderr']); $execution->setAttribute('time', $executionResponse['time']); } catch (\Throwable $th) { + $endtime = \time(); + $time = $endtime - $execution->getAttribute('dateCreated'); + $execution->setAttribute('time', $time); $execution->setAttribute('status', 'failed'); $execution->setAttribute('statusCode', $th->getCode()); $execution->setAttribute('stderr', $th->getMessage()); diff --git a/app/executor.php b/app/executor.php index 7948a73feb..d96e86f7d9 100644 --- a/app/executor.php +++ b/app/executor.php @@ -470,7 +470,7 @@ App::post('/v1/execution') case $statusCode >= 500: $stderr = $executorResponse ?? 'Internal Runtime error.'; break; - case $statusCode >= 200: + case $statusCode >= 100: $stdout = $executorResponse; break; default: diff --git a/app/workers/functions.php b/app/workers/functions.php index 2d4cdb2e54..41e685a4dd 100644 --- a/app/workers/functions.php +++ b/app/workers/functions.php @@ -307,6 +307,9 @@ class FunctionsV1 extends Worker $execution->setAttribute('stderr', $executionResponse['stderr']); $execution->setAttribute('time', $executionResponse['time']); } catch (\Throwable $th) { + $endtime = \time(); + $time = $endtime - $execution->getAttribute('dateCreated'); + $execution->setAttribute('time', $time); $execution->setAttribute('status', 'failed'); $execution->setAttribute('statusCode', $th->getCode()); $execution->setAttribute('stderr', $th->getMessage()); diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index e26f93ad34..274a9f07b1 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -761,7 +761,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals($executions['body']['executions'][0]['$id'], $executionId); $this->assertEquals($executions['body']['executions'][0]['trigger'], 'http'); $this->assertEquals($executions['body']['executions'][0]['status'], 'failed'); - $this->assertEquals($executions['body']['executions'][0]['statusCode'], 124); + $this->assertEquals($executions['body']['executions'][0]['statusCode'], 500); $this->assertGreaterThan(2, $executions['body']['executions'][0]['time']); $this->assertLessThan(3, $executions['body']['executions'][0]['time']); $this->assertEquals($executions['body']['executions'][0]['stdout'], ''); From 13b28e0051f73e540de55770a4ebf4d1ad44e1c2 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Tue, 15 Mar 2022 18:51:32 +0400 Subject: [PATCH 005/242] feat: update test message --- app/controllers/api/functions.php | 2 +- app/executor.php | 3 ++- app/workers/functions.php | 3 ++- src/Executor/Executor.php | 6 ++++-- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 4 ++-- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 8293da16ba..5b076b1c59 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -960,7 +960,7 @@ App::post('/v1/functions/:functionId/executions') $execution->setAttribute('stderr', $executionResponse['stderr']); $execution->setAttribute('time', $executionResponse['time']); } catch (\Throwable $th) { - $endtime = \time(); + $endtime = \microtime(true); $time = $endtime - $execution->getAttribute('dateCreated'); $execution->setAttribute('time', $time); $execution->setAttribute('status', 'failed'); diff --git a/app/executor.php b/app/executor.php index d96e86f7d9..50133225ca 100644 --- a/app/executor.php +++ b/app/executor.php @@ -457,7 +457,8 @@ App::post('/v1/execution') switch (true) { /** No Error. */ - case $errNo === 0: break; + case $errNo === 0: + break; /** Runtime not ready for requests yet. 111 is the swoole error code for Connection Refused - see https://openswoole.com/docs/swoole-error-code */ case $errNo === 111: throw new Exception('An internal curl error has occurred within the executor! Error Msg: ' . $error, 406); diff --git a/app/workers/functions.php b/app/workers/functions.php index 41e685a4dd..6ab1289a20 100644 --- a/app/workers/functions.php +++ b/app/workers/functions.php @@ -287,6 +287,7 @@ class FunctionsV1 extends Worker $vars = \array_merge($function->getAttribute('vars', []), $vars); /** Execute function */ + $startTime = microtime(true); try { $executionResponse = $this->executor->createExecution( projectId: $projectId, @@ -307,7 +308,7 @@ class FunctionsV1 extends Worker $execution->setAttribute('stderr', $executionResponse['stderr']); $execution->setAttribute('time', $executionResponse['time']); } catch (\Throwable $th) { - $endtime = \time(); + $endtime = \microtime(true); $time = $endtime - $execution->getAttribute('dateCreated'); $execution->setAttribute('time', $time); $execution->setAttribute('status', 'failed'); diff --git a/src/Executor/Executor.php b/src/Executor/Executor.php index 1a96b3561b..213db074c1 100644 --- a/src/Executor/Executor.php +++ b/src/Executor/Executor.php @@ -161,12 +161,14 @@ class Executor 'timeout' => $timeout, ]; - /* Add 2 seconds as a buffer to the actual timeout value since there can be a slight variance*/ - $requestTimeout = $timeout + 2; + /* Add 1 second as a buffer to the actual timeout value since there can be a slight variance*/ + $requestTimeout = $timeout + 1; $response = $this->call(self::METHOD_POST, $route, $headers, $params, true, $requestTimeout); $status = $response['headers']['status-code']; + var_dump($response); + var_dump($status); for ($attempts = 0; $attempts < 10; $attempts++) { try { switch (true) { diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 274a9f07b1..f2b29d6317 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -763,9 +763,9 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals($executions['body']['executions'][0]['status'], 'failed'); $this->assertEquals($executions['body']['executions'][0]['statusCode'], 500); $this->assertGreaterThan(2, $executions['body']['executions'][0]['time']); - $this->assertLessThan(3, $executions['body']['executions'][0]['time']); + $this->assertLessThan(6, $executions['body']['executions'][0]['time']); $this->assertEquals($executions['body']['executions'][0]['stdout'], ''); - $this->assertEquals($executions['body']['executions'][0]['stderr'], 'Execution timed out.'); + $this->assertEquals($executions['body']['executions'][0]['stderr'], 'An internal curl error has occurred within the executor! Error Msg: Operation timed out'); // Cleanup : Delete function $response = $this->client->call(Client::METHOD_DELETE, '/functions/'. $functionId, [ From 7a2614ed6d6587ae26871dc5c5a5a5d0f93dc34b Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Tue, 15 Mar 2022 18:53:20 +0400 Subject: [PATCH 006/242] feat: update test message --- app/workers/functions.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/workers/functions.php b/app/workers/functions.php index 6ab1289a20..7033e5aa5c 100644 --- a/app/workers/functions.php +++ b/app/workers/functions.php @@ -287,7 +287,6 @@ class FunctionsV1 extends Worker $vars = \array_merge($function->getAttribute('vars', []), $vars); /** Execute function */ - $startTime = microtime(true); try { $executionResponse = $this->executor->createExecution( projectId: $projectId, From 91bd8983924145f0b96b7ec24434b5dd8c2be78f Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Tue, 15 Mar 2022 18:53:48 +0400 Subject: [PATCH 007/242] feat: remove var_dump --- src/Executor/Executor.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Executor/Executor.php b/src/Executor/Executor.php index 213db074c1..9ba9675f30 100644 --- a/src/Executor/Executor.php +++ b/src/Executor/Executor.php @@ -167,8 +167,6 @@ class Executor $response = $this->call(self::METHOD_POST, $route, $headers, $params, true, $requestTimeout); $status = $response['headers']['status-code']; - var_dump($response); - var_dump($status); for ($attempts = 0; $attempts < 10; $attempts++) { try { switch (true) { From 1fd053a8b7f21d212b9abf8826ae02364b7891f4 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Tue, 15 Mar 2022 18:56:12 +0400 Subject: [PATCH 008/242] feat: remove var_dump --- src/Executor/Executor.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Executor/Executor.php b/src/Executor/Executor.php index 9ba9675f30..1a96b3561b 100644 --- a/src/Executor/Executor.php +++ b/src/Executor/Executor.php @@ -161,8 +161,8 @@ class Executor 'timeout' => $timeout, ]; - /* Add 1 second as a buffer to the actual timeout value since there can be a slight variance*/ - $requestTimeout = $timeout + 1; + /* Add 2 seconds as a buffer to the actual timeout value since there can be a slight variance*/ + $requestTimeout = $timeout + 2; $response = $this->call(self::METHOD_POST, $route, $headers, $params, true, $requestTimeout); $status = $response['headers']['status-code']; From 0dd617d4a752c9d916d0da7b1c42a7518baf10c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 21 Mar 2022 11:29:49 +0000 Subject: [PATCH 009/242] Change default to empty string --- app/executor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/executor.php b/app/executor.php index 1fa32599ab..4ef174ab9c 100644 --- a/app/executor.php +++ b/app/executor.php @@ -396,7 +396,7 @@ App::post('/v1/execution') ->desc('Create an execution') ->param('runtimeId', '', new Text(64), 'The runtimeID to execute') ->param('vars', [], new Assoc(), 'Environment variables required for the build') - ->param('data', '{}', new Text(8192), 'Data to be forwarded to the function, this is user specified.', true) + ->param('data', '', new Text(8192), 'Data to be forwarded to the function, this is user specified.', true) ->param('timeout', 15, new Range(1, (int) App::getEnv('_APP_FUNCTIONS_TIMEOUT', 900)), 'Function maximum execution time in seconds.') ->inject('activeRuntimes') ->inject('response') From 45e9040fa5a0c3a9e8650a27c2d6bae88e34dccb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 21 Mar 2022 14:23:56 +0000 Subject: [PATCH 010/242] Disallow HTTP communication if required --- app/config/errors.php | 5 +++++ app/controllers/general.php | 4 ++++ composer.lock | 28 ++++++++++++++-------------- src/Appwrite/Extend/Exception.php | 1 + 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/app/config/errors.php b/app/config/errors.php index b7b5c1ca31..ca305ed0b5 100644 --- a/app/config/errors.php +++ b/app/config/errors.php @@ -78,6 +78,11 @@ return [ 'description' => 'An internal server error occurred.', 'code' => 500, ], + Exception::GENERAL_FORCED_HTTPS_IGNORED => [ + 'name' => Exception::GENERAL_FORCED_HTTPS_IGNORED, + 'description' => 'Appwrite instance forces secure communication. Switch to HTTPS protocol in your endpoint.', + 'code' => 500, + ], /** User Errors */ Exception::USER_COUNT_EXCEEDED => [ diff --git a/app/controllers/general.php b/app/controllers/general.php index c08c244b31..4cf77bb4bb 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -173,6 +173,10 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons */ if (App::getEnv('_APP_OPTIONS_FORCE_HTTPS', 'disabled') === 'enabled') { // Force HTTPS if ($request->getProtocol() !== 'https') { + if($request->getMethod() !== Request::METHOD_GET) { + throw new Exception('HTTPS communication required.', 500, Exception::GENERAL_FORCED_HTTPS_IGNORED); + } + return $response->redirect('https://'.$request->getHostname().$request->getURI()); } diff --git a/composer.lock b/composer.lock index 291b391b3e..4a9b786b33 100644 --- a/composer.lock +++ b/composer.lock @@ -478,16 +478,16 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.4.1", + "version": "7.4.2", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79" + "reference": "ac1ec1cd9b5624694c3a40be801d94137afb12b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/ee0a041b1760e6a53d2a39c8c34115adc2af2c79", - "reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/ac1ec1cd9b5624694c3a40be801d94137afb12b4", + "reference": "ac1ec1cd9b5624694c3a40be801d94137afb12b4", "shasum": "" }, "require": { @@ -582,7 +582,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.4.1" + "source": "https://github.com/guzzle/guzzle/tree/7.4.2" }, "funding": [ { @@ -598,7 +598,7 @@ "type": "tidelift" } ], - "time": "2021-12-06T18:43:05+00:00" + "time": "2022-03-20T14:16:28+00:00" }, { "name": "guzzlehttp/promises", @@ -686,16 +686,16 @@ }, { "name": "guzzlehttp/psr7", - "version": "2.1.0", + "version": "2.2.1", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "089edd38f5b8abba6cb01567c2a8aaa47cec4c72" + "reference": "c94a94f120803a18554c1805ef2e539f8285f9a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/089edd38f5b8abba6cb01567c2a8aaa47cec4c72", - "reference": "089edd38f5b8abba6cb01567c2a8aaa47cec4c72", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/c94a94f120803a18554c1805ef2e539f8285f9a2", + "reference": "c94a94f120803a18554c1805ef2e539f8285f9a2", "shasum": "" }, "require": { @@ -719,7 +719,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } }, "autoload": { @@ -781,7 +781,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.1.0" + "source": "https://github.com/guzzle/psr7/tree/2.2.1" }, "funding": [ { @@ -797,7 +797,7 @@ "type": "tidelift" } ], - "time": "2021-10-06T17:43:30+00:00" + "time": "2022-03-20T21:55:58+00:00" }, { "name": "influxdb/influxdb-php", @@ -6580,5 +6580,5 @@ "platform-overrides": { "php": "8.0" }, - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.2.0" } diff --git a/src/Appwrite/Extend/Exception.php b/src/Appwrite/Extend/Exception.php index 4f396990fd..a5858d662b 100644 --- a/src/Appwrite/Extend/Exception.php +++ b/src/Appwrite/Extend/Exception.php @@ -46,6 +46,7 @@ class Exception extends \Exception const GENERAL_ROUTE_NOT_FOUND = 'general_route_not_found'; const GENERAL_CURSOR_NOT_FOUND = 'general_cursor_not_found'; const GENERAL_SERVER_ERROR = 'general_server_error'; + const GENERAL_FORCED_HTTPS_IGNORED = 'general_forced_https_ignored'; /** Users */ const USER_COUNT_EXCEEDED = 'user_count_exceeded'; From 95d5f7a6592c150eed7df30d3fcb6e8385db1a66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Wed, 23 Mar 2022 08:23:27 +0000 Subject: [PATCH 011/242] Added veritifcation status modal --- app/views/console/users/user.phtml | 35 ++++++++++++++++++++++++++++++ composer.lock | 28 ++++++++++++------------ 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/app/views/console/users/user.phtml b/app/views/console/users/user.phtml index e769ef4bb1..689ae9146c 100644 --- a/app/views/console/users/user.phtml +++ b/app/views/console/users/user.phtml @@ -119,6 +119,40 @@ + + \ No newline at end of file diff --git a/composer.lock b/composer.lock index 3084527702..ca66336799 100644 --- a/composer.lock +++ b/composer.lock @@ -2250,16 +2250,16 @@ }, { "name": "utopia-php/framework", - "version": "0.19.9", + "version": "0.19.20", "source": { "type": "git", "url": "https://github.com/utopia-php/framework.git", - "reference": "4af9fc866edce1b8cff94731fb26c27599118e87" + "reference": "65ced168db8f6e188ceeb0d101f57552c3d8b2af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/framework/zipball/4af9fc866edce1b8cff94731fb26c27599118e87", - "reference": "4af9fc866edce1b8cff94731fb26c27599118e87", + "url": "https://api.github.com/repos/utopia-php/framework/zipball/65ced168db8f6e188ceeb0d101f57552c3d8b2af", + "reference": "65ced168db8f6e188ceeb0d101f57552c3d8b2af", "shasum": "" }, "require": { @@ -2293,9 +2293,9 @@ ], "support": { "issues": "https://github.com/utopia-php/framework/issues", - "source": "https://github.com/utopia-php/framework/tree/0.19.9" + "source": "https://github.com/utopia-php/framework/tree/0.19.20" }, - "time": "2022-04-14T15:39:47+00:00" + "time": "2022-04-14T15:42:37+00:00" }, { "name": "utopia-php/image", diff --git a/docs/references/teams/get-team-logs.md b/docs/references/teams/get-team-logs.md new file mode 100644 index 0000000000..65e685499d --- /dev/null +++ b/docs/references/teams/get-team-logs.md @@ -0,0 +1 @@ +Get the team activity logs list by its unique ID. \ No newline at end of file diff --git a/public/dist/scripts/app-all.js b/public/dist/scripts/app-all.js index 23968d7bbe..8924a1cbcf 100644 --- a/public/dist/scripts/app-all.js +++ b/public/dist/scripts/app-all.js @@ -5,7 +5,7 @@ function rejected(value){try{step(generator["throw"](value));}catch(e){reject(e) function step(result){result.done?resolve(result.value):adopt(result.value).then(fulfilled,rejected);} step((generator=generator.apply(thisArg,_arguments||[])).next());});} class AppwriteException extends Error{constructor(message,code=0,type='',response=''){super(message);this.name='AppwriteException';this.message=message;this.code=code;this.type=type;this.response=response;}} -class Appwrite{constructor(){this.config={endpoint:'https://HOSTNAME/v1',endpointRealtime:'',project:'',key:'',jwt:'',locale:'',mode:'',};this.headers={'x-sdk-version':'appwrite:web:4.0.4','X-Appwrite-Response-Format':'0.13.0',};this.realtime={socket:undefined,timeout:undefined,url:'',channels:new Set(),subscriptions:new Map(),subscriptionsCounter:0,reconnect:true,reconnectAttempts:0,lastMessage:undefined,connect:()=>{clearTimeout(this.realtime.timeout);this.realtime.timeout=window===null||window===void 0?void 0:window.setTimeout(()=>{this.realtime.createSocket();},50);},getTimeout:()=>{switch(true){case this.realtime.reconnectAttempts<5:return 1000;case this.realtime.reconnectAttempts<15:return 5000;case this.realtime.reconnectAttempts<100:return 10000;default:return 60000;}},createSocket:()=>{var _a,_b;if(this.realtime.channels.size<1) +class Appwrite{constructor(){this.config={endpoint:'https://HOSTNAME/v1',endpointRealtime:'',project:'',key:'',jwt:'',locale:'',mode:'',};this.headers={'x-sdk-version':'appwrite:web:5.0.0','X-Appwrite-Response-Format':'0.13.0',};this.realtime={socket:undefined,timeout:undefined,url:'',channels:new Set(),subscriptions:new Map(),subscriptionsCounter:0,reconnect:true,reconnectAttempts:0,lastMessage:undefined,connect:()=>{clearTimeout(this.realtime.timeout);this.realtime.timeout=window===null||window===void 0?void 0:window.setTimeout(()=>{this.realtime.createSocket();},50);},getTimeout:()=>{switch(true){case this.realtime.reconnectAttempts<5:return 1000;case this.realtime.reconnectAttempts<15:return 5000;case this.realtime.reconnectAttempts<100:return 10000;default:return 60000;}},createSocket:()=>{var _a,_b;if(this.realtime.channels.size<1) return;const channels=new URLSearchParams();channels.set('project',this.config.project);this.realtime.channels.forEach(channel=>{channels.append('channels[]',channel);});const url=this.config.endpointRealtime+'/realtime?'+channels.toString();if(url!==this.realtime.url||!this.realtime.socket||((_a=this.realtime.socket)===null||_a===void 0?void 0:_a.readyState)>WebSocket.OPEN){if(this.realtime.socket&&((_b=this.realtime.socket)===null||_b===void 0?void 0:_b.readyState){this.realtime.reconnectAttempts=0;});this.realtime.socket.addEventListener('close',event=>{var _a,_b,_c;if(!this.realtime.reconnect||(((_b=(_a=this.realtime)===null||_a===void 0?void 0:_a.lastMessage)===null||_b===void 0?void 0:_b.type)==='error'&&((_c=this.realtime)===null||_c===void 0?void 0:_c.lastMessage.data).code===1008)){this.realtime.reconnect=true;return;} const timeout=this.realtime.getTimeout();console.error(`Realtime got disconnected. Reconnect will be attempted in ${timeout / 1000} seconds.`,event.reason);setTimeout(()=>{this.realtime.reconnectAttempts++;this.realtime.createSocket();},timeout);});}},onMessage:(event)=>{var _a,_b;try{const message=JSON.parse(event.data);this.realtime.lastMessage=message;switch(message.type){case'connected':const cookie=JSON.parse((_a=window.localStorage.getItem('cookieFallback'))!==null&&_a!==void 0?_a:'{}');const session=cookie===null||cookie===void 0?void 0:cookie[`a_session_${this.config.project}`];const messageData=message.data;if(session&&!messageData.user){(_b=this.realtime.socket)===null||_b===void 0?void 0:_b.send(JSON.stringify({type:'authentication',data:{session}}));} @@ -296,7 +296,7 @@ if(typeof activate!=='undefined'){payload['activate']=activate;} const uri=new URL(this.config.endpoint+path);const size=code.size;if(size<=Appwrite.CHUNK_SIZE){return yield this.call('post',uri,{'content-type':'multipart/form-data',},payload);} let id=undefined;let response=undefined;const headers={'content-type':'multipart/form-data',};let counter=0;const totalCounters=Math.ceil(size/Appwrite.CHUNK_SIZE);for(counter;counter__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');} if(typeof deploymentId==='undefined'){throw new AppwriteException('Missing required parameter: "deploymentId"');} let path='/functions/{functionId}/deployments/{deploymentId}'.replace('{functionId}',functionId).replace('{deploymentId}',deploymentId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateDeployment:(functionId,deploymentId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');} @@ -501,7 +501,7 @@ let id=undefined;let response=undefined;const headers={'content-type':'multipart catch(e){}} for(counter;counter__awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');} if(typeof fileId==='undefined'){throw new AppwriteException('Missing required parameter: "fileId"');} let path='/storage/buckets/{bucketId}/files/{fileId}'.replace('{bucketId}',bucketId).replace('{fileId}',fileId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateFile:(bucketId,fileId,read,write)=>__awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');} @@ -549,7 +549,10 @@ let path='/teams/{teamId}'.replace('{teamId}',teamId);let payload={};const uri=n if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');} let path='/teams/{teamId}'.replace('{teamId}',teamId);let payload={};if(typeof name!=='undefined'){payload['name']=name;} const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),delete:(teamId)=>__awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');} -let path='/teams/{teamId}'.replace('{teamId}',teamId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),getMemberships:(teamId,search,limit,offset,cursor,cursorDirection,orderType)=>__awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');} +let path='/teams/{teamId}'.replace('{teamId}',teamId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listLogs:(teamId,limit,offset)=>__awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');} +let path='/teams/{teamId}/logs'.replace('{teamId}',teamId);let payload={};if(typeof limit!=='undefined'){payload['limit']=limit;} +if(typeof offset!=='undefined'){payload['offset']=offset;} +const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getMemberships:(teamId,search,limit,offset,cursor,cursorDirection,orderType)=>__awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');} let path='/teams/{teamId}/memberships'.replace('{teamId}',teamId);let payload={};if(typeof search!=='undefined'){payload['search']=search;} if(typeof limit!=='undefined'){payload['limit']=limit;} if(typeof offset!=='undefined'){payload['offset']=offset;} @@ -630,7 +633,7 @@ setJWT(value){this.headers['X-Appwrite-JWT']=value;this.config.jwt=value;return setLocale(value){this.headers['X-Appwrite-Locale']=value;this.config.locale=value;return this;} setMode(value){this.headers['X-Appwrite-Mode']=value;this.config.mode=value;return this;} subscribe(channels,callback){let channelArray=typeof channels==='string'?[channels]:channels;channelArray.forEach(channel=>this.realtime.channels.add(channel));const counter=this.realtime.subscriptionsCounter++;this.realtime.subscriptions.set(counter,{channels:channelArray,callback});this.realtime.connect();return()=>{this.realtime.subscriptions.delete(counter);this.realtime.cleanUp(channelArray);this.realtime.connect();};} -call(method,url,headers={},params={}){var _a,_b;return __awaiter(this,void 0,void 0,function*(){method=method.toUpperCase();headers=Object.assign(Object.assign({},headers),this.headers);let options={method,headers,credentials:'include'};if(typeof window!=='undefined'&&window.localStorage){headers['X-Fallback-Cookies']=(_a=window.localStorage.getItem('cookieFallback'))!==null&&_a!==void 0?_a:'';} +call(method,url,headers={},params={}){var _a,_b;return __awaiter(this,void 0,void 0,function*(){method=method.toUpperCase();headers=Object.assign({},this.headers,headers);let options={method,headers,credentials:'include'};if(typeof window!=='undefined'&&window.localStorage){headers['X-Fallback-Cookies']=(_a=window.localStorage.getItem('cookieFallback'))!==null&&_a!==void 0?_a:'';} if(method==='GET'){for(const[key,value]of Object.entries(this.flatten(params))){url.searchParams.append(key,value);}} else{switch(headers['content-type']){case'application/json':options.body=JSON.stringify(params);break;case'multipart/form-data':let formData=new FormData();for(const key in params){if(Array.isArray(params[key])){params[key].forEach((value)=>{formData.append(key+'[]',value);});} else{formData.append(key,params[key]);}} diff --git a/public/dist/scripts/app-dep.js b/public/dist/scripts/app-dep.js index 07160ea78b..7d2781e842 100644 --- a/public/dist/scripts/app-dep.js +++ b/public/dist/scripts/app-dep.js @@ -5,7 +5,7 @@ function rejected(value){try{step(generator["throw"](value));}catch(e){reject(e) function step(result){result.done?resolve(result.value):adopt(result.value).then(fulfilled,rejected);} step((generator=generator.apply(thisArg,_arguments||[])).next());});} class AppwriteException extends Error{constructor(message,code=0,type='',response=''){super(message);this.name='AppwriteException';this.message=message;this.code=code;this.type=type;this.response=response;}} -class Appwrite{constructor(){this.config={endpoint:'https://HOSTNAME/v1',endpointRealtime:'',project:'',key:'',jwt:'',locale:'',mode:'',};this.headers={'x-sdk-version':'appwrite:web:4.0.4','X-Appwrite-Response-Format':'0.13.0',};this.realtime={socket:undefined,timeout:undefined,url:'',channels:new Set(),subscriptions:new Map(),subscriptionsCounter:0,reconnect:true,reconnectAttempts:0,lastMessage:undefined,connect:()=>{clearTimeout(this.realtime.timeout);this.realtime.timeout=window===null||window===void 0?void 0:window.setTimeout(()=>{this.realtime.createSocket();},50);},getTimeout:()=>{switch(true){case this.realtime.reconnectAttempts<5:return 1000;case this.realtime.reconnectAttempts<15:return 5000;case this.realtime.reconnectAttempts<100:return 10000;default:return 60000;}},createSocket:()=>{var _a,_b;if(this.realtime.channels.size<1) +class Appwrite{constructor(){this.config={endpoint:'https://HOSTNAME/v1',endpointRealtime:'',project:'',key:'',jwt:'',locale:'',mode:'',};this.headers={'x-sdk-version':'appwrite:web:5.0.0','X-Appwrite-Response-Format':'0.13.0',};this.realtime={socket:undefined,timeout:undefined,url:'',channels:new Set(),subscriptions:new Map(),subscriptionsCounter:0,reconnect:true,reconnectAttempts:0,lastMessage:undefined,connect:()=>{clearTimeout(this.realtime.timeout);this.realtime.timeout=window===null||window===void 0?void 0:window.setTimeout(()=>{this.realtime.createSocket();},50);},getTimeout:()=>{switch(true){case this.realtime.reconnectAttempts<5:return 1000;case this.realtime.reconnectAttempts<15:return 5000;case this.realtime.reconnectAttempts<100:return 10000;default:return 60000;}},createSocket:()=>{var _a,_b;if(this.realtime.channels.size<1) return;const channels=new URLSearchParams();channels.set('project',this.config.project);this.realtime.channels.forEach(channel=>{channels.append('channels[]',channel);});const url=this.config.endpointRealtime+'/realtime?'+channels.toString();if(url!==this.realtime.url||!this.realtime.socket||((_a=this.realtime.socket)===null||_a===void 0?void 0:_a.readyState)>WebSocket.OPEN){if(this.realtime.socket&&((_b=this.realtime.socket)===null||_b===void 0?void 0:_b.readyState){this.realtime.reconnectAttempts=0;});this.realtime.socket.addEventListener('close',event=>{var _a,_b,_c;if(!this.realtime.reconnect||(((_b=(_a=this.realtime)===null||_a===void 0?void 0:_a.lastMessage)===null||_b===void 0?void 0:_b.type)==='error'&&((_c=this.realtime)===null||_c===void 0?void 0:_c.lastMessage.data).code===1008)){this.realtime.reconnect=true;return;} const timeout=this.realtime.getTimeout();console.error(`Realtime got disconnected. Reconnect will be attempted in ${timeout / 1000} seconds.`,event.reason);setTimeout(()=>{this.realtime.reconnectAttempts++;this.realtime.createSocket();},timeout);});}},onMessage:(event)=>{var _a,_b;try{const message=JSON.parse(event.data);this.realtime.lastMessage=message;switch(message.type){case'connected':const cookie=JSON.parse((_a=window.localStorage.getItem('cookieFallback'))!==null&&_a!==void 0?_a:'{}');const session=cookie===null||cookie===void 0?void 0:cookie[`a_session_${this.config.project}`];const messageData=message.data;if(session&&!messageData.user){(_b=this.realtime.socket)===null||_b===void 0?void 0:_b.send(JSON.stringify({type:'authentication',data:{session}}));} @@ -296,7 +296,7 @@ if(typeof activate!=='undefined'){payload['activate']=activate;} const uri=new URL(this.config.endpoint+path);const size=code.size;if(size<=Appwrite.CHUNK_SIZE){return yield this.call('post',uri,{'content-type':'multipart/form-data',},payload);} let id=undefined;let response=undefined;const headers={'content-type':'multipart/form-data',};let counter=0;const totalCounters=Math.ceil(size/Appwrite.CHUNK_SIZE);for(counter;counter__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');} if(typeof deploymentId==='undefined'){throw new AppwriteException('Missing required parameter: "deploymentId"');} let path='/functions/{functionId}/deployments/{deploymentId}'.replace('{functionId}',functionId).replace('{deploymentId}',deploymentId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateDeployment:(functionId,deploymentId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');} @@ -501,7 +501,7 @@ let id=undefined;let response=undefined;const headers={'content-type':'multipart catch(e){}} for(counter;counter__awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');} if(typeof fileId==='undefined'){throw new AppwriteException('Missing required parameter: "fileId"');} let path='/storage/buckets/{bucketId}/files/{fileId}'.replace('{bucketId}',bucketId).replace('{fileId}',fileId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateFile:(bucketId,fileId,read,write)=>__awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');} @@ -549,7 +549,10 @@ let path='/teams/{teamId}'.replace('{teamId}',teamId);let payload={};const uri=n if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');} let path='/teams/{teamId}'.replace('{teamId}',teamId);let payload={};if(typeof name!=='undefined'){payload['name']=name;} const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),delete:(teamId)=>__awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');} -let path='/teams/{teamId}'.replace('{teamId}',teamId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),getMemberships:(teamId,search,limit,offset,cursor,cursorDirection,orderType)=>__awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');} +let path='/teams/{teamId}'.replace('{teamId}',teamId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listLogs:(teamId,limit,offset)=>__awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');} +let path='/teams/{teamId}/logs'.replace('{teamId}',teamId);let payload={};if(typeof limit!=='undefined'){payload['limit']=limit;} +if(typeof offset!=='undefined'){payload['offset']=offset;} +const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getMemberships:(teamId,search,limit,offset,cursor,cursorDirection,orderType)=>__awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');} let path='/teams/{teamId}/memberships'.replace('{teamId}',teamId);let payload={};if(typeof search!=='undefined'){payload['search']=search;} if(typeof limit!=='undefined'){payload['limit']=limit;} if(typeof offset!=='undefined'){payload['offset']=offset;} @@ -630,7 +633,7 @@ setJWT(value){this.headers['X-Appwrite-JWT']=value;this.config.jwt=value;return setLocale(value){this.headers['X-Appwrite-Locale']=value;this.config.locale=value;return this;} setMode(value){this.headers['X-Appwrite-Mode']=value;this.config.mode=value;return this;} subscribe(channels,callback){let channelArray=typeof channels==='string'?[channels]:channels;channelArray.forEach(channel=>this.realtime.channels.add(channel));const counter=this.realtime.subscriptionsCounter++;this.realtime.subscriptions.set(counter,{channels:channelArray,callback});this.realtime.connect();return()=>{this.realtime.subscriptions.delete(counter);this.realtime.cleanUp(channelArray);this.realtime.connect();};} -call(method,url,headers={},params={}){var _a,_b;return __awaiter(this,void 0,void 0,function*(){method=method.toUpperCase();headers=Object.assign(Object.assign({},headers),this.headers);let options={method,headers,credentials:'include'};if(typeof window!=='undefined'&&window.localStorage){headers['X-Fallback-Cookies']=(_a=window.localStorage.getItem('cookieFallback'))!==null&&_a!==void 0?_a:'';} +call(method,url,headers={},params={}){var _a,_b;return __awaiter(this,void 0,void 0,function*(){method=method.toUpperCase();headers=Object.assign({},this.headers,headers);let options={method,headers,credentials:'include'};if(typeof window!=='undefined'&&window.localStorage){headers['X-Fallback-Cookies']=(_a=window.localStorage.getItem('cookieFallback'))!==null&&_a!==void 0?_a:'';} if(method==='GET'){for(const[key,value]of Object.entries(this.flatten(params))){url.searchParams.append(key,value);}} else{switch(headers['content-type']){case'application/json':options.body=JSON.stringify(params);break;case'multipart/form-data':let formData=new FormData();for(const key in params){if(Array.isArray(params[key])){params[key].forEach((value)=>{formData.append(key+'[]',value);});} else{formData.append(key,params[key]);}} diff --git a/public/scripts/dependencies/appwrite.js b/public/scripts/dependencies/appwrite.js index 1abd519001..6d7d73a2ff 100644 --- a/public/scripts/dependencies/appwrite.js +++ b/public/scripts/dependencies/appwrite.js @@ -48,7 +48,7 @@ mode: '', }; this.headers = { - 'x-sdk-version': 'appwrite:web:4.0.4', + 'x-sdk-version': 'appwrite:web:5.0.0', 'X-Appwrite-Response-Format': '0.13.0', }; this.realtime = { @@ -371,7 +371,7 @@ * * Update currently logged in user password. For validation, user is required * to pass in the new password, and the old password. For users created with - * OAuth and Team Invites, oldPassword is optional. + * OAuth, Team Invites and Magic URL, oldPassword is optional. * * @param {string} password * @param {string} oldPassword @@ -768,6 +768,9 @@ /** * Update Session (Refresh Tokens) * + * Access tokens have limited lifespan and expire to mitigate security risks. + * If session was created using an OAuth provider, this route can be used to + * "refresh" the access token. * * @param {string} sessionId * @throws {AppwriteException} @@ -1923,9 +1926,7 @@ /** * Delete Document * - * Delete a document by its unique ID. This endpoint deletes only the parent - * documents, its attributes and relations to other documents. Child documents - * **will not** be deleted. + * Delete a document by its unique ID. * * @param {string} collectionId * @param {string} documentId @@ -2263,7 +2264,7 @@ }, payload); }), /** - * List the currently active function runtimes. + * List runtimes * * Get a list of all runtimes that are currently active on your instance. * @@ -2488,8 +2489,8 @@ if (onProgress) { onProgress({ $id: response.$id, - progress: Math.min((counter + 1) * Appwrite.CHUNK_SIZE, size) / size * 100, - sizeUploaded: end + 1, + progress: Math.min((counter + 1) * Appwrite.CHUNK_SIZE - 1, size) / size * 100, + sizeUploaded: end, chunksTotal: response.chunksTotal, chunksUploaded: response.chunksUploaded }); @@ -4329,8 +4330,8 @@ if (onProgress) { onProgress({ $id: response.$id, - progress: Math.min((counter + 1) * Appwrite.CHUNK_SIZE, size) / size * 100, - sizeUploaded: end + 1, + progress: Math.min((counter + 1) * Appwrite.CHUNK_SIZE - 1, size) / size * 100, + sizeUploaded: end, chunksTotal: response.chunksTotal, chunksUploaded: response.chunksUploaded }); @@ -4744,6 +4745,34 @@ 'content-type': 'application/json', }, payload); }), + /** + * List Team Logs + * + * Get the team activity logs list by its unique ID. + * + * @param {string} teamId + * @param {number} limit + * @param {number} offset + * @throws {AppwriteException} + * @returns {Promise} + */ + listLogs: (teamId, limit, offset) => __awaiter(this, void 0, void 0, function* () { + if (typeof teamId === 'undefined') { + throw new AppwriteException('Missing required parameter: "teamId"'); + } + let path = '/teams/{teamId}/logs'.replace('{teamId}', teamId); + let payload = {}; + if (typeof limit !== 'undefined') { + payload['limit'] = limit; + } + if (typeof offset !== 'undefined') { + payload['offset'] = offset; + } + const uri = new URL(this.config.endpoint + path); + return yield this.call('get', uri, { + 'content-type': 'application/json', + }, payload); + }), /** * Get Team Memberships * @@ -5536,7 +5565,7 @@ var _a, _b; return __awaiter(this, void 0, void 0, function* () { method = method.toUpperCase(); - headers = Object.assign(Object.assign({}, headers), this.headers); + headers = Object.assign({}, this.headers, headers); let options = { method, headers, From c2be304345c16bc76b52010692dfb5d54a835ea1 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Fri, 22 Apr 2022 14:10:16 +0200 Subject: [PATCH 078/242] fix(ui): improve validation of attributes --- app/views/console/database/collection.phtml | 22 ++++++++++----------- app/views/console/database/document.phtml | 10 ++++++++++ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/app/views/console/database/collection.phtml b/app/views/console/database/collection.phtml index 1bdef71d18..eb045c9f2c 100644 --- a/app/views/console/database/collection.phtml +++ b/app/views/console/database/collection.phtml @@ -621,7 +621,7 @@ $logs = $this->getParam('logs', null); data-failure-param-alert-text="Failed to create attribute" data-failure-param-alert-classname="error" @reset="array = required = false" - x-data="{ array: false, required: false }"> + x-data="{ array: false, required: false, size: null }"> @@ -631,7 +631,7 @@ $logs = $this->getParam('logs', null);
Allowed Characters A-Z, a-z, 0-9, and non-leading underscore, hyphen and dot
- +
  Required @@ -643,7 +643,7 @@ $logs = $this->getParam('logs', null); @@ -197,6 +202,8 @@ $logs = $this->getParam('logs', null); :placeholder="attr.default" :name="attr.key" :required="attr.required" + :min="attr.min" + :max="attr.max" x-model="doc[attr.key][index]" data-cast-to="integer" /> @@ -207,6 +214,8 @@ $logs = $this->getParam('logs', null); :placeholder="attr.default" :name="attr.key" :required="attr.required" + :min="attr.min" + :max="attr.max" x-model="doc[attr.key][index]" data-cast-to="float" /> @@ -226,6 +235,7 @@ $logs = $this->getParam('logs', null); :placeholder="attr.default" :name="attr.key" :required="attr.required" + :maxlength="attr.size" x-model="doc[attr.key][index]" data-cast-to="string"> From 82d30ebc35ad19b03c5d431960e78112d642855e Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Fri, 22 Apr 2022 14:21:04 +0200 Subject: [PATCH 079/242] fix(ui): increase alert time --- public/dist/scripts/app-all.js | 2 +- public/dist/scripts/app.js | 2 +- public/scripts/views/service.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/public/dist/scripts/app-all.js b/public/dist/scripts/app-all.js index ba65cee32d..ea271fea4f 100644 --- a/public/dist/scripts/app-all.js +++ b/public/dist/scripts/app-all.js @@ -3746,7 +3746,7 @@ if(this.getFile(id)){this.updateFile(id,{name:file.name,completed:false,failed:f target.reset();try{const response=await sdk.storage.createFile(bucketId,fileId,file,read,write,(progress)=>{this.updateFile(id,{id:progress.$id,progress:Math.round(progress.progress),error:"",});id=progress.$id;const file=this.getFile(id)??{};if(file.cancelled===true){throw'USER_CANCELLED';}});const existingFile=this.getFile(id)??{};if(existingFile.cancelled){this.updateFile(id,{id:response.$id,name:response.name,failed:false,});id=response.$id;throw'USER_CANCELLED'}else{this.updateFile(id,{id:response.$id,name:response.name,progress:100,completed:true,failed:false,});id=response.$id;} document.dispatchEvent(new CustomEvent('storage.createFile'));}catch(error){if(error==='USER_CANCELLED'){await sdk.storage.deleteFile(bucketId,id);this.updateFile(id,{cancelled:false,failed:true,});this.removeFile(id);}else{this.updateFile(id,{id:id,failed:true,error:error.message??error});} document.dispatchEvent(new CustomEvent('storage.createFile'));}}});});})(window);(function(window){"use strict";window.ls.view.add({selector:"data-service",controller:function(element,view,container,form,alerts,expression,window){let action=element.dataset["service"];let service=element.dataset["name"]||null;let event=expression.parse(element.dataset["event"]);let confirm=element.dataset["confirm"]||"";let loading=element.dataset["loading"]||"";let loaderId=null;let scope=element.dataset["scope"]||"sdk";let success=element.dataset["success"]||"";let failure=element.dataset["failure"]||"";let running=false;let callbacks={hide:function(){return function(){return element.style.opacity='0';};},reset:function(){return function(){if("FORM"===element.tagName){return element.reset();} -throw new Error("This callback is only valid for forms");};},alert:function(text,classname){return function(alerts){alerts.add({text:text,class:classname||"success"},3000);};},redirect:function(url){return function(router){if(url==="/console"){window.location=url;return;} +throw new Error("This callback is only valid for forms");};},alert:function(text,classname){return function(alerts){alerts.add({text:text,class:classname||"success"},6000);};},redirect:function(url){return function(router){if(url==="/console"){window.location=url;return;} router.change(url||"/");};},reload:function(){return function(router){router.reload();};},state:function(keys){let updateQueryString=function(key,value,url){var re=new RegExp("([?&])"+key+"=.*?(&|#|$)(.*)","gi"),hash;if(re.test(url)){if(typeof value!=="undefined"&&value!==null){return url.replace(re,"$1"+key+"="+value+"$2$3");}else{hash=url.split("#");url=hash[0].replace(re,"$1$3").replace(/(&|\?)$/,"");if(typeof hash[1]!=="undefined"&&hash[1]!==null){url+="#"+hash[1];} return url;}}else{if(typeof value!=="undefined"&&value!==null){var separator=url.indexOf("?")!==-1?"&":"?";hash=url.split("#");url=hash[0]+separator+key+"="+value;if(typeof hash[1]!=="undefined"&&hash[1]!==null){url+="#"+hash[1];} return url;}else{return url;}}};keys=keys.split(",").map(element=>element.trim());return function(serviceForm,router,window){let url=window.location.href;keys.map(node=>{node=node.split("=");let key=node[0]||"";let name=node[1]||key;let value=getValue(key,"param",serviceForm);url=updateQueryString(name,value?value:null,url);});if(url!==window.location.href){window.history.pushState({},"",url);router.reset();}};},trigger:function(events){return function(document){events=events.trim().split(",");for(let i=0;i{this.updateFile(id,{id:progress.$id,progress:Math.round(progress.progress),error:"",});id=progress.$id;const file=this.getFile(id)??{};if(file.cancelled===true){throw'USER_CANCELLED';}});const existingFile=this.getFile(id)??{};if(existingFile.cancelled){this.updateFile(id,{id:response.$id,name:response.name,failed:false,});id=response.$id;throw'USER_CANCELLED'}else{this.updateFile(id,{id:response.$id,name:response.name,progress:100,completed:true,failed:false,});id=response.$id;} document.dispatchEvent(new CustomEvent('storage.createFile'));}catch(error){if(error==='USER_CANCELLED'){await sdk.storage.deleteFile(bucketId,id);this.updateFile(id,{cancelled:false,failed:true,});this.removeFile(id);}else{this.updateFile(id,{id:id,failed:true,error:error.message??error});} document.dispatchEvent(new CustomEvent('storage.createFile'));}}});});})(window);(function(window){"use strict";window.ls.view.add({selector:"data-service",controller:function(element,view,container,form,alerts,expression,window){let action=element.dataset["service"];let service=element.dataset["name"]||null;let event=expression.parse(element.dataset["event"]);let confirm=element.dataset["confirm"]||"";let loading=element.dataset["loading"]||"";let loaderId=null;let scope=element.dataset["scope"]||"sdk";let success=element.dataset["success"]||"";let failure=element.dataset["failure"]||"";let running=false;let callbacks={hide:function(){return function(){return element.style.opacity='0';};},reset:function(){return function(){if("FORM"===element.tagName){return element.reset();} -throw new Error("This callback is only valid for forms");};},alert:function(text,classname){return function(alerts){alerts.add({text:text,class:classname||"success"},3000);};},redirect:function(url){return function(router){if(url==="/console"){window.location=url;return;} +throw new Error("This callback is only valid for forms");};},alert:function(text,classname){return function(alerts){alerts.add({text:text,class:classname||"success"},6000);};},redirect:function(url){return function(router){if(url==="/console"){window.location=url;return;} router.change(url||"/");};},reload:function(){return function(router){router.reload();};},state:function(keys){let updateQueryString=function(key,value,url){var re=new RegExp("([?&])"+key+"=.*?(&|#|$)(.*)","gi"),hash;if(re.test(url)){if(typeof value!=="undefined"&&value!==null){return url.replace(re,"$1"+key+"="+value+"$2$3");}else{hash=url.split("#");url=hash[0].replace(re,"$1$3").replace(/(&|\?)$/,"");if(typeof hash[1]!=="undefined"&&hash[1]!==null){url+="#"+hash[1];} return url;}}else{if(typeof value!=="undefined"&&value!==null){var separator=url.indexOf("?")!==-1?"&":"?";hash=url.split("#");url=hash[0]+separator+key+"="+value;if(typeof hash[1]!=="undefined"&&hash[1]!==null){url+="#"+hash[1];} return url;}else{return url;}}};keys=keys.split(",").map(element=>element.trim());return function(serviceForm,router,window){let url=window.location.href;keys.map(node=>{node=node.split("=");let key=node[0]||"";let name=node[1]||key;let value=getValue(key,"param",serviceForm);url=updateQueryString(name,value?value:null,url);});if(url!==window.location.href){window.history.pushState({},"",url);router.reset();}};},trigger:function(events){return function(document){events=events.trim().split(",");for(let i=0;i Date: Mon, 25 Apr 2022 09:00:31 +0000 Subject: [PATCH 080/242] Fix typo --- 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 fa7fddfccd..637e158a45 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -31,7 +31,7 @@ use Appwrite\Network\Validator\IP; use Appwrite\Network\Validator\URL; use Appwrite\Utopia\Database\Validator\CustomId; use Appwrite\Utopia\Database\Validator\Queries as QueriesValidator; -use Appwrite\Utopia\Database\Validator\OrderAttributes as OrderAttributesValudator; +use Appwrite\Utopia\Database\Validator\OrderAttributes as OrderAttributesValidator; use Appwrite\Utopia\Response; use Appwrite\Detector\Detector; use Appwrite\Event\Event; @@ -1744,7 +1744,7 @@ App::get('/v1/database/collections/:collectionId/documents') } if(!empty($orderAttributes)) { - $validator = new OrderAttributesValudator($collection->getAttribute('attributes', []), $collection->getAttribute('indexes', []), true); + $validator = new OrderAttributesValidator($collection->getAttribute('attributes', []), $collection->getAttribute('indexes', []), true); if (!$validator->isValid($orderAttributes)) { throw new Exception($validator->getDescription(), 400, Exception::GENERAL_QUERY_INVALID); } From 023e9f0f73e6f8f551a2eedeb282523bbc6424f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 25 Apr 2022 09:03:03 +0000 Subject: [PATCH 081/242] Fix spacings --- src/Appwrite/Network/Validator/Host.php | 2 +- src/Appwrite/Network/Validator/Origin.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Network/Validator/Host.php b/src/Appwrite/Network/Validator/Host.php index b993903d10..c81a931f37 100644 --- a/src/Appwrite/Network/Validator/Host.php +++ b/src/Appwrite/Network/Validator/Host.php @@ -1,8 +1,8 @@ Date: Mon, 25 Apr 2022 09:04:08 +0000 Subject: [PATCH 082/242] Add const usage --- app/controllers/general.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index b39e9ea4ce..eacf926955 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -12,6 +12,7 @@ use Appwrite\Extend\Exception; use Utopia\Config\Config; use Utopia\Domains\Domain; use Appwrite\Auth\Auth; +use Appwrite\Event\Event; use Appwrite\Network\Validator\Origin; use Appwrite\Utopia\Response\Filters\V11 as ResponseV11; use Appwrite\Utopia\Response\Filters\V12 as ResponseV12; @@ -101,7 +102,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons Console::info('Issuing a TLS certificate for the main domain (' . $domain->get() . ') in a few seconds...'); - Resque::enqueue('v1-certificates', 'CertificatesV1', [ + Resque::enqueue(Event::CERTIFICATES_QUEUE_NAME, Event::CERTIFICATES_CLASS_NAME, [ 'document' => $domainDocument, 'domain' => $domain->get(), 'validateTarget' => false, From 4c82810d619a79a7cb2425eae511f57348ea1d8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 25 Apr 2022 09:12:43 +0000 Subject: [PATCH 083/242] PR review changes --- app/config/errors.php | 8 ++++---- app/controllers/general.php | 2 +- src/Appwrite/Extend/Exception.php | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/config/errors.php b/app/config/errors.php index 9c1da2c540..8dadcf079c 100644 --- a/app/config/errors.php +++ b/app/config/errors.php @@ -78,10 +78,10 @@ return [ 'description' => 'An internal server error occurred.', 'code' => 500, ], - Exception::GENERAL_METHOD_UNSUPPORTED => [ - 'name' => Exception::GENERAL_METHOD_UNSUPPORTED, - 'description' => 'The HTTP method is unsupported by the current protocol or resource.', - 'code' => 405, + Exception::GENERAL_PROTOCOL_UNSUPPORTED => [ + 'name' => Exception::GENERAL_PROTOCOL_UNSUPPORTED, + 'description' => 'The request cannot be fulfilled with the current protocol. Please check the value of the _APP_OPTIONS_FORCE_HTTPS environment variable.', + 'code' => 500, ], /** User Errors */ diff --git a/app/controllers/general.php b/app/controllers/general.php index 443d32140b..4cb2d9232e 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -174,7 +174,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons if (App::getEnv('_APP_OPTIONS_FORCE_HTTPS', 'disabled') === 'enabled') { // Force HTTPS if ($request->getProtocol() !== 'https') { if($request->getMethod() !== Request::METHOD_GET) { - throw new Exception('Method unsupported over HTTP.', 405, Exception::GENERAL_METHOD_UNSUPPORTED); + throw new Exception('Method unsupported over HTTP.', 500, Exception::GENERAL_PROTOCOL_UNSUPPORTED); } return $response->redirect('https://'.$request->getHostname().$request->getURI()); diff --git a/src/Appwrite/Extend/Exception.php b/src/Appwrite/Extend/Exception.php index 04b44b57b2..ee5d6ab729 100644 --- a/src/Appwrite/Extend/Exception.php +++ b/src/Appwrite/Extend/Exception.php @@ -46,7 +46,7 @@ class Exception extends \Exception const GENERAL_ROUTE_NOT_FOUND = 'general_route_not_found'; const GENERAL_CURSOR_NOT_FOUND = 'general_cursor_not_found'; const GENERAL_SERVER_ERROR = 'general_server_error'; - const GENERAL_METHOD_UNSUPPORTED = 'general_method_unsupported'; + const GENERAL_PROTOCOL_UNSUPPORTED = 'general_protocol_unsupported'; /** Users */ const USER_COUNT_EXCEEDED = 'user_count_exceeded'; From d981c8f5e5d5c796517b60312080722535c120d9 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Mon, 25 Apr 2022 10:12:58 +0100 Subject: [PATCH 084/242] Rename 'stdout' in executions to 'response' --- app/config/collections.php | 2 +- app/controllers/api/functions.php | 4 +- app/executor.php | 4 +- app/workers/functions.php | 4 +- .../Utopia/Response/Model/Execution.php | 4 +- .../Functions/FunctionsCustomClientTest.php | 4 +- .../Functions/FunctionsCustomServerTest.php | 52 +++++++++---------- 7 files changed, 37 insertions(+), 37 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index 3e3de4c7bd..a48eb99c31 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -2121,7 +2121,7 @@ $collections = [ 'filters' => [], ], [ - '$id' => 'stdout', + '$id' => 'response', 'type' => Database::VAR_STRING, 'format' => '', 'size' => 16384, diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index da65d4deb4..2a80c9bb99 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -880,7 +880,7 @@ App::post('/v1/functions/:functionId/executions') 'trigger' => 'http', // http / schedule / event 'status' => 'waiting', // waiting / processing / completed / failed 'statusCode' => 0, - 'stdout' => '', + 'response' => '', 'stderr' => '', 'time' => 0.0, 'search' => implode(' ', [$functionId, $executionId]), @@ -956,7 +956,7 @@ App::post('/v1/functions/:functionId/executions') /** Update execution status */ $execution->setAttribute('status', $executionResponse['status']); $execution->setAttribute('statusCode', $executionResponse['statusCode']); - $execution->setAttribute('stdout', $executionResponse['stdout']); + $execution->setAttribute('response', $executionResponse['response']); $execution->setAttribute('stderr', $executionResponse['stderr']); $execution->setAttribute('time', $executionResponse['time']); } catch (\Throwable $th) { diff --git a/app/executor.php b/app/executor.php index e9f4c21391..104f3db557 100644 --- a/app/executor.php +++ b/app/executor.php @@ -279,7 +279,7 @@ App::post('/v1/runtimes') $endTime = \time(); $container = array_merge($container, [ 'status' => 'ready', - 'stdout' => \utf8_encode($stdout), + 'response' => \utf8_encode($stdout), 'stderr' => \utf8_encode($stderr), 'startTime' => $startTime, 'endTime' => $endTime, @@ -512,7 +512,7 @@ App::post('/v1/execution') $execution = [ 'status' => $functionStatus, 'statusCode' => $statusCode, - 'stdout' => \utf8_encode(\mb_substr($stdout, -16384)), + 'response' => \utf8_encode(\mb_substr($stdout, -16384)), 'stderr' => \utf8_encode(\mb_substr($stderr, -16384)), 'time' => $executionTime, ]; diff --git a/app/workers/functions.php b/app/workers/functions.php index 66464a9d23..96f12fddf7 100644 --- a/app/workers/functions.php +++ b/app/workers/functions.php @@ -254,7 +254,7 @@ class FunctionsV1 extends Worker 'trigger' => $trigger, 'status' => 'waiting', 'statusCode' => 0, - 'stdout' => '', + 'response' => '', 'stderr' => '', 'time' => 0.0, 'search' => implode(' ', [$functionId, $executionId]), @@ -303,7 +303,7 @@ class FunctionsV1 extends Worker /** Update execution status */ $execution->setAttribute('status', $executionResponse['status']); $execution->setAttribute('statusCode', $executionResponse['statusCode']); - $execution->setAttribute('stdout', $executionResponse['stdout']); + $execution->setAttribute('response', $executionResponse['response']); $execution->setAttribute('stderr', $executionResponse['stderr']); $execution->setAttribute('time', $executionResponse['time']); } catch (\Throwable $th) { diff --git a/src/Appwrite/Utopia/Response/Model/Execution.php b/src/Appwrite/Utopia/Response/Model/Execution.php index 31d32ffbb0..a8031bb0cd 100644 --- a/src/Appwrite/Utopia/Response/Model/Execution.php +++ b/src/Appwrite/Utopia/Response/Model/Execution.php @@ -53,9 +53,9 @@ class Execution extends Model 'default' => 0, 'example' => 0, ]) - ->addRule('stdout', [ + ->addRule('response', [ 'type' => self::TYPE_STRING, - 'description' => 'The script stdout output string. Logs the last 4,000 characters of the execution stdout output.', + 'description' => 'The script response output string. Logs the last 4,000 characters of the execution response output.', 'default' => '', 'example' => '', ]) diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index d2443783c0..a895995659 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -208,7 +208,7 @@ class FunctionsCustomClientTest extends Scope 'x-appwrite-key' => $apikey, ]); - $output = json_decode($executions['body']['stdout'], true); + $output = json_decode($executions['body']['response'], true); $this->assertEquals(200, $executions['headers']['status-code']); $this->assertEquals('completed', $executions['body']['status']); $this->assertEquals($functionId, $output['APPWRITE_FUNCTION_ID']); @@ -383,7 +383,7 @@ class FunctionsCustomClientTest extends Scope 'async' => false ]); - $output = json_decode($execution['body']['stdout'], true); + $output = json_decode($execution['body']['response'], true); $this->assertEquals(201, $execution['headers']['status-code']); $this->assertEquals('completed', $execution['body']['status']); $this->assertEquals($functionId, $output['APPWRITE_FUNCTION_ID']); diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index e26f93ad34..3431e13ca9 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -490,7 +490,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals($data['functionId'], $execution['body']['functionId']); $this->assertEquals('waiting', $execution['body']['status']); $this->assertEquals(0, $execution['body']['statusCode']); - $this->assertEquals('', $execution['body']['stdout']); + $this->assertEquals('', $execution['body']['response']); $this->assertEquals('', $execution['body']['stderr']); $this->assertEquals(0, $execution['body']['time']); @@ -507,13 +507,13 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals($data['functionId'], $execution['body']['functionId']); $this->assertEquals('completed', $execution['body']['status']); $this->assertEquals(200, $execution['body']['statusCode']); - $this->assertStringContainsString($execution['body']['functionId'], $execution['body']['stdout']); - $this->assertStringContainsString($data['deploymentId'], $execution['body']['stdout']); - $this->assertStringContainsString('Test1', $execution['body']['stdout']); - $this->assertStringContainsString('http', $execution['body']['stdout']); - $this->assertStringContainsString('PHP', $execution['body']['stdout']); - $this->assertStringContainsString('8.0', $execution['body']['stdout']); - // $this->assertStringContainsString('êä', $execution['body']['stdout']); // tests unknown utf-8 chars + $this->assertStringContainsString($execution['body']['functionId'], $execution['body']['response']); + $this->assertStringContainsString($data['deploymentId'], $execution['body']['response']); + $this->assertStringContainsString('Test1', $execution['body']['response']); + $this->assertStringContainsString('http', $execution['body']['response']); + $this->assertStringContainsString('PHP', $execution['body']['response']); + $this->assertStringContainsString('8.0', $execution['body']['response']); + // $this->assertStringContainsString('êä', $execution['body']['response']); // tests unknown utf-8 chars $this->assertEquals('', $execution['body']['stderr']); $this->assertLessThan(0.500, $execution['body']['time']); @@ -596,11 +596,11 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(201, $execution['headers']['status-code']); $this->assertEquals('completed', $execution['body']['status']); - $this->assertStringContainsString($data['deploymentId'], $execution['body']['stdout']); - $this->assertStringContainsString('Test1', $execution['body']['stdout']); - $this->assertStringContainsString('http', $execution['body']['stdout']); - $this->assertStringContainsString('PHP', $execution['body']['stdout']); - $this->assertStringContainsString('8.0', $execution['body']['stdout']); + $this->assertStringContainsString($data['deploymentId'], $execution['body']['response']); + $this->assertStringContainsString('Test1', $execution['body']['response']); + $this->assertStringContainsString('http', $execution['body']['response']); + $this->assertStringContainsString('PHP', $execution['body']['response']); + $this->assertStringContainsString('8.0', $execution['body']['response']); // $this->assertStringContainsString('êä', $execution['body']['sdtout']); // tests unknown utf-8 chars $this->assertLessThan(0.500, $execution['body']['time']); @@ -764,7 +764,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals($executions['body']['executions'][0]['statusCode'], 124); $this->assertGreaterThan(2, $executions['body']['executions'][0]['time']); $this->assertLessThan(3, $executions['body']['executions'][0]['time']); - $this->assertEquals($executions['body']['executions'][0]['stdout'], ''); + $this->assertEquals($executions['body']['executions'][0]['response'], ''); $this->assertEquals($executions['body']['executions'][0]['stderr'], 'Execution timed out.'); // Cleanup : Delete function @@ -847,7 +847,7 @@ class FunctionsCustomServerTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); - $output = json_decode($executions['body']['stdout'], true); + $output = json_decode($executions['body']['response'], true); $this->assertEquals(200, $executions['headers']['status-code']); $this->assertEquals('completed', $executions['body']['status']); @@ -875,7 +875,7 @@ class FunctionsCustomServerTest extends Scope $this->assertCount(1, $executions['body']['executions']); $this->assertEquals($executions['body']['executions'][0]['$id'], $executionId); $this->assertEquals($executions['body']['executions'][0]['trigger'], 'http'); - $this->assertStringContainsString('foobar', $executions['body']['executions'][0]['stdout']); + $this->assertStringContainsString('foobar', $executions['body']['executions'][0]['response']); // Cleanup : Delete function $response = $this->client->call(Client::METHOD_DELETE, '/functions/'. $functionId, [ @@ -952,7 +952,7 @@ class FunctionsCustomServerTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); - $output = json_decode($executions['body']['stdout'], true); + $output = json_decode($executions['body']['response'], true); $this->assertEquals(200, $executions['headers']['status-code']); $this->assertEquals('completed', $executions['body']['status']); @@ -981,7 +981,7 @@ class FunctionsCustomServerTest extends Scope $this->assertCount(1, $executions['body']['executions']); $this->assertEquals($executions['body']['executions'][0]['$id'], $executionId); $this->assertEquals($executions['body']['executions'][0]['trigger'], 'http'); - $this->assertStringContainsString('foobar', $executions['body']['executions'][0]['stdout']); + $this->assertStringContainsString('foobar', $executions['body']['executions'][0]['response']); // Cleanup : Delete function $response = $this->client->call(Client::METHOD_DELETE, '/functions/'. $functionId, [ @@ -1057,7 +1057,7 @@ class FunctionsCustomServerTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); - $output = json_decode($executions['body']['stdout'], true); + $output = json_decode($executions['body']['response'], true); $this->assertEquals(200, $executions['headers']['status-code']); $this->assertEquals('completed', $executions['body']['status']); @@ -1086,7 +1086,7 @@ class FunctionsCustomServerTest extends Scope $this->assertCount(1, $executions['body']['executions']); $this->assertEquals($executions['body']['executions'][0]['$id'], $executionId); $this->assertEquals($executions['body']['executions'][0]['trigger'], 'http'); - $this->assertStringContainsString('foobar', $executions['body']['executions'][0]['stdout']); + $this->assertStringContainsString('foobar', $executions['body']['executions'][0]['response']); // Cleanup : Delete function $response = $this->client->call(Client::METHOD_DELETE, '/functions/'. $functionId, [ @@ -1162,7 +1162,7 @@ class FunctionsCustomServerTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); - $output = json_decode($executions['body']['stdout'], true); + $output = json_decode($executions['body']['response'], true); $this->assertEquals(200, $executions['headers']['status-code']); $this->assertEquals('completed', $executions['body']['status']); @@ -1191,7 +1191,7 @@ class FunctionsCustomServerTest extends Scope $this->assertCount(1, $executions['body']['executions']); $this->assertEquals($executions['body']['executions'][0]['$id'], $executionId); $this->assertEquals($executions['body']['executions'][0]['trigger'], 'http'); - $this->assertStringContainsString('foobar', $executions['body']['executions'][0]['stdout']); + $this->assertStringContainsString('foobar', $executions['body']['executions'][0]['response']); // Cleanup : Delete function $response = $this->client->call(Client::METHOD_DELETE, '/functions/'. $functionId, [ @@ -1267,7 +1267,7 @@ class FunctionsCustomServerTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); - $output = json_decode($executions['body']['stdout'], true); + $output = json_decode($executions['body']['response'], true); $this->assertEquals(200, $executions['headers']['status-code']); $this->assertEquals('completed', $executions['body']['status']); @@ -1296,7 +1296,7 @@ class FunctionsCustomServerTest extends Scope $this->assertCount(1, $executions['body']['executions']); $this->assertEquals($executions['body']['executions'][0]['$id'], $executionId); $this->assertEquals($executions['body']['executions'][0]['trigger'], 'http'); - $this->assertStringContainsString('foobar', $executions['body']['executions'][0]['stdout']); + $this->assertStringContainsString('foobar', $executions['body']['executions'][0]['response']); // Cleanup : Delete function $response = $this->client->call(Client::METHOD_DELETE, '/functions/'. $functionId, [ @@ -1372,7 +1372,7 @@ class FunctionsCustomServerTest extends Scope // 'x-appwrite-project' => $this->getProject()['$id'], // ], $this->getHeaders())); - // $output = json_decode($executions['body']['stdout'], true); + // $output = json_decode($executions['body']['response'], true); // $this->assertEquals(200, $executions['headers']['status-code']); // $this->assertEquals('completed', $executions['body']['status']); @@ -1401,7 +1401,7 @@ class FunctionsCustomServerTest extends Scope // $this->assertCount(1, $executions['body']['executions']); // $this->assertEquals($executions['body']['executions'][0]['$id'], $executionId); // $this->assertEquals($executions['body']['executions'][0]['trigger'], 'http'); - // $this->assertStringContainsString('foobar', $executions['body']['executions'][0]['stdout']); + // $this->assertStringContainsString('foobar', $executions['body']['executions'][0]['response']); // // Cleanup : Delete function // $response = $this->client->call(Client::METHOD_DELETE, '/functions/'. $functionId, [ From ff28d0d2a190355fdc5f3efa00dbb4319fd48725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 25 Apr 2022 09:26:38 +0000 Subject: [PATCH 085/242] PR review changes --- composer.lock | 34 ++++++++++---------------- docs/references/avatars/get-browser.md | 4 +-- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/composer.lock b/composer.lock index d9d2f30b2b..4cb16a1266 100644 --- a/composer.lock +++ b/composer.lock @@ -2250,16 +2250,16 @@ }, { "name": "utopia-php/framework", - "version": "0.19.8", + "version": "0.19.9", "source": { "type": "git", "url": "https://github.com/utopia-php/framework.git", - "reference": "8c3b3e330546fd6cd65bd1f8d8d08882ff3abb7d" + "reference": "4af9fc866edce1b8cff94731fb26c27599118e87" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/framework/zipball/8c3b3e330546fd6cd65bd1f8d8d08882ff3abb7d", - "reference": "8c3b3e330546fd6cd65bd1f8d8d08882ff3abb7d", + "url": "https://api.github.com/repos/utopia-php/framework/zipball/4af9fc866edce1b8cff94731fb26c27599118e87", + "reference": "4af9fc866edce1b8cff94731fb26c27599118e87", "shasum": "" }, "require": { @@ -2293,9 +2293,9 @@ ], "support": { "issues": "https://github.com/utopia-php/framework/issues", - "source": "https://github.com/utopia-php/framework/tree/0.19.8" + "source": "https://github.com/utopia-php/framework/tree/0.19.9" }, - "time": "2022-04-12T00:28:15+00:00" + "time": "2022-04-14T15:39:47+00:00" }, { "name": "utopia-php/image", @@ -3551,16 +3551,16 @@ }, { "name": "matthiasmullie/minify", - "version": "1.3.66", + "version": "1.3.67", "source": { "type": "git", "url": "https://github.com/matthiasmullie/minify.git", - "reference": "45fd3b0f1dfa2c965857c6d4a470bea52adc31a6" + "reference": "acaee1b7ca3cd67a39d7f98673cacd7e4739a8d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/45fd3b0f1dfa2c965857c6d4a470bea52adc31a6", - "reference": "45fd3b0f1dfa2c965857c6d4a470bea52adc31a6", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/acaee1b7ca3cd67a39d7f98673cacd7e4739a8d9", + "reference": "acaee1b7ca3cd67a39d7f98673cacd7e4739a8d9", "shasum": "" }, "require": { @@ -3609,23 +3609,15 @@ ], "support": { "issues": "https://github.com/matthiasmullie/minify/issues", - "source": "https://github.com/matthiasmullie/minify/tree/1.3.66" + "source": "https://github.com/matthiasmullie/minify/tree/1.3.67" }, "funding": [ { - "url": "https://github.com/[user1", - "type": "github" - }, - { - "url": "https://github.com/matthiasmullie] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g.", - "type": "github" - }, - { - "url": "https://github.com/user2", + "url": "https://github.com/matthiasmullie", "type": "github" } ], - "time": "2021-01-06T15:18:10+00:00" + "time": "2022-03-24T08:54:59+00:00" }, { "name": "matthiasmullie/path-converter", diff --git a/docs/references/avatars/get-browser.md b/docs/references/avatars/get-browser.md index 7cc841e9da..616439a470 100644 --- a/docs/references/avatars/get-browser.md +++ b/docs/references/avatars/get-browser.md @@ -1,3 +1,3 @@ -You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user /account/sessions endpoint. Use width, height and quality arguments to change the output settings. +You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user [GET /account/sessions](/docs/client/account#accountGetSessions) endpoint. Use width, height and quality arguments to change the output settings. -When one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px. +When one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px. \ No newline at end of file From 1eb821c8236c69cd3609e3a9718304d9dc980617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 25 Apr 2022 11:43:30 +0000 Subject: [PATCH 086/242] Default value & perms bug fix --- app/config/collections.php | 4 +- app/controllers/api/account.php | 2 - app/init.php | 11 ++- composer.lock | 120 +++++++++++++++----------------- 4 files changed, 63 insertions(+), 74 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index 1da342767a..b0d3a57b78 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -1054,8 +1054,8 @@ $collections = [ 'size' => 16384, 'signed' => true, 'required' => false, - 'default' => [], - 'array' => true, + 'default' => null, + 'array' => false, 'filters' => ['subQuerySessions'], ], [ diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 7b190b8a1d..f043609daf 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -28,8 +28,6 @@ use Utopia\Validator\Range; use Utopia\Validator\Text; use Utopia\Validator\WhiteList; -use function PHPUnit\Framework\isEmpty; - $oauthDefaultSuccess = '/v1/auth/oauth2/success'; $oauthDefaultFailure = '/v1/auth/oauth2/failure'; diff --git a/app/init.php b/app/init.php index d14c77d755..0be713fabc 100644 --- a/app/init.php +++ b/app/init.php @@ -306,10 +306,11 @@ Database::addFilter('subQuerySessions', return null; }, function($value, Document $document, Database $database) { - return $database - ->find('sessions', [ - new Query('userId', Query::TYPE_EQUAL, [$document->getId()]) - ], $database->getIndexLimit(), 0, []); + $sessions = Authorization::skip(fn () => $database->find('sessions', [ + new Query('userId', Query::TYPE_EQUAL, [$document->getId()]) + ], $database->getIndexLimit(), 0, [])); + + return $sessions; } ); @@ -705,8 +706,6 @@ App::setResource('user', function($mode, $project, $console, $request, $response $user = $dbForConsole->getDocument('users', Auth::$unique); } - \var_dump($user); - if ($user->isEmpty() // Check a document has been found in the DB || !Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret)) { // Validate user has valid login token $user = new Document(['$id' => '', '$collection' => 'users']); diff --git a/composer.lock b/composer.lock index 03d8f468d2..67ad704a81 100644 --- a/composer.lock +++ b/composer.lock @@ -300,16 +300,16 @@ }, { "name": "colinmollenhour/credis", - "version": "v1.12.2", + "version": "v1.13.0", "source": { "type": "git", "url": "https://github.com/colinmollenhour/credis.git", - "reference": "77e6ede2e01c4cfaade114fe1e07d2f9756949f1" + "reference": "afec8e58ec93d2291c127fa19709a048f28641e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/77e6ede2e01c4cfaade114fe1e07d2f9756949f1", - "reference": "77e6ede2e01c4cfaade114fe1e07d2f9756949f1", + "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/afec8e58ec93d2291c127fa19709a048f28641e5", + "reference": "afec8e58ec93d2291c127fa19709a048f28641e5", "shasum": "" }, "require": { @@ -341,9 +341,9 @@ "homepage": "https://github.com/colinmollenhour/credis", "support": { "issues": "https://github.com/colinmollenhour/credis/issues", - "source": "https://github.com/colinmollenhour/credis/tree/v1.12.2" + "source": "https://github.com/colinmollenhour/credis/tree/v1.13.0" }, - "time": "2022-03-08T18:12:43+00:00" + "time": "2022-04-07T14:57:22+00:00" }, { "name": "composer/package-versions-deprecated", @@ -1583,16 +1583,16 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.0.0", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced" + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", - "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", "shasum": "" }, "require": { @@ -1630,7 +1630,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.1" }, "funding": [ { @@ -1646,7 +1646,7 @@ "type": "tidelift" } ], - "time": "2021-11-01T23:48:49+00:00" + "time": "2022-01-02T09:55:41+00:00" }, { "name": "symfony/polyfill-ctype", @@ -2250,16 +2250,16 @@ }, { "name": "utopia-php/framework", - "version": "0.19.7", + "version": "0.19.20", "source": { "type": "git", "url": "https://github.com/utopia-php/framework.git", - "reference": "f17afe77a21873b9be18ebc05283813468b4283a" + "reference": "65ced168db8f6e188ceeb0d101f57552c3d8b2af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/framework/zipball/f17afe77a21873b9be18ebc05283813468b4283a", - "reference": "f17afe77a21873b9be18ebc05283813468b4283a", + "url": "https://api.github.com/repos/utopia-php/framework/zipball/65ced168db8f6e188ceeb0d101f57552c3d8b2af", + "reference": "65ced168db8f6e188ceeb0d101f57552c3d8b2af", "shasum": "" }, "require": { @@ -2293,9 +2293,9 @@ ], "support": { "issues": "https://github.com/utopia-php/framework/issues", - "source": "https://github.com/utopia-php/framework/tree/0.19.7" + "source": "https://github.com/utopia-php/framework/tree/0.19.20" }, - "time": "2022-02-18T00:04:49+00:00" + "time": "2022-04-14T15:42:37+00:00" }, { "name": "utopia-php/image", @@ -3195,16 +3195,16 @@ }, { "name": "composer/semver", - "version": "3.3.1", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "5d8e574bb0e69188786b8ef77d43341222a41a71" + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/5d8e574bb0e69188786b8ef77d43341222a41a71", - "reference": "5d8e574bb0e69188786b8ef77d43341222a41a71", + "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", "shasum": "" }, "require": { @@ -3256,7 +3256,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.3.1" + "source": "https://github.com/composer/semver/tree/3.3.2" }, "funding": [ { @@ -3272,7 +3272,7 @@ "type": "tidelift" } ], - "time": "2022-03-16T11:22:07+00:00" + "time": "2022-04-01T19:23:25+00:00" }, { "name": "composer/xdebug-handler", @@ -3550,16 +3550,16 @@ }, { "name": "matthiasmullie/minify", - "version": "1.3.66", + "version": "1.3.67", "source": { "type": "git", "url": "https://github.com/matthiasmullie/minify.git", - "reference": "45fd3b0f1dfa2c965857c6d4a470bea52adc31a6" + "reference": "acaee1b7ca3cd67a39d7f98673cacd7e4739a8d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/45fd3b0f1dfa2c965857c6d4a470bea52adc31a6", - "reference": "45fd3b0f1dfa2c965857c6d4a470bea52adc31a6", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/acaee1b7ca3cd67a39d7f98673cacd7e4739a8d9", + "reference": "acaee1b7ca3cd67a39d7f98673cacd7e4739a8d9", "shasum": "" }, "require": { @@ -3608,23 +3608,15 @@ ], "support": { "issues": "https://github.com/matthiasmullie/minify/issues", - "source": "https://github.com/matthiasmullie/minify/tree/1.3.66" + "source": "https://github.com/matthiasmullie/minify/tree/1.3.67" }, "funding": [ { - "url": "https://github.com/[user1", - "type": "github" - }, - { - "url": "https://github.com/matthiasmullie] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g.", - "type": "github" - }, - { - "url": "https://github.com/user2", + "url": "https://github.com/matthiasmullie", "type": "github" } ], - "time": "2021-01-06T15:18:10+00:00" + "time": "2022-03-24T08:54:59+00:00" }, { "name": "matthiasmullie/path-converter", @@ -5076,16 +5068,16 @@ }, { "name": "sebastian/environment", - "version": "5.1.3", + "version": "5.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "388b6ced16caa751030f6a69e588299fa09200ac" + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", - "reference": "388b6ced16caa751030f6a69e588299fa09200ac", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", "shasum": "" }, "require": { @@ -5127,7 +5119,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" }, "funding": [ { @@ -5135,7 +5127,7 @@ "type": "github" } ], - "time": "2020-09-28T05:52:38+00:00" + "time": "2022-04-03T09:37:03+00:00" }, { "name": "sebastian/exporter", @@ -5718,16 +5710,16 @@ }, { "name": "symfony/console", - "version": "v6.0.5", + "version": "v6.0.7", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "3bebf4108b9e07492a2a4057d207aa5a77d146b1" + "reference": "70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/3bebf4108b9e07492a2a4057d207aa5a77d146b1", - "reference": "3bebf4108b9e07492a2a4057d207aa5a77d146b1", + "url": "https://api.github.com/repos/symfony/console/zipball/70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e", + "reference": "70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e", "shasum": "" }, "require": { @@ -5793,7 +5785,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.0.5" + "source": "https://github.com/symfony/console/tree/v6.0.7" }, "funding": [ { @@ -5809,7 +5801,7 @@ "type": "tidelift" } ], - "time": "2022-02-25T10:48:52+00:00" + "time": "2022-03-31T17:18:25+00:00" }, { "name": "symfony/polyfill-intl-grapheme", @@ -6061,16 +6053,16 @@ }, { "name": "symfony/service-contracts", - "version": "v3.0.0", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603" + "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/36715ebf9fb9db73db0cb24263c79077c6fe8603", - "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e517458f278c2131ca9f262f8fbaf01410f2c65c", + "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c", "shasum": "" }, "require": { @@ -6123,7 +6115,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.0.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.0.1" }, "funding": [ { @@ -6139,7 +6131,7 @@ "type": "tidelift" } ], - "time": "2021-11-04T17:53:12+00:00" + "time": "2022-03-13T20:10:05+00:00" }, { "name": "symfony/string", @@ -6327,16 +6319,16 @@ }, { "name": "twig/twig", - "version": "v3.3.9", + "version": "v3.3.10", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "6ff9b0e440fa66f97f207e181c41340ddfa5683d" + "reference": "8442df056c51b706793adf80a9fd363406dd3674" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/6ff9b0e440fa66f97f207e181c41340ddfa5683d", - "reference": "6ff9b0e440fa66f97f207e181c41340ddfa5683d", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/8442df056c51b706793adf80a9fd363406dd3674", + "reference": "8442df056c51b706793adf80a9fd363406dd3674", "shasum": "" }, "require": { @@ -6387,7 +6379,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.3.9" + "source": "https://github.com/twigphp/Twig/tree/v3.3.10" }, "funding": [ { @@ -6399,7 +6391,7 @@ "type": "tidelift" } ], - "time": "2022-03-25T09:37:52+00:00" + "time": "2022-04-06T06:47:41+00:00" }, { "name": "vimeo/psalm", @@ -6583,5 +6575,5 @@ "platform-overrides": { "php": "8.0" }, - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.3.0" } From 9cd79a01934e5e0eff0156744177f4ec70dea945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 25 Apr 2022 11:46:33 +0000 Subject: [PATCH 087/242] Fix composer after merge --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 3084527702..ca66336799 100644 --- a/composer.lock +++ b/composer.lock @@ -2250,16 +2250,16 @@ }, { "name": "utopia-php/framework", - "version": "0.19.9", + "version": "0.19.20", "source": { "type": "git", "url": "https://github.com/utopia-php/framework.git", - "reference": "4af9fc866edce1b8cff94731fb26c27599118e87" + "reference": "65ced168db8f6e188ceeb0d101f57552c3d8b2af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/framework/zipball/4af9fc866edce1b8cff94731fb26c27599118e87", - "reference": "4af9fc866edce1b8cff94731fb26c27599118e87", + "url": "https://api.github.com/repos/utopia-php/framework/zipball/65ced168db8f6e188ceeb0d101f57552c3d8b2af", + "reference": "65ced168db8f6e188ceeb0d101f57552c3d8b2af", "shasum": "" }, "require": { @@ -2293,9 +2293,9 @@ ], "support": { "issues": "https://github.com/utopia-php/framework/issues", - "source": "https://github.com/utopia-php/framework/tree/0.19.9" + "source": "https://github.com/utopia-php/framework/tree/0.19.20" }, - "time": "2022-04-14T15:39:47+00:00" + "time": "2022-04-14T15:42:37+00:00" }, { "name": "utopia-php/image", From 9f1b2644e1d0d46fb7a955bcd9b709e5b00c8d9e Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 25 Apr 2022 14:58:34 +0200 Subject: [PATCH 088/242] fix(account): magic link session verifies email --- app/controllers/api/account.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 200b845987..587d0da862 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -838,6 +838,7 @@ App::put('/v1/account/sessions/magic-url') } $user + ->setAttribute('emailVerification', true) ->setAttribute('sessions', $session, Document::SET_TYPE_APPEND) ->setAttribute('tokens', $tokens); From 5dedd629bd2a580fe4c3c36554f550d757d8049c Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 25 Apr 2022 14:59:08 +0200 Subject: [PATCH 089/242] fix(account): countryName from session locale --- app/controllers/api/account.php | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 587d0da862..4b7db25b7b 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -869,9 +869,7 @@ App::put('/v1/account/sessions/magic-url') ->setStatusCode(Response::STATUS_CODE_CREATED) ; - $countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))])) - ? $countries[strtoupper($session->getAttribute('countryCode'))] - : $locale->getText('locale.country.unknown'); + $countryName = $locale->getText('countries.'.strtolower($session->getAttribute('countryCode')), $locale->getText('locale.country.unknown')); $session ->setAttribute('current', true) @@ -1014,9 +1012,7 @@ App::post('/v1/account/sessions/anonymous') ->setStatusCode(Response::STATUS_CODE_CREATED) ; - $countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))])) - ? $countries[strtoupper($session->getAttribute('countryCode'))] - : $locale->getText('locale.country.unknown'); + $countryName = $locale->getText('countries.'.strtolower($session->getAttribute('countryCode')), $locale->getText('locale.country.unknown')); $session ->setAttribute('current', true) @@ -1281,15 +1277,13 @@ App::get('/v1/account/sessions/:sessionId') $sessions = $user->getAttribute('sessions', []); $sessionId = ($sessionId === 'current') - ? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret) - : $sessionId; + ? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret) + : $sessionId; foreach ($sessions as $session) {/** @var Document $session */ if ($sessionId == $session->getId()) { - $countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))])) - ? $countries[strtoupper($session->getAttribute('countryCode'))] - : $locale->getText('locale.country.unknown'); + $countryName = $locale->getText('countries.'.strtolower($session->getAttribute('countryCode')), $locale->getText('locale.country.unknown')); $session ->setAttribute('current', ($session->getAttribute('secret') == Auth::hash(Auth::$secret))) @@ -1623,7 +1617,7 @@ App::delete('/v1/account/sessions/:sessionId') if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too $session ->setAttribute('current', true) - ->setAttribute('countryName', (isset($countries[strtoupper($session->getAttribute('countryCode'))])) ? $countries[strtoupper($session->getAttribute('countryCode'))] : $locale->getText('locale.country.unknown')) + ->setAttribute('countryName', $locale->getText('countries.'.strtolower($session->getAttribute('countryCode')), $locale->getText('locale.country.unknown'))) ; if (!Config::getParam('domainVerification')) { @@ -1807,7 +1801,7 @@ App::delete('/v1/account/sessions') $session ->setAttribute('current', false) - ->setAttribute('countryName', (isset($countries[strtoupper($session->getAttribute('countryCode'))])) ? $countries[strtoupper($session->getAttribute('countryCode'))] : $locale->getText('locale.country.unknown')) + ->setAttribute('countryName', $locale->getText('countries.'.strtolower($session->getAttribute('countryCode')), $locale->getText('locale.country.unknown'))) ; if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too From 501563f8c4da6e111cf4b7171c4299fe5c2b359a Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 25 Apr 2022 15:07:39 +0200 Subject: [PATCH 090/242] tests: adapt magic url tests --- tests/e2e/Services/Account/AccountBase.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/e2e/Services/Account/AccountBase.php b/tests/e2e/Services/Account/AccountBase.php index cca6c8ff72..2fbe65a0e5 100644 --- a/tests/e2e/Services/Account/AccountBase.php +++ b/tests/e2e/Services/Account/AccountBase.php @@ -1279,7 +1279,7 @@ trait AccountBase $expireTime = strpos($lastEmail['text'], 'expire='.$response['body']['expire'], 0); $this->assertNotFalse($expireTime); - + $secretTest = strpos($lastEmail['text'], 'secret='.$response['body']['secret'], 0); $this->assertNotFalse($secretTest); @@ -1339,6 +1339,7 @@ trait AccountBase { $id = $data['id'] ?? ''; $token = $data['token'] ?? ''; + $email = $data['email'] ?? ''; /** * Test for SUCCESS @@ -1361,6 +1362,20 @@ trait AccountBase $sessionId = $response['body']['$id']; $session = $this->client->parseCookie((string)$response['headers']['set-cookie'])['a_session_'.$this->getProject()['$id']]; + $response = $this->client->call(Client::METHOD_GET, '/account', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session, + ])); + + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['$id']); + $this->assertIsNumeric($response['body']['registration']); + $this->assertEquals($response['body']['email'], $email); + $this->assertTrue($response['body']['emailVerification']); + /** * Test for FAILURE */ From de7e70e2758bcbd77d36f473a7fedcaeb17764e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 26 Apr 2022 08:52:59 +0000 Subject: [PATCH 091/242] Tests fix --- app/controllers/api/account.php | 14 ++++++++++---- app/controllers/api/teams.php | 5 ++--- app/workers/deletes.php | 6 ++---- tests/e2e/Services/Teams/TeamsBaseServer.php | 2 +- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index dd3cf496ba..83e9af04b1 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1041,11 +1041,17 @@ App::post('/v1/account/jwt') /** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Database $dbForProject */ - $current = $dbForProject->findOne('sessions', [ - new Query('secret', Query::TYPE_EQUAL, [Auth::hash(Auth::$secret)]) - ]); - if (!$current) { + $sessions = $user->getAttribute('sessions', []); + $current = new Document(); + + foreach ($sessions as $session) { /** @var Utopia\Database\Document $session */ + if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too + $current = $session; + } + } + + if ($current->isEmpty()) { throw new Exception('No valid session found', 404, Exception::USER_SESSION_NOT_FOUND); } diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 22705d3bf8..ce208b6deb 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -338,7 +338,7 @@ App::post('/v1/teams/:teamId/memberships') 'reset' => false, 'name' => $name, 'prefs' => new \stdClass(), - 'sessions' => [], + 'sessions' => null, 'tokens' => [], 'memberships' => [], 'search' => implode(' ', [$userId, $email, $name]), @@ -728,11 +728,10 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status') ->setAttribute('$write', ['user:'.$user->getId()]) ); - $user->setAttribute('sessions', $session, Document::SET_TYPE_APPEND); + $dbForProject->deleteCachedDocument('users', $user->getId()); Authorization::setRole('user:'.$userId); - $user = $dbForProject->updateDocument('users', $user->getId(), $user); $membership = $dbForProject->updateDocument('memberships', $membership->getId(), $membership); $team = Authorization::skip(fn() => $dbForProject->updateDocument('teams', $team->getId(), $team->setAttribute('total', $team->getAttribute('total', 0) + 1))); diff --git a/app/workers/deletes.php b/app/workers/deletes.php index b8a44ebb82..007b9c2933 100644 --- a/app/workers/deletes.php +++ b/app/workers/deletes.php @@ -207,15 +207,13 @@ class DeletesV1 extends Worker */ $userId = $document->getId(); - $user = $this->getProjectDB($projectId)->getDocument('users', $userId); // Delete all sessions of this user from the sessions table and update the sessions field of the user record $this->deleteByGroup('sessions', [ new Query('userId', Query::TYPE_EQUAL, [$userId]) ], $this->getProjectDB($projectId)); - - $user->setAttribute('sessions', []); - $updated = $this->getProjectDB($projectId)->updateDocument('users', $userId, $user); + + $this->getProjectDB($projectId)->deleteCachedDocument('users', $userId); // Delete Memberships and decrement team membership counts $this->deleteByGroup('memberships', [ diff --git a/tests/e2e/Services/Teams/TeamsBaseServer.php b/tests/e2e/Services/Teams/TeamsBaseServer.php index 41dcc6c84c..5db4b628f6 100644 --- a/tests/e2e/Services/Teams/TeamsBaseServer.php +++ b/tests/e2e/Services/Teams/TeamsBaseServer.php @@ -204,7 +204,7 @@ trait TeamsBaseServer $this->assertEquals(1, $response['body']['total']); $this->assertIsInt($response['body']['total']); $this->assertIsInt($response['body']['dateCreated']); - + /** Delete User */ $user = $this->client->call(Client::METHOD_DELETE, '/users/' . $userUid, array_merge([ From 66d68a786b2bd4bda849d5a4fafbfc26e512ac09 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Tue, 26 Apr 2022 12:22:01 +0300 Subject: [PATCH 092/242] Update src/Appwrite/Extend/Exception.php --- src/Appwrite/Extend/Exception.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Extend/Exception.php b/src/Appwrite/Extend/Exception.php index ee5d6ab729..cf508d1198 100644 --- a/src/Appwrite/Extend/Exception.php +++ b/src/Appwrite/Extend/Exception.php @@ -46,7 +46,7 @@ class Exception extends \Exception const GENERAL_ROUTE_NOT_FOUND = 'general_route_not_found'; const GENERAL_CURSOR_NOT_FOUND = 'general_cursor_not_found'; const GENERAL_SERVER_ERROR = 'general_server_error'; - const GENERAL_PROTOCOL_UNSUPPORTED = 'general_protocol_unsupported'; + const GENERAL_PROTOCOL_UNSUPPORTED = 'general_protocol_unsupported'; /** Users */ const USER_COUNT_EXCEEDED = 'user_count_exceeded'; From 337a120d7f20d137d0cc254938d8713d9cc03d4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 26 Apr 2022 09:33:16 +0000 Subject: [PATCH 093/242] Post-merge lockfile update --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index 6d052aed1c..ea07e51fea 100644 --- a/composer.lock +++ b/composer.lock @@ -6576,5 +6576,5 @@ "platform-overrides": { "php": "8.0" }, - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.3.0" } From 1e0fe177a8d859a5490674927af0a41742b9dfd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 26 Apr 2022 10:00:20 +0000 Subject: [PATCH 094/242] Post-merge fix --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index 6d052aed1c..ea07e51fea 100644 --- a/composer.lock +++ b/composer.lock @@ -6576,5 +6576,5 @@ "platform-overrides": { "php": "8.0" }, - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.3.0" } From 487d38db958e57fdbf5cff858b49a33ebb27fa50 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 26 Apr 2022 12:07:33 +0200 Subject: [PATCH 095/242] fix(user): search integrity --- app/controllers/api/users.php | 14 +++- tests/e2e/Services/Account/AccountBase.php | 14 ++-- .../Account/AccountCustomClientTest.php | 83 ++++++++++++++++++- .../Account/AccountCustomServerTest.php | 2 +- tests/e2e/Services/Users/UsersBase.php | 76 +++++++++++++++++ 5 files changed, 177 insertions(+), 12 deletions(-) diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 6bb14c5003..a38c8cad89 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -453,7 +453,12 @@ App::patch('/v1/users/:userId/name') throw new Exception('User not found', 404, Exception::USER_NOT_FOUND); } - $user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('name', $name)); + $user + ->setAttribute('name', $name) + ->setAttribute('search', \implode(' ', [$user->getId(), $user->getAttribute('email'), $name])); + ; + + $user = $dbForProject->updateDocument('users', $user->getId(), $user); $audits ->setParam('userId', $user->getId()) @@ -542,8 +547,13 @@ App::patch('/v1/users/:userId/email') $email = \strtolower($email); + $user + ->setAttribute('email', $email) + ->setAttribute('search', \implode(' ', [$user->getId(), $email, $user->getAttribute('name')])) + ; + try { - $user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('email', $email)); + $user = $dbForProject->updateDocument('users', $user->getId(), $user); } catch(Duplicate $th) { throw new Exception('Email already exists', 409, Exception::USER_EMAIL_ALREADY_EXISTS); } diff --git a/tests/e2e/Services/Account/AccountBase.php b/tests/e2e/Services/Account/AccountBase.php index 2fbe65a0e5..3aa368baad 100644 --- a/tests/e2e/Services/Account/AccountBase.php +++ b/tests/e2e/Services/Account/AccountBase.php @@ -445,7 +445,7 @@ trait AccountBase { $email = $data['email'] ?? ''; $session = $data['session'] ?? ''; - $newName = 'New Name'; + $newName = 'Lorem'; /** * Test for SUCCESS @@ -477,7 +477,7 @@ trait AccountBase ])); $this->assertEquals($response['headers']['status-code'], 401); - + $response = $this->client->call(Client::METHOD_PATCH, '/account/name', array_merge([ 'origin' => 'http://localhost', 'content-type' => 'application/json', @@ -485,7 +485,7 @@ trait AccountBase 'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session, ]), [ ]); - + $this->assertEquals($response['headers']['status-code'], 400); $response = $this->client->call(Client::METHOD_PATCH, '/account/name', array_merge([ @@ -496,7 +496,7 @@ trait AccountBase ]), [ 'name' => 'ocSRq1d3QphHivJyUmYY7WMnrxyjdk5YvVwcDqx2zS0coxESN8RmsQwLWw5Whnf0WbVohuFWTRAaoKgCOO0Y0M7LwgFnZmi8881Y72222222222222222222222222222' ]); - + $this->assertEquals($response['headers']['status-code'], 400); $data['name'] = $newName; @@ -532,7 +532,6 @@ trait AccountBase $this->assertNotEmpty($response['body']['$id']); $this->assertIsNumeric($response['body']['registration']); $this->assertEquals($response['body']['email'], $email); - $this->assertEquals($response['body']['name'], 'New Name'); $response = $this->client->call(Client::METHOD_POST, '/account/sessions', array_merge([ 'origin' => 'http://localhost', @@ -625,7 +624,6 @@ trait AccountBase $this->assertNotEmpty($response['body']['$id']); $this->assertIsNumeric($response['body']['registration']); $this->assertEquals($response['body']['email'], $newEmail); - $this->assertEquals($response['body']['name'], 'New Name'); /** * Test for FAILURE @@ -637,7 +635,7 @@ trait AccountBase ])); $this->assertEquals($response['headers']['status-code'], 401); - + $response = $this->client->call(Client::METHOD_PATCH, '/account/email', array_merge([ 'origin' => 'http://localhost', 'content-type' => 'application/json', @@ -645,7 +643,7 @@ trait AccountBase 'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session, ]), [ ]); - + $this->assertEquals($response['headers']['status-code'], 400); // Test if we can create a new account with the old email diff --git a/tests/e2e/Services/Account/AccountCustomClientTest.php b/tests/e2e/Services/Account/AccountCustomClientTest.php index 2b06828a6e..30a01b31b9 100644 --- a/tests/e2e/Services/Account/AccountCustomClientTest.php +++ b/tests/e2e/Services/Account/AccountCustomClientTest.php @@ -510,4 +510,85 @@ class AccountCustomClientTest extends Scope $this->assertEquals($response['headers']['status-code'], 404); } -} \ No newline at end of file + + /** + * @depends testUpdateAccountName + */ + public function testUpdateAccountNameSearch($data): void + { + $id = $data['id'] ?? ''; + $email = $data['email'] ?? ''; + $newName = 'Lorem'; + + /** + * Test for SUCCESS + */ + $response = $this->client->call(Client::METHOD_GET, '/users', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], [ + 'search' => $newName + ]); + + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['users']); + $this->assertCount(1, $response['body']['users']); + $this->assertEquals($response['body']['users'][0]['email'], $email); + + $response = $this->client->call(Client::METHOD_GET, '/users', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], [ + 'search' => $id + ]); + + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['users']); + $this->assertCount(1, $response['body']['users']); + $this->assertEquals($response['body']['users'][0]['email'], $email); + } + + /** + * @depends testUpdateAccountEmail + */ + public function testUpdateAccountEmailSearch($data): void + { + $id = $data['id'] ?? ''; + $email = $data['email'] ?? ''; + + /** + * Test for SUCCESS + */ + $response = $this->client->call(Client::METHOD_GET, '/users', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], [ + 'search' => '"' . $email . '"' + ]); + + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['users']); + $this->assertCount(1, $response['body']['users']); + $this->assertEquals($response['body']['users'][0]['email'], $email); + + $response = $this->client->call(Client::METHOD_GET, '/users', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], [ + 'search' => $id + ]); + + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['users']); + $this->assertCount(1, $response['body']['users']); + $this->assertEquals($response['body']['users'][0]['email'], $email); + } +} diff --git a/tests/e2e/Services/Account/AccountCustomServerTest.php b/tests/e2e/Services/Account/AccountCustomServerTest.php index fabbc5b77f..832dd34389 100644 --- a/tests/e2e/Services/Account/AccountCustomServerTest.php +++ b/tests/e2e/Services/Account/AccountCustomServerTest.php @@ -33,7 +33,7 @@ class AccountCustomServerTest extends Scope ]); $this->assertEquals(401, $response['headers']['status-code']); - + return []; } } \ No newline at end of file diff --git a/tests/e2e/Services/Users/UsersBase.php b/tests/e2e/Services/Users/UsersBase.php index 2e61917d2d..1f5f2922d8 100644 --- a/tests/e2e/Services/Users/UsersBase.php +++ b/tests/e2e/Services/Users/UsersBase.php @@ -281,6 +281,44 @@ trait UsersBase return $data; } + /** + * @depends testUpdateUserName + */ + public function testUpdateUserNameSearch($data): void + { + $id = $data['userId'] ?? ''; + $newName = 'Updated name'; + + /** + * Test for SUCCESS + */ + $response = $this->client->call(Client::METHOD_GET, '/users', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => $newName + ]); + + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['users']); + $this->assertCount(1, $response['body']['users']); + $this->assertEquals($response['body']['users'][0]['$id'], $id); + + $response = $this->client->call(Client::METHOD_GET, '/users', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => $id + ]); + + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['users']); + $this->assertCount(1, $response['body']['users']); + $this->assertEquals($response['body']['users'][0]['$id'], $id); + } + /** * @depends testGetUser */ @@ -310,6 +348,44 @@ trait UsersBase return $data; } + /** + * @depends testUpdateUserEmail + */ + public function testUpdateUserEmailSearch($data): void + { + $id = $data['userId'] ?? ''; + $newEmail = '"users.service@updated.com"'; + + /** + * Test for SUCCESS + */ + $response = $this->client->call(Client::METHOD_GET, '/users', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => $newEmail + ]); + + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['users']); + $this->assertCount(1, $response['body']['users']); + $this->assertEquals($response['body']['users'][0]['$id'], $id); + + $response = $this->client->call(Client::METHOD_GET, '/users', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'search' => $id + ]); + + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['users']); + $this->assertCount(1, $response['body']['users']); + $this->assertEquals($response['body']['users'][0]['$id'], $id); + } + /** * @depends testUpdateUserEmail */ From fde7278f43d638d06e196713c147a116c248c273 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 26 Apr 2022 12:26:07 +0200 Subject: [PATCH 096/242] fix(ui): document crud redirect --- app/views/console/database/document.phtml | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/app/views/console/database/document.phtml b/app/views/console/database/document.phtml index 8324c680d0..a48d533830 100644 --- a/app/views/console/database/document.phtml +++ b/app/views/console/database/document.phtml @@ -55,17 +55,26 @@ $logs = $this->getParam('logs', null); data-analytics-activity data-analytics-event="submit" data-analytics-category="console" - data-analytics-label="Update Database Document" data-service="{{|documentAction}}" data-name="project-document" data-scope="sdk" data-event="submit" - data-success="trigger,redirect" - data-success-param-trigger-events="database.updateDocument" - data-success-param-redirect-url="/console/database/document?id={{serviceData.$id}}&collection={{project-collection.$id}}&project={{router.params.project}}" data-failure="alert" - data-failure-param-alert-text="Failed to update document" - data-failure-param-alert-classname="error"> + data-failure-param-alert-classname="error" + + data-analytics-label="Create Database Document" + data-success="trigger,redirect" + data-success-param-trigger-events="database.createDocument" + data-success-param-redirect-url="/console/database/collection?id={{project-collection.$id}}&project={{router.params.project}}" + data-failure-param-alert-text="Failed to create document" + + data-analytics-label="Update Database Document" + data-success="trigger,alert" + data-success-param-trigger-events="database.updateDocument" + data-success-param-alert-text="Your document was updated" + data-failure-param-alert-text="Failed to update document" + + > From fe646e808d147db8db1db2dcce95b03cd48e778b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 26 Apr 2022 10:32:38 +0000 Subject: [PATCH 097/242] Post-merge lockfile fix --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index 6d052aed1c..ea07e51fea 100644 --- a/composer.lock +++ b/composer.lock @@ -6576,5 +6576,5 @@ "platform-overrides": { "php": "8.0" }, - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.3.0" } From e0426598fc96611a85486c232b0d3c752b324f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 26 Apr 2022 10:36:49 +0000 Subject: [PATCH 098/242] Fix unfinished todos --- app/controllers/api/account.php | 21 ++++++++------------- app/controllers/api/users.php | 6 +++--- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 83e9af04b1..f8b9eb516b 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -104,7 +104,7 @@ App::post('/v1/account') 'reset' => false, 'name' => $name, 'prefs' => new \stdClass(), - 'sessions' => [], + 'sessions' => null, 'tokens' => [], 'memberships' => [], 'search' => implode(' ', [$userId, $email, $name]), @@ -501,7 +501,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') 'reset' => false, 'name' => $name, 'prefs' => new \stdClass(), - 'sessions' => [], + 'sessions' => null, 'tokens' => [], 'memberships' => [], 'search' => implode(' ', [$userId, $email, $name]), @@ -674,7 +674,7 @@ App::post('/v1/account/sessions/magic-url') 'registration' => \time(), 'reset' => false, 'prefs' => new \stdClass(), - 'sessions' => [], + 'sessions' => null, 'tokens' => [], 'memberships' => [], 'search' => implode(' ', [$userId, $email]), @@ -946,7 +946,7 @@ App::post('/v1/account/sessions/anonymous') 'reset' => false, 'name' => null, 'prefs' => new \stdClass(), - 'sessions' => [], + 'sessions' => null, 'tokens' => [], 'memberships' => [], 'search' => $userId, @@ -1273,7 +1273,6 @@ App::get('/v1/account/sessions/:sessionId') /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Stats\Stats $usage */ - // TODO: Matej refactor $sessions = $user->getAttribute('sessions', []); $sessionId = ($sessionId === 'current') ? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret) @@ -1599,7 +1598,6 @@ App::delete('/v1/account/sessions/:sessionId') ? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret) : $sessionId; - // TODO: Matej refactor $sessions = $user->getAttribute('sessions', []); foreach ($sessions as $key => $session) {/** @var Document $session */ @@ -1633,8 +1631,8 @@ App::delete('/v1/account/sessions/:sessionId') ->addCookie(Auth::$cookieName, '', \time() - 3600, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, Config::getParam('cookieSamesite')) ; } - - $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('sessions', $sessions)); + + $dbForProject->deleteCachedDocument('users', $user->getId()); $events ->setParam('eventData', $response->output($session, Response::MODEL_SESSION)) @@ -1690,7 +1688,6 @@ App::patch('/v1/account/sessions/:sessionId') ? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret) : $sessionId; - // TODO: Matej refactor $sessions = $user->getAttribute('sessions', []); foreach ($sessions as $key => $session) {/** @var Document $session */ @@ -1729,8 +1726,7 @@ App::patch('/v1/account/sessions/:sessionId') $dbForProject->updateDocument('sessions', $sessionId, $session); - $user->setAttribute("sessions", $sessions); - $user = $dbForProject->updateDocument('users', $user->getId(), $user); + $dbForProject->deleteCachedDocument('users', $user->getId()); $audits ->setParam('userId', $user->getId()) @@ -1786,7 +1782,6 @@ App::delete('/v1/account/sessions') $protocol = $request->getProtocol(); $sessions = $user->getAttribute('sessions', []); - // TODO: Matej refactor foreach ($sessions as $session) {/** @var Document $session */ $dbForProject->deleteDocument('sessions', $session->getId()); @@ -1817,7 +1812,7 @@ App::delete('/v1/account/sessions') } } - $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('sessions', [])); + $dbForProject->deleteCachedDocument('users', $user->getId()); $numOfSessions = count($sessions); diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 2732421c33..c9a6c0be8a 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -63,7 +63,7 @@ App::post('/v1/users') 'reset' => false, 'name' => $name, 'prefs' => new \stdClass(), - 'sessions' => [], + 'sessions' => null, 'tokens' => [], 'memberships' => [], 'search' => implode(' ', [$userId, $email, $name]), @@ -630,12 +630,12 @@ App::delete('/v1/users/:userId/sessions/:sessionId') $dbForProject->deleteDocument('sessions', $session->getId()); + $dbForProject->deleteCachedDocument('users', $user->getId()); + $events ->setParam('eventData', $response->output($user, Response::MODEL_USER)) ; - $dbForProject->deleteCachedDocument('users', $user->getId()); - $usage ->setParam('users.update', 1) ->setParam('users.sessions.delete', 1) From f642f19ca6a99a3674adf8bce2e2d6155f467c16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 26 Apr 2022 10:46:35 +0000 Subject: [PATCH 099/242] Final test fix --- app/controllers/api/account.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index f8b9eb516b..d3fbe4e714 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -553,6 +553,8 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') Authorization::setRole('user:' . $user->getId()); + $dbForProject->updateDocument('users', $user->getId(), $user); + $session = $dbForProject->createDocument('sessions', $session ->setAttribute('$read', ['user:' . $user->getId()]) ->setAttribute('$write', ['user:' . $user->getId()]) From a32713011f3b459798d935ddc3b4e9321a1e15aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Wed, 27 Apr 2022 09:02:31 +0000 Subject: [PATCH 100/242] PR review changes --- app/tasks/maintenance.php | 3 +-- app/tasks/ssl.php | 17 +---------------- app/workers/certificates.php | 32 +++++++++++++++++--------------- composer.lock | 34 +++++++++++++--------------------- 4 files changed, 32 insertions(+), 54 deletions(-) diff --git a/app/tasks/maintenance.php b/app/tasks/maintenance.php index db2d2e808a..087b16cf95 100644 --- a/app/tasks/maintenance.php +++ b/app/tasks/maintenance.php @@ -131,8 +131,7 @@ $cli Console::loop(function() use ($register, $interval, $executionLogsRetention, $abuseLogsRetention, $auditLogRetention, $usageStatsRetention30m, $usageStatsRetention1d) { go(function () use ($register, $interval, $executionLogsRetention, $abuseLogsRetention, $auditLogRetention, $usageStatsRetention30m, $usageStatsRetention1d) { try { - [$database, $returnDatabase] = getConsoleDB - ($register, '_console'); + [$database, $returnDatabase] = getConsoleDB($register, '_console'); $time = date('d-m-Y H:i:s', time()); Console::info("[{$time}] Notifying workers with maintenance tasks every {$interval} seconds"); diff --git a/app/tasks/ssl.php b/app/tasks/ssl.php index 18f7ee8324..e1724e8401 100644 --- a/app/tasks/ssl.php +++ b/app/tasks/ssl.php @@ -12,22 +12,7 @@ $cli ->desc('Validate server certificates') ->param('domain', App::getEnv('_APP_DOMAIN', ''), new Hostname(), 'Domain to generate certificate for. If empty, main domain will be used.', true) ->action(function ($domain) { - // HTTTP ping to check if domain is Appwrite server - $ch = \curl_init(); - \curl_setopt($ch, CURLOPT_URL, 'http://appwrite/manifest.json'); - \curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - \curl_setopt($ch, CURLOPT_TIMEOUT, 5); - \curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); - \curl_exec($ch); - $statusCode = \curl_getinfo($ch, CURLINFO_HTTP_CODE); - $error = \curl_error($ch); - \curl_close($ch); - - if($statusCode < 100) { - return Console::error('Appwrite connection refused with message: ' . $error); - } - - Console::success('Schedule a job to issue a TLS certificate for domain:' . $domain); + Console::success('Scheduling a job to issue a TLS certificate for domain:' . $domain); // Scheduje a job Resque::enqueue(Event::CERTIFICATES_QUEUE_NAME, Event::CERTIFICATES_CLASS_NAME, [ diff --git a/app/workers/certificates.php b/app/workers/certificates.php index 825bb1689c..25eda60a91 100644 --- a/app/workers/certificates.php +++ b/app/workers/certificates.php @@ -18,12 +18,15 @@ Console::success(APP_NAME . ' certificates worker v1 has started'); class CertificatesV1 extends Worker { + private $certificate = null; // run function fills this. onError callback uses it + public function getName(): string { return "certificates"; } public function init(): void { + } public function run(): void @@ -32,8 +35,7 @@ class CertificatesV1 extends Worker $dbForConsole = $this->getConsoleDB(); - $certificate = new Document(); - + $this->certificate = new Document(); /** * 1. Read arguments and validate domain @@ -70,7 +72,7 @@ class CertificatesV1 extends Worker $domain = $this->args['domain']; // String of domain (hostname) $domain = new Domain((!empty($domain)) ? $domain : ''); - $certificate->setAttribute('domain', $domain->get()); + $this->certificate->setAttribute('domain', $domain->get()); $skipRenewCheck = $this->args['skipRenewCheck'] ?? false; // If true, we won't double-check expiry from cert file @@ -169,7 +171,7 @@ class CertificatesV1 extends Worker // Command succeeded, store all data into document // We store stderr too, because it may include warnings // This is only stored if everytng below passes too. Otherwise, it will be overwritten by error message - $certificate->setAttribute('log', \json_encode([ + $this->certificate->setAttribute('log', \json_encode([ 'stdout' => $stdout, 'stderr' => $stderr, ])); @@ -217,26 +219,26 @@ class CertificatesV1 extends Worker $certData = openssl_x509_parse(file_get_contents($certPath)); $validTo = $certData['validTo_time_t'] ?? 0; $expiryInAdvance = (60*60*24*30); - $certificate->setAttribute('renewDate', $validTo - $expiryInAdvance); + $this->certificate->setAttribute('renewDate', $validTo - $expiryInAdvance); // All went well at this point 🥳 // Reset attempts count for next renwal - $certificate->setAttribute('attempts', 0); + $this->certificate->setAttribute('attempts', 0); // Mark issue date - $certificate->setAttribute('issueDate', \time()); + $this->certificate->setAttribute('issueDate', \time()); } catch(ExceptionCertificate $e) { // These exceptions are expected if renew shouldn't or can't happen // Add exception as log into certificate - $certificate->setAttribute('log', $e->getMessage()); + $this->certificate->setAttribute('log', $e->getMessage()); - $attempt = $certificate->getAttribute('attempts', 0); + $attempt = $this->certificate->getAttribute('attempts', 0); $attempt++; // Save increased attempts count - $certificate->setAttribute('attempts', $attempt); + $this->certificate->setAttribute('attempts', $attempt); Console::warning('Cannot renew domain (' . $domain->get() . ') on attempt no. ' . $attempt . ' certificate: ' . $e->getMessage()); @@ -256,22 +258,22 @@ class CertificatesV1 extends Worker ]); } finally { // All actions result in new updatedAt date - $certificate->setAttribute('updated', \time()); + $this->certificate->setAttribute('updated', \time()); // Save certificate data into database // Check if update or insert required $certificateDocument = $dbForConsole->findOne('certificates', [ new Query('domain', Query::TYPE_EQUAL, [$domain->get()]) ]); if (!empty($certificateDocument) && !$certificateDocument->isEmpty()) { // Merge new data with current data - $certificate = new Document(\array_merge($certificateDocument->getArrayCopy(), $certificate->getArrayCopy())); + $this->certificate = new Document(\array_merge($certificateDocument->getArrayCopy(), $this->certificate->getArrayCopy())); - $certificate = $dbForConsole->updateDocument('certificates', $certificate->getId(), $certificate); + $this->certificate = $dbForConsole->updateDocument('certificates', $this->certificate->getId(), $this->certificate); } else { - $certificate = $dbForConsole->createDocument('certificates', $certificate); + $this->certificate = $dbForConsole->createDocument('certificates', $this->certificate); } // Update domains with new certificate ID - $certificateId = $certificate->getId(); + $certificateId = $this->certificate->getId(); $domains = $dbForConsole->find('domains', [ new Query('domain', Query::TYPE_EQUAL, [$domain->get()]) diff --git a/composer.lock b/composer.lock index 9bafae75a0..c82900e1bb 100644 --- a/composer.lock +++ b/composer.lock @@ -2250,16 +2250,16 @@ }, { "name": "utopia-php/framework", - "version": "0.19.8", + "version": "0.19.20", "source": { "type": "git", "url": "https://github.com/utopia-php/framework.git", - "reference": "8c3b3e330546fd6cd65bd1f8d8d08882ff3abb7d" + "reference": "65ced168db8f6e188ceeb0d101f57552c3d8b2af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/framework/zipball/8c3b3e330546fd6cd65bd1f8d8d08882ff3abb7d", - "reference": "8c3b3e330546fd6cd65bd1f8d8d08882ff3abb7d", + "url": "https://api.github.com/repos/utopia-php/framework/zipball/65ced168db8f6e188ceeb0d101f57552c3d8b2af", + "reference": "65ced168db8f6e188ceeb0d101f57552c3d8b2af", "shasum": "" }, "require": { @@ -2293,9 +2293,9 @@ ], "support": { "issues": "https://github.com/utopia-php/framework/issues", - "source": "https://github.com/utopia-php/framework/tree/0.19.8" + "source": "https://github.com/utopia-php/framework/tree/0.19.20" }, - "time": "2022-04-12T00:28:15+00:00" + "time": "2022-04-14T15:42:37+00:00" }, { "name": "utopia-php/image", @@ -3550,16 +3550,16 @@ }, { "name": "matthiasmullie/minify", - "version": "1.3.66", + "version": "1.3.67", "source": { "type": "git", "url": "https://github.com/matthiasmullie/minify.git", - "reference": "45fd3b0f1dfa2c965857c6d4a470bea52adc31a6" + "reference": "acaee1b7ca3cd67a39d7f98673cacd7e4739a8d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/45fd3b0f1dfa2c965857c6d4a470bea52adc31a6", - "reference": "45fd3b0f1dfa2c965857c6d4a470bea52adc31a6", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/acaee1b7ca3cd67a39d7f98673cacd7e4739a8d9", + "reference": "acaee1b7ca3cd67a39d7f98673cacd7e4739a8d9", "shasum": "" }, "require": { @@ -3608,23 +3608,15 @@ ], "support": { "issues": "https://github.com/matthiasmullie/minify/issues", - "source": "https://github.com/matthiasmullie/minify/tree/1.3.66" + "source": "https://github.com/matthiasmullie/minify/tree/1.3.67" }, "funding": [ { - "url": "https://github.com/[user1", - "type": "github" - }, - { - "url": "https://github.com/matthiasmullie] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g.", - "type": "github" - }, - { - "url": "https://github.com/user2", + "url": "https://github.com/matthiasmullie", "type": "github" } ], - "time": "2021-01-06T15:18:10+00:00" + "time": "2022-03-24T08:54:59+00:00" }, { "name": "matthiasmullie/path-converter", From 18c3f021af294a69a1d885a8d0e26b94817d7667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Wed, 27 Apr 2022 09:13:34 +0000 Subject: [PATCH 101/242] Add index --- app/config/collections.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/config/collections.php b/app/config/collections.php index 47ecdf4311..1ff3c66c46 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -1395,6 +1395,13 @@ $collections = [ 'lengths' => [100, 100], 'orders' => [Database::ORDER_ASC, Database::ORDER_ASC], ], + [ + '$id' => '_key_user', + 'type' => Database::INDEX_KEY, + 'attributes' => ['userId'], + 'lengths' => [Database::LENGTH_KEY], + 'orders' => [Database::ORDER_ASC], + ], ], ], From e4379ec850d8c9117c815c83b98083f11705d4a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Wed, 27 Apr 2022 09:42:15 +0000 Subject: [PATCH 102/242] PR review changes --- app/workers/certificates.php | 31 +++++++++++++------------- src/Appwrite/Exception/Certificate.php | 7 ------ 2 files changed, 15 insertions(+), 23 deletions(-) delete mode 100644 src/Appwrite/Exception/Certificate.php diff --git a/app/workers/certificates.php b/app/workers/certificates.php index 25eda60a91..6c246d0af8 100644 --- a/app/workers/certificates.php +++ b/app/workers/certificates.php @@ -3,7 +3,6 @@ use Appwrite\Event\Event; use Appwrite\Network\Validator\CNAME; use Appwrite\Resque\Worker; -use Appwrite\Exception\Certificate as ExceptionCertificate; use Utopia\App; use Utopia\CLI\Console; use Utopia\Database\Document; @@ -91,11 +90,11 @@ class CertificatesV1 extends Worker } if (empty($domain->get())) { - throw new ExceptionCertificate('Missing certificate domain.'); + throw new Exception('Missing certificate domain.'); } if (!$domain->isKnown() || $domain->isTest()) { - throw new ExceptionCertificate('Unknown public suffix for domain.'); + throw new Exception('Unknown public suffix for domain.'); } if ($validateCNAME) { @@ -105,13 +104,13 @@ class CertificatesV1 extends Worker $target = new Domain(App::getEnv('_APP_DOMAIN_TARGET', '')); if (!$target->isKnown() || $target->isTest()) { - throw new ExceptionCertificate('Unreachable CNAME target ('.$target->get().'), please use a domain with a public suffix.'); + throw new Exception('Unreachable CNAME target ('.$target->get().'), please use a domain with a public suffix.'); } // Verify domain with DNS records $validator = new CNAME($target->get()); if (!$validator->isValid($domain->get())) { - throw new ExceptionCertificate('Failed to verify domain DNS records.'); + throw new Exception('Failed to verify domain DNS records.'); } } else { // Main domain validation @@ -133,21 +132,21 @@ class CertificatesV1 extends Worker throw new Exception('Invalid expiry date.'); } } catch(\Throwable $th) { - throw new ExceptionCertificate('Unable to read certificate file (cert.pem).'); + throw new Exception('Unable to read certificate file (cert.pem).'); } // LetsEncrypt allows renewal 30 days before expiry $expiryInAdvance = (60*60*24*30); if ($validTo - $expiryInAdvance > \time()) { $validToVerbose = date('d-m-Y H:i:s', $validTo); - throw new ExceptionCertificate('Renew isn\'t required. Next renew at ' . $validToVerbose); + throw new Exception('Renew isn\'t required. Next renew at ' . $validToVerbose); } } // Email for alerts is required by LetsEncrypt $email = App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS'); if (empty($email)) { - throw new ExceptionCertificate('You must set a valid security email address (_APP_SYSTEM_SECURITY_EMAIL_ADDRESS) to issue an SSL certificate.'); + throw new Exception('You must set a valid security email address (_APP_SYSTEM_SECURITY_EMAIL_ADDRESS) to issue an SSL certificate.'); } // LetsEncrypt communication to issue certificate (using certbot CLI) @@ -165,7 +164,7 @@ class CertificatesV1 extends Worker // Unexpected error, usually 5XX, API limits, ... if ($exit !== 0) { - throw new ExceptionCertificate('Failed to issue a certificate with message: ' . $stderr); + throw new Exception('Failed to issue a certificate with message: ' . $stderr); } // Command succeeded, store all data into document @@ -180,25 +179,25 @@ class CertificatesV1 extends Worker $path = APP_STORAGE_CERTIFICATES . '/' . $domain->get(); if (!\is_readable($path)) { if (!\mkdir($path, 0755, true)) { - throw new ExceptionCertificate('Failed to create path for certificate.'); + throw new Exception('Failed to create path for certificate.'); } } // Move generated files from certbot into our storage if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/cert.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/cert.pem')) { - throw new ExceptionCertificate('Failed to rename certificate cert.pem: '.\json_encode($stdout)); + throw new Exception('Failed to rename certificate cert.pem: '.\json_encode($stdout)); } if (!@\rename('/etc/letsencrypt/live/' . $domain->get() . '/chain.pem', APP_STORAGE_CERTIFICATES . '/' . $domain->get() . '/chain.pem')) { - throw new ExceptionCertificate('Failed to rename certificate chain.pem: ' . \json_encode($stdout)); + throw new Exception('Failed to rename certificate chain.pem: ' . \json_encode($stdout)); } if (!@\rename('/etc/letsencrypt/live/' . $domain->get() . '/fullchain.pem', APP_STORAGE_CERTIFICATES . '/' . $domain->get() . '/fullchain.pem')) { - throw new ExceptionCertificate('Failed to rename certificate fullchain.pem: ' . \json_encode($stdout)); + throw new Exception('Failed to rename certificate fullchain.pem: ' . \json_encode($stdout)); } if (!@\rename('/etc/letsencrypt/live/' . $domain->get() . '/privkey.pem', APP_STORAGE_CERTIFICATES . '/' . $domain->get() . '/privkey.pem')) { - throw new ExceptionCertificate('Failed to rename certificate privkey.pem: ' . \json_encode($stdout)); + throw new Exception('Failed to rename certificate privkey.pem: ' . \json_encode($stdout)); } // This multi-line syntax helps IDE @@ -210,7 +209,7 @@ class CertificatesV1 extends Worker // Save configuration into Traefik using our new cert files if (!\file_put_contents(APP_STORAGE_CONFIG . '/' . $domain->get() . '.yml', $config)) { - throw new ExceptionCertificate('Failed to save Traefik configuration.'); + throw new Exception('Failed to save Traefik configuration.'); } // Read new renew date from cert file @@ -228,7 +227,7 @@ class CertificatesV1 extends Worker // Mark issue date $this->certificate->setAttribute('issueDate', \time()); - } catch(ExceptionCertificate $e) { + } catch(Throwable $e) { // These exceptions are expected if renew shouldn't or can't happen // Add exception as log into certificate diff --git a/src/Appwrite/Exception/Certificate.php b/src/Appwrite/Exception/Certificate.php deleted file mode 100644 index 0b044015d4..0000000000 --- a/src/Appwrite/Exception/Certificate.php +++ /dev/null @@ -1,7 +0,0 @@ - Date: Wed, 27 Apr 2022 13:20:08 +0000 Subject: [PATCH 103/242] Code quality improvement --- app/workers/deletes.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/workers/deletes.php b/app/workers/deletes.php index cf62089165..1748060b2c 100644 --- a/app/workers/deletes.php +++ b/app/workers/deletes.php @@ -18,6 +18,9 @@ use Utopia\Audit\Audit; require_once __DIR__ . '/../init.php'; +Authorization::disable(); +Authorization::setDefaultStatus(false); + Console::title('Deletes V1 Worker'); Console::success(APP_NAME . ' deletes worker v1 has started' . "\n"); @@ -38,7 +41,6 @@ class DeletesV1 extends Worker public function run(): void { - Authorization::disable(); $projectId = $this->args['projectId'] ?? ''; $type = $this->args['type'] ?? ''; @@ -113,8 +115,6 @@ class DeletesV1 extends Worker Console::error('No delete operation for type: ' . $type); break; } - - Authorization::reset(); } public function shutdown(): void From feb124d16577472804ae7fe596e441fc49ca1e0f Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 27 Apr 2022 22:08:32 +0300 Subject: [PATCH 104/242] feat: add method to check for email verification --- src/Appwrite/Auth/OAuth2.php | 38 ++++++++++++------------- src/Appwrite/Auth/OAuth2/Amazon.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Apple.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Bitbucket.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Bitly.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Box.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Discord.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Dropbox.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Facebook.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Github.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Gitlab.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Google.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Linkedin.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Microsoft.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Mock.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Notion.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Paypal.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Salesforce.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Slack.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Spotify.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Stripe.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Tradeshift.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Twitch.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Vk.php | 10 +++++++ src/Appwrite/Auth/OAuth2/WordPress.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Yahoo.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Yammer.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Yandex.php | 10 +++++++ src/Appwrite/Auth/OAuth2/Zoom.php | 10 +++++++ 29 files changed, 299 insertions(+), 19 deletions(-) diff --git a/src/Appwrite/Auth/OAuth2.php b/src/Appwrite/Auth/OAuth2.php index 4eafba7610..5ef4263833 100644 --- a/src/Appwrite/Auth/OAuth2.php +++ b/src/Appwrite/Auth/OAuth2.php @@ -52,54 +52,54 @@ abstract class OAuth2 /** * @return string */ - abstract public function getName():string; + abstract public function getName(): string; /** * @return string */ - abstract public function getLoginURL():string; + abstract public function getLoginURL(): string; /** * @param string $code * * @return array */ - abstract protected function getTokens(string $code):array; + abstract protected function getTokens(string $code): array; /** * @param string $refreshToken * * @return array */ - abstract public function refreshTokens(string $refreshToken):array; + abstract public function refreshTokens(string $refreshToken): array; /** * @param $accessToken * * @return string */ - abstract public function getUserID(string $accessToken):string; + abstract public function getUserEmail(string $accessToken): string; + + /** + * Is the OAuth email verified? + * + * @return bool + */ + abstract public function isEmailVerififed(): bool; /** * @param $accessToken * * @return string */ - abstract public function getUserEmail(string $accessToken):string; - - /** - * @param $accessToken - * - * @return string - */ - abstract public function getUserName(string $accessToken):string; + abstract public function getUserName(string $accessToken): string; /** * @param $scope * * @return $this */ - protected function addScope(string $scope):OAuth2 + protected function addScope(string $scope): OAuth2 { // Add a scope to the scopes array if it isn't already present if (!\in_array($scope, $this->scopes)) { @@ -111,7 +111,7 @@ abstract class OAuth2 /** * @return array */ - protected function getScopes():array + protected function getScopes(): array { return $this->scopes; } @@ -121,7 +121,7 @@ abstract class OAuth2 * * @return string */ - public function getAccessToken(string $code):string + public function getAccessToken(string $code): string { $tokens = $this->getTokens($code); return $tokens['access_token'] ?? ''; @@ -132,7 +132,7 @@ abstract class OAuth2 * * @return string */ - public function getRefreshToken(string $code):string + public function getRefreshToken(string $code): string { $tokens = $this->getTokens($code); return $tokens['refresh_token'] ?? ''; @@ -143,7 +143,7 @@ abstract class OAuth2 * * @return string */ - public function getAccessTokenExpiry(string $code):string + public function getAccessTokenExpiry(string $code): string { $tokens = $this->getTokens($code); return $tokens['expires_in'] ?? ''; @@ -170,7 +170,7 @@ abstract class OAuth2 * * @return string */ - protected function request(string $method, string $url = '', array $headers = [], string $payload = ''):string + protected function request(string $method, string $url = '', array $headers = [], string $payload = ''): string { $ch = \curl_init($url); diff --git a/src/Appwrite/Auth/OAuth2/Amazon.php b/src/Appwrite/Auth/OAuth2/Amazon.php index 7ec2769c9a..7b8cf6dbb0 100644 --- a/src/Appwrite/Auth/OAuth2/Amazon.php +++ b/src/Appwrite/Auth/OAuth2/Amazon.php @@ -146,6 +146,16 @@ class Amazon extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Apple.php b/src/Appwrite/Auth/OAuth2/Apple.php index f1ff4b724d..c380f7b6a7 100644 --- a/src/Appwrite/Auth/OAuth2/Apple.php +++ b/src/Appwrite/Auth/OAuth2/Apple.php @@ -146,6 +146,16 @@ class Apple extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Bitbucket.php b/src/Appwrite/Auth/OAuth2/Bitbucket.php index 74d684c845..5d6c6430d9 100644 --- a/src/Appwrite/Auth/OAuth2/Bitbucket.php +++ b/src/Appwrite/Auth/OAuth2/Bitbucket.php @@ -130,6 +130,16 @@ class Bitbucket extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Bitly.php b/src/Appwrite/Auth/OAuth2/Bitly.php index 02a21dc29e..a2d72b492d 100644 --- a/src/Appwrite/Auth/OAuth2/Bitly.php +++ b/src/Appwrite/Auth/OAuth2/Bitly.php @@ -148,6 +148,16 @@ class Bitly extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Box.php b/src/Appwrite/Auth/OAuth2/Box.php index 80d59e9198..a6a1aa27d8 100644 --- a/src/Appwrite/Auth/OAuth2/Box.php +++ b/src/Appwrite/Auth/OAuth2/Box.php @@ -147,6 +147,16 @@ class Box extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Discord.php b/src/Appwrite/Auth/OAuth2/Discord.php index dece646e55..7c31c01e71 100644 --- a/src/Appwrite/Auth/OAuth2/Discord.php +++ b/src/Appwrite/Auth/OAuth2/Discord.php @@ -141,6 +141,16 @@ class Discord extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Dropbox.php b/src/Appwrite/Auth/OAuth2/Dropbox.php index f67e10b01d..ea6a9c8fce 100644 --- a/src/Appwrite/Auth/OAuth2/Dropbox.php +++ b/src/Appwrite/Auth/OAuth2/Dropbox.php @@ -131,6 +131,16 @@ class Dropbox extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Facebook.php b/src/Appwrite/Auth/OAuth2/Facebook.php index 7759a54042..f4e3c54541 100644 --- a/src/Appwrite/Auth/OAuth2/Facebook.php +++ b/src/Appwrite/Auth/OAuth2/Facebook.php @@ -129,6 +129,16 @@ class Facebook extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Github.php b/src/Appwrite/Auth/OAuth2/Github.php index dddd4a5181..4ca85f2b13 100644 --- a/src/Appwrite/Auth/OAuth2/Github.php +++ b/src/Appwrite/Auth/OAuth2/Github.php @@ -137,6 +137,16 @@ class Github extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Gitlab.php b/src/Appwrite/Auth/OAuth2/Gitlab.php index 19ee1363a7..39c827389a 100644 --- a/src/Appwrite/Auth/OAuth2/Gitlab.php +++ b/src/Appwrite/Auth/OAuth2/Gitlab.php @@ -127,6 +127,16 @@ class Gitlab extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Google.php b/src/Appwrite/Auth/OAuth2/Google.php index 5b3ab938b3..b91fd91bee 100644 --- a/src/Appwrite/Auth/OAuth2/Google.php +++ b/src/Appwrite/Auth/OAuth2/Google.php @@ -137,6 +137,16 @@ class Google extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Linkedin.php b/src/Appwrite/Auth/OAuth2/Linkedin.php index 2519859a1b..577426e96b 100644 --- a/src/Appwrite/Auth/OAuth2/Linkedin.php +++ b/src/Appwrite/Auth/OAuth2/Linkedin.php @@ -148,6 +148,16 @@ class Linkedin extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Microsoft.php b/src/Appwrite/Auth/OAuth2/Microsoft.php index ebfd2e4e83..bc4ea55b51 100644 --- a/src/Appwrite/Auth/OAuth2/Microsoft.php +++ b/src/Appwrite/Auth/OAuth2/Microsoft.php @@ -137,6 +137,16 @@ class Microsoft extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Mock.php b/src/Appwrite/Auth/OAuth2/Mock.php index aef92dac23..494674dfb6 100644 --- a/src/Appwrite/Auth/OAuth2/Mock.php +++ b/src/Appwrite/Auth/OAuth2/Mock.php @@ -130,6 +130,16 @@ class Mock extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return true; + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Notion.php b/src/Appwrite/Auth/OAuth2/Notion.php index 5c117caa3c..0a293e3c4d 100644 --- a/src/Appwrite/Auth/OAuth2/Notion.php +++ b/src/Appwrite/Auth/OAuth2/Notion.php @@ -134,6 +134,16 @@ class Notion extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Paypal.php b/src/Appwrite/Auth/OAuth2/Paypal.php index 39544c6bd8..e4e1bb626f 100644 --- a/src/Appwrite/Auth/OAuth2/Paypal.php +++ b/src/Appwrite/Auth/OAuth2/Paypal.php @@ -154,6 +154,16 @@ class Paypal extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Salesforce.php b/src/Appwrite/Auth/OAuth2/Salesforce.php index 04ef1901b5..167629a497 100644 --- a/src/Appwrite/Auth/OAuth2/Salesforce.php +++ b/src/Appwrite/Auth/OAuth2/Salesforce.php @@ -148,6 +148,16 @@ class Salesforce extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Slack.php b/src/Appwrite/Auth/OAuth2/Slack.php index 92c210151b..f11d9fb653 100644 --- a/src/Appwrite/Auth/OAuth2/Slack.php +++ b/src/Appwrite/Auth/OAuth2/Slack.php @@ -128,6 +128,16 @@ class Slack extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Spotify.php b/src/Appwrite/Auth/OAuth2/Spotify.php index 5c1a43299a..ac21b6161b 100644 --- a/src/Appwrite/Auth/OAuth2/Spotify.php +++ b/src/Appwrite/Auth/OAuth2/Spotify.php @@ -141,6 +141,16 @@ class Spotify extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Stripe.php b/src/Appwrite/Auth/OAuth2/Stripe.php index 589e6b7b81..35e01c6c87 100644 --- a/src/Appwrite/Auth/OAuth2/Stripe.php +++ b/src/Appwrite/Auth/OAuth2/Stripe.php @@ -141,6 +141,16 @@ class Stripe extends OAuth2 return $user['email'] ?? ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Tradeshift.php b/src/Appwrite/Auth/OAuth2/Tradeshift.php index 38b58432a0..b2a9720c89 100644 --- a/src/Appwrite/Auth/OAuth2/Tradeshift.php +++ b/src/Appwrite/Auth/OAuth2/Tradeshift.php @@ -141,6 +141,16 @@ class Tradeshift extends OAuth2 return $user['Username'] ?? ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Twitch.php b/src/Appwrite/Auth/OAuth2/Twitch.php index 0deeb088e2..befaeefc14 100644 --- a/src/Appwrite/Auth/OAuth2/Twitch.php +++ b/src/Appwrite/Auth/OAuth2/Twitch.php @@ -140,6 +140,16 @@ class Twitch extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Vk.php b/src/Appwrite/Auth/OAuth2/Vk.php index 5e54b14394..6bcd9b1691 100644 --- a/src/Appwrite/Auth/OAuth2/Vk.php +++ b/src/Appwrite/Auth/OAuth2/Vk.php @@ -150,6 +150,16 @@ class Vk extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/WordPress.php b/src/Appwrite/Auth/OAuth2/WordPress.php index 5b957d9495..c394a96552 100644 --- a/src/Appwrite/Auth/OAuth2/WordPress.php +++ b/src/Appwrite/Auth/OAuth2/WordPress.php @@ -131,6 +131,16 @@ class WordPress extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Yahoo.php b/src/Appwrite/Auth/OAuth2/Yahoo.php index ffefbe9c63..b6650cb739 100644 --- a/src/Appwrite/Auth/OAuth2/Yahoo.php +++ b/src/Appwrite/Auth/OAuth2/Yahoo.php @@ -161,6 +161,16 @@ class Yahoo extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Yammer.php b/src/Appwrite/Auth/OAuth2/Yammer.php index 6e9f4fb86b..97e6f5e133 100644 --- a/src/Appwrite/Auth/OAuth2/Yammer.php +++ b/src/Appwrite/Auth/OAuth2/Yammer.php @@ -130,6 +130,16 @@ class Yammer extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Yandex.php b/src/Appwrite/Auth/OAuth2/Yandex.php index 1f6dda0d1b..4aa4a93cfe 100644 --- a/src/Appwrite/Auth/OAuth2/Yandex.php +++ b/src/Appwrite/Auth/OAuth2/Yandex.php @@ -144,6 +144,16 @@ class Yandex extends OAuth2 return ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param string $accessToken * diff --git a/src/Appwrite/Auth/OAuth2/Zoom.php b/src/Appwrite/Auth/OAuth2/Zoom.php index 9aa77ceb91..f0f322e571 100644 --- a/src/Appwrite/Auth/OAuth2/Zoom.php +++ b/src/Appwrite/Auth/OAuth2/Zoom.php @@ -126,6 +126,16 @@ class Zoom extends OAuth2 return $response['email'] ?? ''; } + /** + * Is the OAuth email verified? + * + * @return bool + */ + public function isEmailVerififed(): bool + { + return false; + } + /** * @param $accessToken * From 957a99ce38d9c58a793dd6283bc3bf2e9d3e6cd6 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 27 Apr 2022 22:08:40 +0300 Subject: [PATCH 105/242] feat: add method to check for email verification --- src/Appwrite/Auth/OAuth2/Paypal.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Auth/OAuth2/Paypal.php b/src/Appwrite/Auth/OAuth2/Paypal.php index e4e1bb626f..e87d3f4d76 100644 --- a/src/Appwrite/Auth/OAuth2/Paypal.php +++ b/src/Appwrite/Auth/OAuth2/Paypal.php @@ -161,7 +161,7 @@ class Paypal extends OAuth2 */ public function isEmailVerififed(): bool { - return false + return false; } /** From 16c45fad29488a03f3ea48c765ee6fb059473d7e Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 27 Apr 2022 22:14:09 +0300 Subject: [PATCH 106/242] feat: add method to check for email verification --- src/Appwrite/Auth/OAuth2.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Amazon.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Apple.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Bitbucket.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Bitly.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Box.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Discord.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Dropbox.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Facebook.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Github.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Gitlab.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Google.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Linkedin.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Microsoft.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Mock.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Notion.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Paypal.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Salesforce.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Slack.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Spotify.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Stripe.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Tradeshift.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Twitch.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Vk.php | 6 ++++-- src/Appwrite/Auth/OAuth2/WordPress.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Yahoo.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Yammer.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Yandex.php | 6 ++++-- src/Appwrite/Auth/OAuth2/Zoom.php | 6 ++++-- 29 files changed, 116 insertions(+), 58 deletions(-) diff --git a/src/Appwrite/Auth/OAuth2.php b/src/Appwrite/Auth/OAuth2.php index 5ef4263833..3956a138c1 100644 --- a/src/Appwrite/Auth/OAuth2.php +++ b/src/Appwrite/Auth/OAuth2.php @@ -81,11 +81,13 @@ abstract class OAuth2 abstract public function getUserEmail(string $accessToken): string; /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - abstract public function isEmailVerififed(): bool; + abstract public function isEmailVerififed(string $accessToken): bool; /** * @param $accessToken diff --git a/src/Appwrite/Auth/OAuth2/Amazon.php b/src/Appwrite/Auth/OAuth2/Amazon.php index 7b8cf6dbb0..d100600592 100644 --- a/src/Appwrite/Auth/OAuth2/Amazon.php +++ b/src/Appwrite/Auth/OAuth2/Amazon.php @@ -147,11 +147,13 @@ class Amazon extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Apple.php b/src/Appwrite/Auth/OAuth2/Apple.php index c380f7b6a7..a58644588c 100644 --- a/src/Appwrite/Auth/OAuth2/Apple.php +++ b/src/Appwrite/Auth/OAuth2/Apple.php @@ -147,11 +147,13 @@ class Apple extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Bitbucket.php b/src/Appwrite/Auth/OAuth2/Bitbucket.php index 5d6c6430d9..c321ca83ba 100644 --- a/src/Appwrite/Auth/OAuth2/Bitbucket.php +++ b/src/Appwrite/Auth/OAuth2/Bitbucket.php @@ -131,11 +131,13 @@ class Bitbucket extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Bitly.php b/src/Appwrite/Auth/OAuth2/Bitly.php index a2d72b492d..0b50e9127f 100644 --- a/src/Appwrite/Auth/OAuth2/Bitly.php +++ b/src/Appwrite/Auth/OAuth2/Bitly.php @@ -149,11 +149,13 @@ class Bitly extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Box.php b/src/Appwrite/Auth/OAuth2/Box.php index a6a1aa27d8..bdc7d52701 100644 --- a/src/Appwrite/Auth/OAuth2/Box.php +++ b/src/Appwrite/Auth/OAuth2/Box.php @@ -148,11 +148,13 @@ class Box extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Discord.php b/src/Appwrite/Auth/OAuth2/Discord.php index 7c31c01e71..b7b58cfa9f 100644 --- a/src/Appwrite/Auth/OAuth2/Discord.php +++ b/src/Appwrite/Auth/OAuth2/Discord.php @@ -142,11 +142,13 @@ class Discord extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Dropbox.php b/src/Appwrite/Auth/OAuth2/Dropbox.php index ea6a9c8fce..592a395a31 100644 --- a/src/Appwrite/Auth/OAuth2/Dropbox.php +++ b/src/Appwrite/Auth/OAuth2/Dropbox.php @@ -132,11 +132,13 @@ class Dropbox extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Facebook.php b/src/Appwrite/Auth/OAuth2/Facebook.php index f4e3c54541..61617d0ea2 100644 --- a/src/Appwrite/Auth/OAuth2/Facebook.php +++ b/src/Appwrite/Auth/OAuth2/Facebook.php @@ -130,11 +130,13 @@ class Facebook extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Github.php b/src/Appwrite/Auth/OAuth2/Github.php index 4ca85f2b13..cdf0119d4b 100644 --- a/src/Appwrite/Auth/OAuth2/Github.php +++ b/src/Appwrite/Auth/OAuth2/Github.php @@ -138,11 +138,13 @@ class Github extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Gitlab.php b/src/Appwrite/Auth/OAuth2/Gitlab.php index 39c827389a..1fa139f566 100644 --- a/src/Appwrite/Auth/OAuth2/Gitlab.php +++ b/src/Appwrite/Auth/OAuth2/Gitlab.php @@ -128,11 +128,13 @@ class Gitlab extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Google.php b/src/Appwrite/Auth/OAuth2/Google.php index b91fd91bee..70d3f9b378 100644 --- a/src/Appwrite/Auth/OAuth2/Google.php +++ b/src/Appwrite/Auth/OAuth2/Google.php @@ -138,11 +138,13 @@ class Google extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Linkedin.php b/src/Appwrite/Auth/OAuth2/Linkedin.php index 577426e96b..5ff8fc42cc 100644 --- a/src/Appwrite/Auth/OAuth2/Linkedin.php +++ b/src/Appwrite/Auth/OAuth2/Linkedin.php @@ -149,11 +149,13 @@ class Linkedin extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Microsoft.php b/src/Appwrite/Auth/OAuth2/Microsoft.php index bc4ea55b51..115756fc46 100644 --- a/src/Appwrite/Auth/OAuth2/Microsoft.php +++ b/src/Appwrite/Auth/OAuth2/Microsoft.php @@ -138,11 +138,13 @@ class Microsoft extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Mock.php b/src/Appwrite/Auth/OAuth2/Mock.php index 494674dfb6..dc53041dcb 100644 --- a/src/Appwrite/Auth/OAuth2/Mock.php +++ b/src/Appwrite/Auth/OAuth2/Mock.php @@ -131,11 +131,13 @@ class Mock extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return true; } diff --git a/src/Appwrite/Auth/OAuth2/Notion.php b/src/Appwrite/Auth/OAuth2/Notion.php index 0a293e3c4d..320f9108b8 100644 --- a/src/Appwrite/Auth/OAuth2/Notion.php +++ b/src/Appwrite/Auth/OAuth2/Notion.php @@ -135,11 +135,13 @@ class Notion extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Paypal.php b/src/Appwrite/Auth/OAuth2/Paypal.php index e87d3f4d76..f74ce9e9f7 100644 --- a/src/Appwrite/Auth/OAuth2/Paypal.php +++ b/src/Appwrite/Auth/OAuth2/Paypal.php @@ -155,11 +155,13 @@ class Paypal extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Salesforce.php b/src/Appwrite/Auth/OAuth2/Salesforce.php index 167629a497..ed640b0951 100644 --- a/src/Appwrite/Auth/OAuth2/Salesforce.php +++ b/src/Appwrite/Auth/OAuth2/Salesforce.php @@ -149,11 +149,13 @@ class Salesforce extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Slack.php b/src/Appwrite/Auth/OAuth2/Slack.php index f11d9fb653..655714c947 100644 --- a/src/Appwrite/Auth/OAuth2/Slack.php +++ b/src/Appwrite/Auth/OAuth2/Slack.php @@ -129,11 +129,13 @@ class Slack extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Spotify.php b/src/Appwrite/Auth/OAuth2/Spotify.php index ac21b6161b..4a9a955c30 100644 --- a/src/Appwrite/Auth/OAuth2/Spotify.php +++ b/src/Appwrite/Auth/OAuth2/Spotify.php @@ -142,11 +142,13 @@ class Spotify extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Stripe.php b/src/Appwrite/Auth/OAuth2/Stripe.php index 35e01c6c87..c136ce5599 100644 --- a/src/Appwrite/Auth/OAuth2/Stripe.php +++ b/src/Appwrite/Auth/OAuth2/Stripe.php @@ -142,11 +142,13 @@ class Stripe extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Tradeshift.php b/src/Appwrite/Auth/OAuth2/Tradeshift.php index b2a9720c89..968bc89b49 100644 --- a/src/Appwrite/Auth/OAuth2/Tradeshift.php +++ b/src/Appwrite/Auth/OAuth2/Tradeshift.php @@ -142,11 +142,13 @@ class Tradeshift extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Twitch.php b/src/Appwrite/Auth/OAuth2/Twitch.php index befaeefc14..4c8b35385d 100644 --- a/src/Appwrite/Auth/OAuth2/Twitch.php +++ b/src/Appwrite/Auth/OAuth2/Twitch.php @@ -141,11 +141,13 @@ class Twitch extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Vk.php b/src/Appwrite/Auth/OAuth2/Vk.php index 6bcd9b1691..cbcc98a0e5 100644 --- a/src/Appwrite/Auth/OAuth2/Vk.php +++ b/src/Appwrite/Auth/OAuth2/Vk.php @@ -151,11 +151,13 @@ class Vk extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/WordPress.php b/src/Appwrite/Auth/OAuth2/WordPress.php index c394a96552..76fb010fbd 100644 --- a/src/Appwrite/Auth/OAuth2/WordPress.php +++ b/src/Appwrite/Auth/OAuth2/WordPress.php @@ -132,11 +132,13 @@ class WordPress extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Yahoo.php b/src/Appwrite/Auth/OAuth2/Yahoo.php index b6650cb739..f2c1b2e45c 100644 --- a/src/Appwrite/Auth/OAuth2/Yahoo.php +++ b/src/Appwrite/Auth/OAuth2/Yahoo.php @@ -162,11 +162,13 @@ class Yahoo extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Yammer.php b/src/Appwrite/Auth/OAuth2/Yammer.php index 97e6f5e133..00c1c512cf 100644 --- a/src/Appwrite/Auth/OAuth2/Yammer.php +++ b/src/Appwrite/Auth/OAuth2/Yammer.php @@ -131,11 +131,13 @@ class Yammer extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Yandex.php b/src/Appwrite/Auth/OAuth2/Yandex.php index 4aa4a93cfe..f25d366f8e 100644 --- a/src/Appwrite/Auth/OAuth2/Yandex.php +++ b/src/Appwrite/Auth/OAuth2/Yandex.php @@ -145,11 +145,13 @@ class Yandex extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Zoom.php b/src/Appwrite/Auth/OAuth2/Zoom.php index f0f322e571..df63749fb0 100644 --- a/src/Appwrite/Auth/OAuth2/Zoom.php +++ b/src/Appwrite/Auth/OAuth2/Zoom.php @@ -127,11 +127,13 @@ class Zoom extends OAuth2 } /** - * Is the OAuth email verified? + * Check if the OAuth email is verified + * + * @param $accessToken * * @return bool */ - public function isEmailVerififed(): bool + public function isEmailVerififed(string $accessToken): bool { return false; } From d5b2f0c7d4ccb5fa16162fc1f46f8e071ce3df5b Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 27 Apr 2022 22:32:06 +0300 Subject: [PATCH 107/242] feat: update paypal OAuth provider --- src/Appwrite/Auth/OAuth2/Paypal.php | 16 +++++++++++++++- src/Appwrite/Auth/OAuth2/Salesforce.php | 8 ++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Auth/OAuth2/Paypal.php b/src/Appwrite/Auth/OAuth2/Paypal.php index f74ce9e9f7..06637b5ec7 100644 --- a/src/Appwrite/Auth/OAuth2/Paypal.php +++ b/src/Appwrite/Auth/OAuth2/Paypal.php @@ -148,7 +148,13 @@ class Paypal extends OAuth2 $user = $this->getUser($accessToken); if (isset($user['emails'])) { - return $user['emails'][0]['value']; + $email = array_filter($user['emails'], function ($email) { + return $email['primary'] === true; + }); + + if (!empty($email)) { + return $email[0]['value']; + } } return ''; @@ -157,12 +163,20 @@ class Paypal extends OAuth2 /** * Check if the OAuth email is verified * + * @link https://developer.paypal.com/docs/api/identity/v1/#userinfo_get + * * @param $accessToken * * @return bool */ public function isEmailVerififed(string $accessToken): bool { + $user = $this->getUser($accessToken); + + if (isset($user['verified_account']) && $user['verified_account'] === true) { + return true; + } + return false; } diff --git a/src/Appwrite/Auth/OAuth2/Salesforce.php b/src/Appwrite/Auth/OAuth2/Salesforce.php index ed640b0951..699cbc7581 100644 --- a/src/Appwrite/Auth/OAuth2/Salesforce.php +++ b/src/Appwrite/Auth/OAuth2/Salesforce.php @@ -151,12 +151,20 @@ class Salesforce extends OAuth2 /** * Check if the OAuth email is verified * + * @link https://help.salesforce.com/s/articleView?id=sf.remoteaccess_using_userinfo_endpoint.htm&type=5 + * * @param $accessToken * * @return bool */ public function isEmailVerififed(string $accessToken): bool { + $user = $this->getUser($accessToken); + + if (isset($user['email_verified']) && $user['email_verified'] === true) { + return true; + } + return false; } From 996504043ee26256550a6fae5a04ffc5b85b57b7 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 27 Apr 2022 22:57:36 +0300 Subject: [PATCH 108/242] feat: update slack OAuth provider --- src/Appwrite/Auth/OAuth2/Slack.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Auth/OAuth2/Slack.php b/src/Appwrite/Auth/OAuth2/Slack.php index 655714c947..344790c162 100644 --- a/src/Appwrite/Auth/OAuth2/Slack.php +++ b/src/Appwrite/Auth/OAuth2/Slack.php @@ -131,12 +131,22 @@ class Slack extends OAuth2 /** * Check if the OAuth email is verified * + * In case of Slack, if an email is present, it is verified + * + * @link https://slack.com/help/articles/207262907-Change-your-email-address + * * @param $accessToken * * @return bool */ public function isEmailVerififed(string $accessToken): bool { + $user = $this->getUser($accessToken); + + if (isset($user['user']['email'])) { + return true; + } + return false; } @@ -157,6 +167,8 @@ class Slack extends OAuth2 } /** + * @link https://api.slack.com/methods/users.identity + * * @param string $accessToken * * @return array @@ -164,7 +176,6 @@ class Slack extends OAuth2 protected function getUser(string $accessToken):array { if (empty($this->user)) { - // https://api.slack.com/methods/users.identity $user = $this->request( 'GET', 'https://slack.com/api/users.identity?token='.\urlencode($accessToken) From cf44f8c03d8387376599f58d6269fd06e8b3aa25 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 27 Apr 2022 22:58:52 +0300 Subject: [PATCH 109/242] feat: update spotify OAuth provider --- src/Appwrite/Auth/OAuth2/Spotify.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Auth/OAuth2/Spotify.php b/src/Appwrite/Auth/OAuth2/Spotify.php index 4a9a955c30..7509e271a7 100644 --- a/src/Appwrite/Auth/OAuth2/Spotify.php +++ b/src/Appwrite/Auth/OAuth2/Spotify.php @@ -144,6 +144,8 @@ class Spotify extends OAuth2 /** * Check if the OAuth email is verified * + * @link https://developer.spotify.com/documentation/web-api/reference/#/operations/get-current-users-profile + * * @param $accessToken * * @return bool @@ -179,7 +181,7 @@ class Spotify extends OAuth2 if (empty($this->user)) { $this->user = \json_decode($this->request( 'GET', - $this->resourceEndpoint . "me", + $this->resourceEndpoint . 'me', ['Authorization: Bearer '.\urlencode($accessToken)] ), true); } From f815201ada368a2a12c6eecee4689511e2331103 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 27 Apr 2022 23:10:48 +0300 Subject: [PATCH 110/242] feat: update stripe OAuth provider --- src/Appwrite/Auth/OAuth2/Slack.php | 8 ++------ src/Appwrite/Auth/OAuth2/Stripe.php | 5 ++++- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Appwrite/Auth/OAuth2/Slack.php b/src/Appwrite/Auth/OAuth2/Slack.php index 344790c162..f61c776d41 100644 --- a/src/Appwrite/Auth/OAuth2/Slack.php +++ b/src/Appwrite/Auth/OAuth2/Slack.php @@ -141,13 +141,9 @@ class Slack extends OAuth2 */ public function isEmailVerififed(string $accessToken): bool { - $user = $this->getUser($accessToken); + $email = $this->getUserEmail($accessToken); - if (isset($user['user']['email'])) { - return true; - } - - return false; + return !empty($email); } /** diff --git a/src/Appwrite/Auth/OAuth2/Stripe.php b/src/Appwrite/Auth/OAuth2/Stripe.php index c136ce5599..5cfceaacae 100644 --- a/src/Appwrite/Auth/OAuth2/Stripe.php +++ b/src/Appwrite/Auth/OAuth2/Stripe.php @@ -144,13 +144,16 @@ class Stripe extends OAuth2 /** * Check if the OAuth email is verified * + * Stripe emails if present are verfied. + * * @param $accessToken * * @return bool */ public function isEmailVerififed(string $accessToken): bool { - return false; + $email = $this->getUserEmail($accessToken); + return !empty($email); } /** From 274a61f2c463cd15936bf0adb6b23f24efe51136 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 27 Apr 2022 23:19:15 +0300 Subject: [PATCH 111/242] feat: update Tradeshift OAuth provider --- src/Appwrite/Auth/OAuth2/Spotify.php | 2 ++ src/Appwrite/Auth/OAuth2/Stripe.php | 3 ++- src/Appwrite/Auth/OAuth2/Tradeshift.php | 6 +++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Auth/OAuth2/Spotify.php b/src/Appwrite/Auth/OAuth2/Spotify.php index 7509e271a7..d9f3589d0b 100644 --- a/src/Appwrite/Auth/OAuth2/Spotify.php +++ b/src/Appwrite/Auth/OAuth2/Spotify.php @@ -144,6 +144,8 @@ class Spotify extends OAuth2 /** * Check if the OAuth email is verified * + * Spotify does not assure that the email is verified + * * @link https://developer.spotify.com/documentation/web-api/reference/#/operations/get-current-users-profile * * @param $accessToken diff --git a/src/Appwrite/Auth/OAuth2/Stripe.php b/src/Appwrite/Auth/OAuth2/Stripe.php index 5cfceaacae..cf55156a14 100644 --- a/src/Appwrite/Auth/OAuth2/Stripe.php +++ b/src/Appwrite/Auth/OAuth2/Stripe.php @@ -144,7 +144,7 @@ class Stripe extends OAuth2 /** * Check if the OAuth email is verified * - * Stripe emails if present are verfied. + * Stripe emails if present are verfied. This was verified manually * * @param $accessToken * @@ -153,6 +153,7 @@ class Stripe extends OAuth2 public function isEmailVerififed(string $accessToken): bool { $email = $this->getUserEmail($accessToken); + return !empty($email); } diff --git a/src/Appwrite/Auth/OAuth2/Tradeshift.php b/src/Appwrite/Auth/OAuth2/Tradeshift.php index 968bc89b49..1aac40d934 100644 --- a/src/Appwrite/Auth/OAuth2/Tradeshift.php +++ b/src/Appwrite/Auth/OAuth2/Tradeshift.php @@ -144,13 +144,17 @@ class Tradeshift extends OAuth2 /** * Check if the OAuth email is verified * + * Tradeshift's signup process requires emails to be verified. This was verified manually + * * @param $accessToken * * @return bool */ public function isEmailVerififed(string $accessToken): bool { - return false; + $email = $this->getUser($accessToken); + + return !empty($email); } /** From 114e8300b7777a7d191987aa1294111564fac8b2 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 27 Apr 2022 23:25:28 +0300 Subject: [PATCH 112/242] feat: update Twitch OAuth provider --- src/Appwrite/Auth/OAuth2/Slack.php | 2 +- src/Appwrite/Auth/OAuth2/Stripe.php | 4 ++-- src/Appwrite/Auth/OAuth2/Tradeshift.php | 4 ++-- src/Appwrite/Auth/OAuth2/Twitch.php | 8 +++++++- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Appwrite/Auth/OAuth2/Slack.php b/src/Appwrite/Auth/OAuth2/Slack.php index f61c776d41..da09ad318a 100644 --- a/src/Appwrite/Auth/OAuth2/Slack.php +++ b/src/Appwrite/Auth/OAuth2/Slack.php @@ -131,7 +131,7 @@ class Slack extends OAuth2 /** * Check if the OAuth email is verified * - * In case of Slack, if an email is present, it is verified + * If present, the email is verified. This was verfied through a manual Slack sign up process * * @link https://slack.com/help/articles/207262907-Change-your-email-address * diff --git a/src/Appwrite/Auth/OAuth2/Stripe.php b/src/Appwrite/Auth/OAuth2/Stripe.php index cf55156a14..dc46974317 100644 --- a/src/Appwrite/Auth/OAuth2/Stripe.php +++ b/src/Appwrite/Auth/OAuth2/Stripe.php @@ -144,7 +144,7 @@ class Stripe extends OAuth2 /** * Check if the OAuth email is verified * - * Stripe emails if present are verfied. This was verified manually + * If present, the email is verified. This was verfied through a manual Stripe sign up process * * @param $accessToken * @@ -153,7 +153,7 @@ class Stripe extends OAuth2 public function isEmailVerififed(string $accessToken): bool { $email = $this->getUserEmail($accessToken); - + return !empty($email); } diff --git a/src/Appwrite/Auth/OAuth2/Tradeshift.php b/src/Appwrite/Auth/OAuth2/Tradeshift.php index 1aac40d934..96339137c1 100644 --- a/src/Appwrite/Auth/OAuth2/Tradeshift.php +++ b/src/Appwrite/Auth/OAuth2/Tradeshift.php @@ -144,7 +144,7 @@ class Tradeshift extends OAuth2 /** * Check if the OAuth email is verified * - * Tradeshift's signup process requires emails to be verified. This was verified manually + * If present, the email is verified. This was verfied through a manual Tradeshift sign up process * * @param $accessToken * @@ -153,7 +153,7 @@ class Tradeshift extends OAuth2 public function isEmailVerififed(string $accessToken): bool { $email = $this->getUser($accessToken); - + return !empty($email); } diff --git a/src/Appwrite/Auth/OAuth2/Twitch.php b/src/Appwrite/Auth/OAuth2/Twitch.php index 4c8b35385d..73cd57ec75 100644 --- a/src/Appwrite/Auth/OAuth2/Twitch.php +++ b/src/Appwrite/Auth/OAuth2/Twitch.php @@ -143,13 +143,19 @@ class Twitch extends OAuth2 /** * Check if the OAuth email is verified * + * If present, the email is verified + * + * @link https://dev.twitch.tv/docs/api/reference#get-users + * * @param $accessToken * * @return bool */ public function isEmailVerififed(string $accessToken): bool { - return false; + $email = $this->getUserEmail($accessToken); + + return !empty($email); } /** From a2542e7716c00afde49927e4606b6358b4073a40 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 27 Apr 2022 23:27:21 +0300 Subject: [PATCH 113/242] feat: fixed typo --- src/Appwrite/Auth/OAuth2.php | 2 +- src/Appwrite/Auth/OAuth2/Amazon.php | 2 +- src/Appwrite/Auth/OAuth2/Apple.php | 2 +- src/Appwrite/Auth/OAuth2/Bitbucket.php | 2 +- src/Appwrite/Auth/OAuth2/Bitly.php | 2 +- src/Appwrite/Auth/OAuth2/Box.php | 2 +- src/Appwrite/Auth/OAuth2/Discord.php | 2 +- src/Appwrite/Auth/OAuth2/Dropbox.php | 2 +- src/Appwrite/Auth/OAuth2/Facebook.php | 2 +- src/Appwrite/Auth/OAuth2/Github.php | 2 +- src/Appwrite/Auth/OAuth2/Gitlab.php | 2 +- src/Appwrite/Auth/OAuth2/Google.php | 2 +- src/Appwrite/Auth/OAuth2/Linkedin.php | 2 +- src/Appwrite/Auth/OAuth2/Microsoft.php | 2 +- src/Appwrite/Auth/OAuth2/Mock.php | 2 +- src/Appwrite/Auth/OAuth2/Notion.php | 2 +- src/Appwrite/Auth/OAuth2/Paypal.php | 2 +- src/Appwrite/Auth/OAuth2/Salesforce.php | 2 +- src/Appwrite/Auth/OAuth2/Slack.php | 2 +- src/Appwrite/Auth/OAuth2/Spotify.php | 2 +- src/Appwrite/Auth/OAuth2/Stripe.php | 2 +- src/Appwrite/Auth/OAuth2/Tradeshift.php | 2 +- src/Appwrite/Auth/OAuth2/Twitch.php | 2 +- src/Appwrite/Auth/OAuth2/Vk.php | 2 +- src/Appwrite/Auth/OAuth2/WordPress.php | 2 +- src/Appwrite/Auth/OAuth2/Yahoo.php | 2 +- src/Appwrite/Auth/OAuth2/Yammer.php | 2 +- src/Appwrite/Auth/OAuth2/Yandex.php | 2 +- src/Appwrite/Auth/OAuth2/Zoom.php | 2 +- 29 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/Appwrite/Auth/OAuth2.php b/src/Appwrite/Auth/OAuth2.php index 3956a138c1..10a81d7b6c 100644 --- a/src/Appwrite/Auth/OAuth2.php +++ b/src/Appwrite/Auth/OAuth2.php @@ -87,7 +87,7 @@ abstract class OAuth2 * * @return bool */ - abstract public function isEmailVerififed(string $accessToken): bool; + abstract public function isEmailVerified(string $accessToken): bool; /** * @param $accessToken diff --git a/src/Appwrite/Auth/OAuth2/Amazon.php b/src/Appwrite/Auth/OAuth2/Amazon.php index d100600592..c406817f36 100644 --- a/src/Appwrite/Auth/OAuth2/Amazon.php +++ b/src/Appwrite/Auth/OAuth2/Amazon.php @@ -153,7 +153,7 @@ class Amazon extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Apple.php b/src/Appwrite/Auth/OAuth2/Apple.php index a58644588c..de438c9889 100644 --- a/src/Appwrite/Auth/OAuth2/Apple.php +++ b/src/Appwrite/Auth/OAuth2/Apple.php @@ -153,7 +153,7 @@ class Apple extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Bitbucket.php b/src/Appwrite/Auth/OAuth2/Bitbucket.php index c321ca83ba..ee675d48c0 100644 --- a/src/Appwrite/Auth/OAuth2/Bitbucket.php +++ b/src/Appwrite/Auth/OAuth2/Bitbucket.php @@ -137,7 +137,7 @@ class Bitbucket extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Bitly.php b/src/Appwrite/Auth/OAuth2/Bitly.php index 0b50e9127f..4084874265 100644 --- a/src/Appwrite/Auth/OAuth2/Bitly.php +++ b/src/Appwrite/Auth/OAuth2/Bitly.php @@ -155,7 +155,7 @@ class Bitly extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Box.php b/src/Appwrite/Auth/OAuth2/Box.php index bdc7d52701..f58ce3692f 100644 --- a/src/Appwrite/Auth/OAuth2/Box.php +++ b/src/Appwrite/Auth/OAuth2/Box.php @@ -154,7 +154,7 @@ class Box extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Discord.php b/src/Appwrite/Auth/OAuth2/Discord.php index b7b58cfa9f..033150d045 100644 --- a/src/Appwrite/Auth/OAuth2/Discord.php +++ b/src/Appwrite/Auth/OAuth2/Discord.php @@ -148,7 +148,7 @@ class Discord extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Dropbox.php b/src/Appwrite/Auth/OAuth2/Dropbox.php index 592a395a31..ac03e89153 100644 --- a/src/Appwrite/Auth/OAuth2/Dropbox.php +++ b/src/Appwrite/Auth/OAuth2/Dropbox.php @@ -138,7 +138,7 @@ class Dropbox extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Facebook.php b/src/Appwrite/Auth/OAuth2/Facebook.php index 61617d0ea2..888f45caea 100644 --- a/src/Appwrite/Auth/OAuth2/Facebook.php +++ b/src/Appwrite/Auth/OAuth2/Facebook.php @@ -136,7 +136,7 @@ class Facebook extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Github.php b/src/Appwrite/Auth/OAuth2/Github.php index cdf0119d4b..d6c52d0eab 100644 --- a/src/Appwrite/Auth/OAuth2/Github.php +++ b/src/Appwrite/Auth/OAuth2/Github.php @@ -144,7 +144,7 @@ class Github extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Gitlab.php b/src/Appwrite/Auth/OAuth2/Gitlab.php index 1fa139f566..ee898e251a 100644 --- a/src/Appwrite/Auth/OAuth2/Gitlab.php +++ b/src/Appwrite/Auth/OAuth2/Gitlab.php @@ -134,7 +134,7 @@ class Gitlab extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Google.php b/src/Appwrite/Auth/OAuth2/Google.php index 70d3f9b378..bdc3b42adb 100644 --- a/src/Appwrite/Auth/OAuth2/Google.php +++ b/src/Appwrite/Auth/OAuth2/Google.php @@ -144,7 +144,7 @@ class Google extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Linkedin.php b/src/Appwrite/Auth/OAuth2/Linkedin.php index 5ff8fc42cc..92a2e32ed1 100644 --- a/src/Appwrite/Auth/OAuth2/Linkedin.php +++ b/src/Appwrite/Auth/OAuth2/Linkedin.php @@ -155,7 +155,7 @@ class Linkedin extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Microsoft.php b/src/Appwrite/Auth/OAuth2/Microsoft.php index 115756fc46..150fbda85b 100644 --- a/src/Appwrite/Auth/OAuth2/Microsoft.php +++ b/src/Appwrite/Auth/OAuth2/Microsoft.php @@ -144,7 +144,7 @@ class Microsoft extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Mock.php b/src/Appwrite/Auth/OAuth2/Mock.php index dc53041dcb..7e8848bdf9 100644 --- a/src/Appwrite/Auth/OAuth2/Mock.php +++ b/src/Appwrite/Auth/OAuth2/Mock.php @@ -137,7 +137,7 @@ class Mock extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return true; } diff --git a/src/Appwrite/Auth/OAuth2/Notion.php b/src/Appwrite/Auth/OAuth2/Notion.php index 320f9108b8..3687be0b82 100644 --- a/src/Appwrite/Auth/OAuth2/Notion.php +++ b/src/Appwrite/Auth/OAuth2/Notion.php @@ -141,7 +141,7 @@ class Notion extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Paypal.php b/src/Appwrite/Auth/OAuth2/Paypal.php index 06637b5ec7..d517c8c685 100644 --- a/src/Appwrite/Auth/OAuth2/Paypal.php +++ b/src/Appwrite/Auth/OAuth2/Paypal.php @@ -169,7 +169,7 @@ class Paypal extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { $user = $this->getUser($accessToken); diff --git a/src/Appwrite/Auth/OAuth2/Salesforce.php b/src/Appwrite/Auth/OAuth2/Salesforce.php index 699cbc7581..3181657235 100644 --- a/src/Appwrite/Auth/OAuth2/Salesforce.php +++ b/src/Appwrite/Auth/OAuth2/Salesforce.php @@ -157,7 +157,7 @@ class Salesforce extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { $user = $this->getUser($accessToken); diff --git a/src/Appwrite/Auth/OAuth2/Slack.php b/src/Appwrite/Auth/OAuth2/Slack.php index da09ad318a..f1c5b6af9c 100644 --- a/src/Appwrite/Auth/OAuth2/Slack.php +++ b/src/Appwrite/Auth/OAuth2/Slack.php @@ -139,7 +139,7 @@ class Slack extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { $email = $this->getUserEmail($accessToken); diff --git a/src/Appwrite/Auth/OAuth2/Spotify.php b/src/Appwrite/Auth/OAuth2/Spotify.php index d9f3589d0b..9c541cf8ee 100644 --- a/src/Appwrite/Auth/OAuth2/Spotify.php +++ b/src/Appwrite/Auth/OAuth2/Spotify.php @@ -152,7 +152,7 @@ class Spotify extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Stripe.php b/src/Appwrite/Auth/OAuth2/Stripe.php index dc46974317..b34937a53e 100644 --- a/src/Appwrite/Auth/OAuth2/Stripe.php +++ b/src/Appwrite/Auth/OAuth2/Stripe.php @@ -150,7 +150,7 @@ class Stripe extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { $email = $this->getUserEmail($accessToken); diff --git a/src/Appwrite/Auth/OAuth2/Tradeshift.php b/src/Appwrite/Auth/OAuth2/Tradeshift.php index 96339137c1..142216ce26 100644 --- a/src/Appwrite/Auth/OAuth2/Tradeshift.php +++ b/src/Appwrite/Auth/OAuth2/Tradeshift.php @@ -150,7 +150,7 @@ class Tradeshift extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { $email = $this->getUser($accessToken); diff --git a/src/Appwrite/Auth/OAuth2/Twitch.php b/src/Appwrite/Auth/OAuth2/Twitch.php index 73cd57ec75..acb8587ced 100644 --- a/src/Appwrite/Auth/OAuth2/Twitch.php +++ b/src/Appwrite/Auth/OAuth2/Twitch.php @@ -151,7 +151,7 @@ class Twitch extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { $email = $this->getUserEmail($accessToken); diff --git a/src/Appwrite/Auth/OAuth2/Vk.php b/src/Appwrite/Auth/OAuth2/Vk.php index cbcc98a0e5..fefd2f7862 100644 --- a/src/Appwrite/Auth/OAuth2/Vk.php +++ b/src/Appwrite/Auth/OAuth2/Vk.php @@ -157,7 +157,7 @@ class Vk extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/WordPress.php b/src/Appwrite/Auth/OAuth2/WordPress.php index 76fb010fbd..4f9019f69d 100644 --- a/src/Appwrite/Auth/OAuth2/WordPress.php +++ b/src/Appwrite/Auth/OAuth2/WordPress.php @@ -138,7 +138,7 @@ class WordPress extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Yahoo.php b/src/Appwrite/Auth/OAuth2/Yahoo.php index f2c1b2e45c..fb6b73f583 100644 --- a/src/Appwrite/Auth/OAuth2/Yahoo.php +++ b/src/Appwrite/Auth/OAuth2/Yahoo.php @@ -168,7 +168,7 @@ class Yahoo extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Yammer.php b/src/Appwrite/Auth/OAuth2/Yammer.php index 00c1c512cf..c5c4c34b55 100644 --- a/src/Appwrite/Auth/OAuth2/Yammer.php +++ b/src/Appwrite/Auth/OAuth2/Yammer.php @@ -137,7 +137,7 @@ class Yammer extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Yandex.php b/src/Appwrite/Auth/OAuth2/Yandex.php index f25d366f8e..385127ca74 100644 --- a/src/Appwrite/Auth/OAuth2/Yandex.php +++ b/src/Appwrite/Auth/OAuth2/Yandex.php @@ -151,7 +151,7 @@ class Yandex extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } diff --git a/src/Appwrite/Auth/OAuth2/Zoom.php b/src/Appwrite/Auth/OAuth2/Zoom.php index df63749fb0..8d3987d7c6 100644 --- a/src/Appwrite/Auth/OAuth2/Zoom.php +++ b/src/Appwrite/Auth/OAuth2/Zoom.php @@ -133,7 +133,7 @@ class Zoom extends OAuth2 * * @return bool */ - public function isEmailVerififed(string $accessToken): bool + public function isEmailVerified(string $accessToken): bool { return false; } From b810d52e590f510d9125820ce3b1d5895c0c0f8a Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 27 Apr 2022 23:39:11 +0300 Subject: [PATCH 114/242] feat: update Wordpress OAuth provider --- src/Appwrite/Auth/OAuth2/WordPress.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Appwrite/Auth/OAuth2/WordPress.php b/src/Appwrite/Auth/OAuth2/WordPress.php index 4f9019f69d..03c1802834 100644 --- a/src/Appwrite/Auth/OAuth2/WordPress.php +++ b/src/Appwrite/Auth/OAuth2/WordPress.php @@ -134,12 +134,20 @@ class WordPress extends OAuth2 /** * Check if the OAuth email is verified * + * @link https://developer.wordpress.com/docs/api/1.1/get/me/ + * * @param $accessToken * * @return bool */ public function isEmailVerified(string $accessToken): bool { + $user = $this->getUser($accessToken); + + if (isset($user['email_verified']) && $user['email_verified'] === true) { + return true; + } + return false; } From 99871309c1b3681d82d2af1027625ebb23f3973b Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 27 Apr 2022 23:46:34 +0300 Subject: [PATCH 115/242] feat: update Yahoo OAuth provider --- src/Appwrite/Auth/OAuth2/Yahoo.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Auth/OAuth2/Yahoo.php b/src/Appwrite/Auth/OAuth2/Yahoo.php index fb6b73f583..90e797568f 100644 --- a/src/Appwrite/Auth/OAuth2/Yahoo.php +++ b/src/Appwrite/Auth/OAuth2/Yahoo.php @@ -164,13 +164,17 @@ class Yahoo extends OAuth2 /** * Check if the OAuth email is verified * + * If present, the email is verified. This was verfied through a manual Yahoo sign up process + * * @param $accessToken * * @return bool */ public function isEmailVerified(string $accessToken): bool { - return false; + $email = $this->getUserEmail($accessToken); + + return !empty($email); } /** From 35ac32bd2255bc04cc778b6ecb22dd6b1f8c7126 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 27 Apr 2022 23:50:03 +0300 Subject: [PATCH 116/242] feat: update Yammer OAuth provider --- src/Appwrite/Auth/OAuth2/Yammer.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Auth/OAuth2/Yammer.php b/src/Appwrite/Auth/OAuth2/Yammer.php index c5c4c34b55..a50975c82e 100644 --- a/src/Appwrite/Auth/OAuth2/Yammer.php +++ b/src/Appwrite/Auth/OAuth2/Yammer.php @@ -133,13 +133,17 @@ class Yammer extends OAuth2 /** * Check if the OAuth email is verified * + * If present, the email is verified. + * * @param $accessToken * * @return bool */ public function isEmailVerified(string $accessToken): bool { - return false; + $email = $this->getUserEmail($accessToken); + + return !empty($email); } /** From d52af8afa987fec16cfd8c03930aa0fe1931fb86 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Thu, 28 Apr 2022 10:44:09 +0300 Subject: [PATCH 117/242] feat: update Zoom & Amazon OAuth provider --- src/Appwrite/Auth/OAuth2/Amazon.php | 6 +++++- src/Appwrite/Auth/OAuth2/Zoom.php | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Auth/OAuth2/Amazon.php b/src/Appwrite/Auth/OAuth2/Amazon.php index c406817f36..edace5df6b 100644 --- a/src/Appwrite/Auth/OAuth2/Amazon.php +++ b/src/Appwrite/Auth/OAuth2/Amazon.php @@ -149,13 +149,17 @@ class Amazon extends OAuth2 /** * Check if the OAuth email is verified * + * If present, the email is verified. This was verfied through a manual Amazon sign up process + * * @param $accessToken * * @return bool */ public function isEmailVerified(string $accessToken): bool { - return false; + $email = $this->getUserEmail($accessToken); + + return !empty($email); } /** diff --git a/src/Appwrite/Auth/OAuth2/Zoom.php b/src/Appwrite/Auth/OAuth2/Zoom.php index 8d3987d7c6..a36c3e44c1 100644 --- a/src/Appwrite/Auth/OAuth2/Zoom.php +++ b/src/Appwrite/Auth/OAuth2/Zoom.php @@ -129,12 +129,20 @@ class Zoom extends OAuth2 /** * Check if the OAuth email is verified * + * @link https://marketplace.zoom.us/docs/api-reference/zoom-api/methods/#operation/user + * * @param $accessToken * * @return bool */ public function isEmailVerified(string $accessToken): bool { + $user = $this->getUser($accessToken); + + if (isset($user['verified']) && $user['verified'] === 1) { + return true; + } + return false; } From 1457bab4b1aa3bd78eb8f4d5476db65fc4e190a7 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Thu, 28 Apr 2022 13:40:59 +0200 Subject: [PATCH 118/242] feat: event model ui init --- app/controllers/web/console.php | 4 +- app/views/console/webhooks/index.phtml | 125 +++++++++++++---- gulpfile.js | 1 + package-lock.json | 32 +++-- public/dist/scripts/app-all.js | 8 +- public/dist/scripts/app.js | 8 +- public/scripts/events.js | 178 +++++++++++++++++++++++++ 7 files changed, 305 insertions(+), 51 deletions(-) create mode 100644 public/scripts/events.js diff --git a/app/controllers/web/console.php b/app/controllers/web/console.php index 58bc905dbe..06fd839aae 100644 --- a/app/controllers/web/console.php +++ b/app/controllers/web/console.php @@ -162,9 +162,7 @@ App::get('/console/webhooks') $page = new View(__DIR__.'/../../views/console/webhooks/index.phtml'); - $page - ->setParam('events', Config::getParam('events', [])) - ; + $page->setParam('events', Config::getParam('events', [])); $layout ->setParam('title', APP_NAME.' - Webhooks') diff --git a/app/views/console/webhooks/index.phtml b/app/views/console/webhooks/index.phtml index 93bc72edd7..54c9f6e765 100644 --- a/app/views/console/webhooks/index.phtml +++ b/app/views/console/webhooks/index.phtml @@ -1,8 +1,27 @@ getParam('events', [])); +$events = $this->getParam('events', []); + +foreach ($events as $name => $event) { + foreach ($event as $key => $value) { + if (!\str_starts_with($key, '$')) { + if (!($value['$resource'] ?? false)) { + $patterns[] = "{$name}.{$key}"; + } else { + foreach ($value as $key2 => $value2) { + if (!\str_starts_with($key2, '$')) { + if (!($value2['$resource'] ?? false)) { + $patterns[] = "{$key}.{$key2}"; + } + } + } + } + } + } +} ?> +

Home @@ -61,22 +80,46 @@ $events = array_keys($this->getParam('events', [])); -
- -
- $event): ?> -
- -   - +
+ + + + +
+ + +
Leave empty for wildcard access
+
+ + +
Leave empty for wildcard access
+
+
+ + +
+
@@ -99,7 +142,7 @@ $events = array_keys($this->getParam('events', [])); Learn more

- +
@@ -183,22 +226,46 @@ $events = array_keys($this->getParam('events', [])); -
- -
- $event): ?> -
- -   - +
+ + + + +
+ + +
Leave empty for wildcard access
+
+ + +
Leave empty for wildcard access
+
+
+ + +
+
@@ -221,7 +288,7 @@ $events = array_keys($this->getParam('events', [])); Learn more

- +
diff --git a/gulpfile.js b/gulpfile.js index 781f7bad4d..8bd41ece4c 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -34,6 +34,7 @@ const configApp = { 'public/scripts/filters.js', 'public/scripts/app.js', 'public/scripts/upload-modal.js', + 'public/scripts/events.js', 'public/scripts/views/service.js', diff --git a/package-lock.json b/package-lock.json index e3f483af6a..999afa76a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2950,6 +2950,15 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, + "node_modules/meow/node_modules/trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -4601,18 +4610,6 @@ "xtend": "~4.0.1" } }, - "node_modules/trim-newlines": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.0.2.tgz", - "integrity": "sha512-GJtWyq9InR/2HRiLZgpIKv+ufIKrVrvjQWEj7PxAXNc5dwbNJkqhAUoAGgzRmULAnoOM5EIpveYd3J2VeSAIew==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -7490,6 +7487,12 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true } } }, @@ -8837,11 +8840,6 @@ } } }, - "trim-newlines": { - "version": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.0.2.tgz", - "integrity": "sha512-GJtWyq9InR/2HRiLZgpIKv+ufIKrVrvjQWEj7PxAXNc5dwbNJkqhAUoAGgzRmULAnoOM5EIpveYd3J2VeSAIew==", - "dev": true - }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", diff --git a/public/dist/scripts/app-all.js b/public/dist/scripts/app-all.js index 10fd74576c..7b438114e7 100644 --- a/public/dist/scripts/app-all.js +++ b/public/dist/scripts/app-all.js @@ -3748,7 +3748,13 @@ let write=formData.get('write');if(write){write=JSON.parse(write);} if(this.getFile(id)){this.updateFile(id,{name:file.name,completed:false,failed:false,cancelled:false,error:"",});}else{this.addFile({id:id,name:file.name,progress:0,completed:false,failed:false,cancelled:false,error:"",});} target.reset();try{const response=await sdk.storage.createFile(bucketId,fileId,file,read,write,(progress)=>{this.updateFile(id,{id:progress.$id,progress:Math.round(progress.progress),error:"",});id=progress.$id;const file=this.getFile(id)??{};if(file.cancelled===true){throw'USER_CANCELLED';}});const existingFile=this.getFile(id)??{};if(existingFile.cancelled){this.updateFile(id,{id:response.$id,name:response.name,failed:false,});id=response.$id;throw'USER_CANCELLED'}else{this.updateFile(id,{id:response.$id,name:response.name,progress:100,completed:true,failed:false,});id=response.$id;} document.dispatchEvent(new CustomEvent('storage.createFile'));}catch(error){if(error==='USER_CANCELLED'){await sdk.storage.deleteFile(bucketId,id);this.updateFile(id,{cancelled:false,failed:true,});this.removeFile(id);}else{this.updateFile(id,{id:id,failed:true,error:error.message??error});} -document.dispatchEvent(new CustomEvent('storage.createFile'));}}});});})(window);(function(window){"use strict";window.ls.view.add({selector:"data-service",controller:function(element,view,container,form,alerts,expression,window){let action=element.dataset["service"];let service=element.dataset["name"]||null;let event=expression.parse(element.dataset["event"]);let confirm=element.dataset["confirm"]||"";let loading=element.dataset["loading"]||"";let loaderId=null;let scope=element.dataset["scope"]||"sdk";let success=element.dataset["success"]||"";let failure=element.dataset["failure"]||"";let running=false;let callbacks={hide:function(){return function(){return element.style.opacity='0';};},reset:function(){return function(){if("FORM"===element.tagName){return element.reset();} +document.dispatchEvent(new CustomEvent('storage.createFile'));}}});});})(window);(function(window){document.addEventListener('alpine:init',()=>{Alpine.data('events',()=>({events:[],selected:null,action:null,type:null,subType:null,resource:null,resourceName:'',subResource:null,subResourceName:'',hasResource:false,hasSubResource:false,attribute:null,hasAttribute:false,attributes:[],setEvent(){this.hasResource=this.hasSubResource=this.hasAttribute=this.action=false;if(!event)return;let[type,action]=this.selected.split('.');switch(type){case'users':if(action==='update'){this.hasAttribute=true;this.attributes=['email','name','password','status','prefs']} +this.hasResource=true;this.type=type;this.resourceName='User ID';break;case'collections':this.hasResource=true;this.type=type;this.resourceName='Collection ID';break;case'teams':this.hasResource=true;this.type=type;this.resourceName='Team ID';break;case'buckets':this.hasResource=true;this.type=type;this.resourceName='Bucket ID';break;case'functions':this.hasResource=true;this.type=type;this.resourceName='Function ID';break;case'sessions':this.hasResource=this.hasSubResource=true;this.type='users';this.subType=type;this.resourceName='User ID';this.subResourceName='Session ID';break;case'verification':this.hasResource=this.hasSubResource=true;this.type='users';this.subType=type;this.resourceName='User ID';this.subResourceName='Verification ID';break;case'recovery':this.hasResource=this.hasSubResource=true;this.type='users';this.subType=type;this.resourceName='User ID';this.subResourceName='Recovery ID';break;case'documents':this.hasResource=this.hasSubResource=true;this.type='collections';this.subType=type;this.resourceName='Collection ID';this.subResourceName='Document ID';break;case'attributes':this.hasResource=this.hasSubResource=true;this.type='collections';this.subType=type;this.resourceName='Collection ID';this.subResourceName='Attribute ID';break;case'indexes':this.hasResource=this.hasSubResource=true;this.type='collections';this.subType=type;this.resourceName='Collection ID';this.subResourceName='Index ID';break;case'files':this.hasResource=this.hasSubResource=true;this.type='buckets';this.subType=type;this.resourceName='Bucket ID';this.subResourceName='File ID';break;case'memberships':if(action==='update'){this.hasAttribute=true;this.attributes=['status']} +this.hasResource=this.hasSubResource=true;this.type='teams';this.subType=type;this.resourceName='Team ID';this.subResourceName='Membership ID';break;case'executions':this.hasResource=this.hasSubResource=true;this.type='functions';this.subType=type;this.resourceName='Function ID';this.subResourceName='Execution ID';break;case'deployments':this.hasResource=this.hasSubResource=true;this.type='functions';this.subType=type;this.resourceName='Function ID';this.subResourceName='Deployment ID';break;default:this.hasResource=true;this.hasSubResource=true;break;} +this.action=action;},addEvent(){let event=`${this.type}.${this.resource ? this.resource : '*'}`;if(this.hasSubResource){event+=`.${this.subType}.${this.subResource ? this.subResource : '*'}`;} +if(this.action){event+=`.${this.action}`;} +if(this.attribute){event+=`.${this.attribute}`;} +this.events.push(event);this.status=[];this.hasResource=this.hasSubResource=this.hasAttribute=false;this.type=this.subType=this.subResource=this.resource=this.attribute=this.selected=this.action=null;},removeEvent(index){this.events.splice(index,1);}}));});})(window);(function(window){"use strict";window.ls.view.add({selector:"data-service",controller:function(element,view,container,form,alerts,expression,window){let action=element.dataset["service"];let service=element.dataset["name"]||null;let event=expression.parse(element.dataset["event"]);let confirm=element.dataset["confirm"]||"";let loading=element.dataset["loading"]||"";let loaderId=null;let scope=element.dataset["scope"]||"sdk";let success=element.dataset["success"]||"";let failure=element.dataset["failure"]||"";let running=false;let callbacks={hide:function(){return function(){return element.style.opacity='0';};},reset:function(){return function(){if("FORM"===element.tagName){return element.reset();} throw new Error("This callback is only valid for forms");};},alert:function(text,classname){return function(alerts){alerts.add({text:text,class:classname||"success"},6000);};},redirect:function(url){return function(router){if(url==="/console"){window.location=url;return;} router.change(url||"/");};},reload:function(){return function(router){router.reload();};},state:function(keys){let updateQueryString=function(key,value,url){var re=new RegExp("([?&])"+key+"=.*?(&|#|$)(.*)","gi"),hash;if(re.test(url)){if(typeof value!=="undefined"&&value!==null){return url.replace(re,"$1"+key+"="+value+"$2$3");}else{hash=url.split("#");url=hash[0].replace(re,"$1$3").replace(/(&|\?)$/,"");if(typeof hash[1]!=="undefined"&&hash[1]!==null){url+="#"+hash[1];} return url;}}else{if(typeof value!=="undefined"&&value!==null){var separator=url.indexOf("?")!==-1?"&":"?";hash=url.split("#");url=hash[0]+separator+key+"="+value;if(typeof hash[1]!=="undefined"&&hash[1]!==null){url+="#"+hash[1];} diff --git a/public/dist/scripts/app.js b/public/dist/scripts/app.js index 7240e243c9..8576a3a617 100644 --- a/public/dist/scripts/app.js +++ b/public/dist/scripts/app.js @@ -695,7 +695,13 @@ let write=formData.get('write');if(write){write=JSON.parse(write);} if(this.getFile(id)){this.updateFile(id,{name:file.name,completed:false,failed:false,cancelled:false,error:"",});}else{this.addFile({id:id,name:file.name,progress:0,completed:false,failed:false,cancelled:false,error:"",});} target.reset();try{const response=await sdk.storage.createFile(bucketId,fileId,file,read,write,(progress)=>{this.updateFile(id,{id:progress.$id,progress:Math.round(progress.progress),error:"",});id=progress.$id;const file=this.getFile(id)??{};if(file.cancelled===true){throw'USER_CANCELLED';}});const existingFile=this.getFile(id)??{};if(existingFile.cancelled){this.updateFile(id,{id:response.$id,name:response.name,failed:false,});id=response.$id;throw'USER_CANCELLED'}else{this.updateFile(id,{id:response.$id,name:response.name,progress:100,completed:true,failed:false,});id=response.$id;} document.dispatchEvent(new CustomEvent('storage.createFile'));}catch(error){if(error==='USER_CANCELLED'){await sdk.storage.deleteFile(bucketId,id);this.updateFile(id,{cancelled:false,failed:true,});this.removeFile(id);}else{this.updateFile(id,{id:id,failed:true,error:error.message??error});} -document.dispatchEvent(new CustomEvent('storage.createFile'));}}});});})(window);(function(window){"use strict";window.ls.view.add({selector:"data-service",controller:function(element,view,container,form,alerts,expression,window){let action=element.dataset["service"];let service=element.dataset["name"]||null;let event=expression.parse(element.dataset["event"]);let confirm=element.dataset["confirm"]||"";let loading=element.dataset["loading"]||"";let loaderId=null;let scope=element.dataset["scope"]||"sdk";let success=element.dataset["success"]||"";let failure=element.dataset["failure"]||"";let running=false;let callbacks={hide:function(){return function(){return element.style.opacity='0';};},reset:function(){return function(){if("FORM"===element.tagName){return element.reset();} +document.dispatchEvent(new CustomEvent('storage.createFile'));}}});});})(window);(function(window){document.addEventListener('alpine:init',()=>{Alpine.data('events',()=>({events:[],selected:null,action:null,type:null,subType:null,resource:null,resourceName:'',subResource:null,subResourceName:'',hasResource:false,hasSubResource:false,attribute:null,hasAttribute:false,attributes:[],setEvent(){this.hasResource=this.hasSubResource=this.hasAttribute=this.action=false;if(!event)return;let[type,action]=this.selected.split('.');switch(type){case'users':if(action==='update'){this.hasAttribute=true;this.attributes=['email','name','password','status','prefs']} +this.hasResource=true;this.type=type;this.resourceName='User ID';break;case'collections':this.hasResource=true;this.type=type;this.resourceName='Collection ID';break;case'teams':this.hasResource=true;this.type=type;this.resourceName='Team ID';break;case'buckets':this.hasResource=true;this.type=type;this.resourceName='Bucket ID';break;case'functions':this.hasResource=true;this.type=type;this.resourceName='Function ID';break;case'sessions':this.hasResource=this.hasSubResource=true;this.type='users';this.subType=type;this.resourceName='User ID';this.subResourceName='Session ID';break;case'verification':this.hasResource=this.hasSubResource=true;this.type='users';this.subType=type;this.resourceName='User ID';this.subResourceName='Verification ID';break;case'recovery':this.hasResource=this.hasSubResource=true;this.type='users';this.subType=type;this.resourceName='User ID';this.subResourceName='Recovery ID';break;case'documents':this.hasResource=this.hasSubResource=true;this.type='collections';this.subType=type;this.resourceName='Collection ID';this.subResourceName='Document ID';break;case'attributes':this.hasResource=this.hasSubResource=true;this.type='collections';this.subType=type;this.resourceName='Collection ID';this.subResourceName='Attribute ID';break;case'indexes':this.hasResource=this.hasSubResource=true;this.type='collections';this.subType=type;this.resourceName='Collection ID';this.subResourceName='Index ID';break;case'files':this.hasResource=this.hasSubResource=true;this.type='buckets';this.subType=type;this.resourceName='Bucket ID';this.subResourceName='File ID';break;case'memberships':if(action==='update'){this.hasAttribute=true;this.attributes=['status']} +this.hasResource=this.hasSubResource=true;this.type='teams';this.subType=type;this.resourceName='Team ID';this.subResourceName='Membership ID';break;case'executions':this.hasResource=this.hasSubResource=true;this.type='functions';this.subType=type;this.resourceName='Function ID';this.subResourceName='Execution ID';break;case'deployments':this.hasResource=this.hasSubResource=true;this.type='functions';this.subType=type;this.resourceName='Function ID';this.subResourceName='Deployment ID';break;default:this.hasResource=true;this.hasSubResource=true;break;} +this.action=action;},addEvent(){let event=`${this.type}.${this.resource ? this.resource : '*'}`;if(this.hasSubResource){event+=`.${this.subType}.${this.subResource ? this.subResource : '*'}`;} +if(this.action){event+=`.${this.action}`;} +if(this.attribute){event+=`.${this.attribute}`;} +this.events.push(event);this.status=[];this.hasResource=this.hasSubResource=this.hasAttribute=false;this.type=this.subType=this.subResource=this.resource=this.attribute=this.selected=this.action=null;},removeEvent(index){this.events.splice(index,1);}}));});})(window);(function(window){"use strict";window.ls.view.add({selector:"data-service",controller:function(element,view,container,form,alerts,expression,window){let action=element.dataset["service"];let service=element.dataset["name"]||null;let event=expression.parse(element.dataset["event"]);let confirm=element.dataset["confirm"]||"";let loading=element.dataset["loading"]||"";let loaderId=null;let scope=element.dataset["scope"]||"sdk";let success=element.dataset["success"]||"";let failure=element.dataset["failure"]||"";let running=false;let callbacks={hide:function(){return function(){return element.style.opacity='0';};},reset:function(){return function(){if("FORM"===element.tagName){return element.reset();} throw new Error("This callback is only valid for forms");};},alert:function(text,classname){return function(alerts){alerts.add({text:text,class:classname||"success"},6000);};},redirect:function(url){return function(router){if(url==="/console"){window.location=url;return;} router.change(url||"/");};},reload:function(){return function(router){router.reload();};},state:function(keys){let updateQueryString=function(key,value,url){var re=new RegExp("([?&])"+key+"=.*?(&|#|$)(.*)","gi"),hash;if(re.test(url)){if(typeof value!=="undefined"&&value!==null){return url.replace(re,"$1"+key+"="+value+"$2$3");}else{hash=url.split("#");url=hash[0].replace(re,"$1$3").replace(/(&|\?)$/,"");if(typeof hash[1]!=="undefined"&&hash[1]!==null){url+="#"+hash[1];} return url;}}else{if(typeof value!=="undefined"&&value!==null){var separator=url.indexOf("?")!==-1?"&":"?";hash=url.split("#");url=hash[0]+separator+key+"="+value;if(typeof hash[1]!=="undefined"&&hash[1]!==null){url+="#"+hash[1];} diff --git a/public/scripts/events.js b/public/scripts/events.js new file mode 100644 index 0000000000..b95a895d32 --- /dev/null +++ b/public/scripts/events.js @@ -0,0 +1,178 @@ +(function (window) { + document.addEventListener('alpine:init', () => { + Alpine.data('events', () => ({ + events: [], + selected: null, + action: null, + type: null, + subType: null, + resource: null, + resourceName: '', + subResource: null, + subResourceName: '', + hasResource: false, + hasSubResource: false, + attribute: null, + hasAttribute: false, + attributes: [], + setEvent() { + this.hasResource = this.hasSubResource = this.hasAttribute = this.action = false; + + if (!event) return; + + let [type, action] = this.selected.split('.'); + + switch (type) { + case 'users': + if (action === 'update') { + this.hasAttribute = true; + this.attributes = ['email', 'name', 'password', 'status', 'prefs'] + } + this.hasResource = true; + this.type = type; + this.resourceName = 'User ID'; + break; + + case 'collections': + this.hasResource = true; + this.type = type; + this.resourceName = 'Collection ID'; + break; + + case 'teams': + this.hasResource = true; + this.type = type; + this.resourceName = 'Team ID'; + break; + + case 'buckets': + this.hasResource = true; + this.type = type; + this.resourceName = 'Bucket ID'; + break; + + case 'functions': + this.hasResource = true; + this.type = type; + this.resourceName = 'Function ID'; + break; + + case 'sessions': + this.hasResource = this.hasSubResource = true; + this.type = 'users'; + this.subType = type; + this.resourceName = 'User ID'; + this.subResourceName = 'Session ID'; + break; + + case 'verification': + this.hasResource = this.hasSubResource = true; + this.type = 'users'; + this.subType = type; + this.resourceName = 'User ID'; + this.subResourceName = 'Verification ID'; + break; + + case 'recovery': + this.hasResource = this.hasSubResource = true; + this.type = 'users'; + this.subType = type; + this.resourceName = 'User ID'; + this.subResourceName = 'Recovery ID'; + break; + + case 'documents': + this.hasResource = this.hasSubResource = true; + this.type = 'collections'; + this.subType = type; + this.resourceName = 'Collection ID'; + this.subResourceName = 'Document ID'; + break; + + case 'attributes': + this.hasResource = this.hasSubResource = true; + this.type = 'collections'; + this.subType = type; + this.resourceName = 'Collection ID'; + this.subResourceName = 'Attribute ID'; + break; + + case 'indexes': + this.hasResource = this.hasSubResource = true; + this.type = 'collections'; + this.subType = type; + this.resourceName = 'Collection ID'; + this.subResourceName = 'Index ID'; + break; + + case 'files': + this.hasResource = this.hasSubResource = true; + this.type = 'buckets'; + this.subType = type; + this.resourceName = 'Bucket ID'; + this.subResourceName = 'File ID'; + break; + + case 'memberships': + if (action === 'update') { + this.hasAttribute = true; + this.attributes = ['status'] + } + this.hasResource = this.hasSubResource = true; + this.type = 'teams'; + this.subType = type; + this.resourceName = 'Team ID'; + this.subResourceName = 'Membership ID'; + break; + + case 'executions': + this.hasResource = this.hasSubResource = true; + this.type = 'functions'; + this.subType = type; + this.resourceName = 'Function ID'; + this.subResourceName = 'Execution ID'; + break; + + case 'deployments': + this.hasResource = this.hasSubResource = true; + this.type = 'functions'; + this.subType = type; + this.resourceName = 'Function ID'; + this.subResourceName = 'Deployment ID'; + break; + + default: + this.hasResource = true; + this.hasSubResource = true; + + break; + } + this.action = action; + }, + addEvent() { + let event = `${this.type}.${this.resource ? this.resource : '*'}`; + + if (this.hasSubResource) { + event += `.${this.subType}.${this.subResource ? this.subResource : '*'}`; + } + + if (this.action) { + event += `.${this.action}`; + } + + if (this.attribute) { + event += `.${this.attribute}`; + } + + this.events.push(event); + + this.status = []; + this.hasResource = this.hasSubResource = this.hasAttribute = false; + this.type = this.subType = this.subResource = this.resource = this.attribute = this.selected = this.action = null; + }, + removeEvent(index) { + this.events.splice(index, 1); + } + })); + }); +})(window); \ No newline at end of file From 73fe35f2022bd478ff5518f9e98a9e39374b3f2c Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Fri, 29 Apr 2022 13:08:22 +0300 Subject: [PATCH 119/242] feat: update Apple OAuth provider --- src/Appwrite/Auth/OAuth2/Apple.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Appwrite/Auth/OAuth2/Apple.php b/src/Appwrite/Auth/OAuth2/Apple.php index de438c9889..7c6436f3cb 100644 --- a/src/Appwrite/Auth/OAuth2/Apple.php +++ b/src/Appwrite/Auth/OAuth2/Apple.php @@ -136,10 +136,7 @@ class Apple extends OAuth2 */ public function getUserEmail(string $accessToken): string { - if (isset($this->claims['email']) && - !empty($this->claims['email']) && - isset($this->claims['email_verified']) && - $this->claims['email_verified'] === 'true') { + if (isset($this->claims['email']) && !empty($this->claims['email'])) { return $this->claims['email']; } @@ -149,12 +146,18 @@ class Apple extends OAuth2 /** * Check if the OAuth email is verified * + * @link https://developer.apple.com/forums/thread/121411 + * * @param $accessToken * * @return bool */ public function isEmailVerified(string $accessToken): bool { + if (isset($this->claims['email_verified']) && $this->claims['email_verified'] === 'true') { + return true; + } + return false; } From a3dcc0759919da9610e00bcd6a5be97345b949f9 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Wed, 4 May 2022 12:54:34 +0200 Subject: [PATCH 120/242] feat(ui): new events --- app/views/console/functions/function.phtml | 73 +++++++++++++++++----- app/views/console/webhooks/index.phtml | 18 +++--- public/dist/scripts/app-all.js | 5 +- public/dist/scripts/app.js | 5 +- public/dist/styles/default-ltr.css | 2 +- public/dist/styles/default-rtl.css | 2 +- public/scripts/events.js | 13 ++-- public/styles/comps/events.less | 16 +++++ public/styles/default.less | 1 + 9 files changed, 101 insertions(+), 34 deletions(-) create mode 100644 public/styles/comps/events.less diff --git a/app/views/console/functions/function.phtml b/app/views/console/functions/function.phtml index 8ea9d2f8a0..5ad830bcd4 100644 --- a/app/views/console/functions/function.phtml +++ b/app/views/console/functions/function.phtml @@ -1,9 +1,29 @@ getParam('fileLimit', 0); $fileLimitHuman = $this->getParam('fileLimitHuman', 0); -$events = array_keys($this->getParam('events', [])); +$events = $this->getParam('events', []); $timeout = $this->getParam('timeout', 900); $usageStatsEnabled = $this->getParam('usageStatsEnabled', true); +$patterns = []; + +foreach ($events as $name => $event) { + foreach ($event as $key => $value) { + if (!\str_starts_with($key, '$')) { + if (!($value['$resource'] ?? false)) { + $patterns[] = "{$name}.{$key}"; + } else { + foreach ($value as $key2 => $value2) { + if (!\str_starts_with($key2, '$')) { + if (!($value2['$resource'] ?? false)) { + $patterns[] = "{$key}.{$key2}"; + } + } + } + } + } + } +} + ?>
getParam('usageStatsEnabled', true);
Max value is escape(number_format($timeout)); ?> seconds (escape((int) ($timeout / 60)); ?> minutes)
-
- -
- $event): ?> -
- -   - +
+ + + +
+ + +
Leave empty for wildcard access
+
+ + +
Leave empty for wildcard access
+
+
+ + +
+
diff --git a/app/views/console/webhooks/index.phtml b/app/views/console/webhooks/index.phtml index 54c9f6e765..6463acf330 100644 --- a/app/views/console/webhooks/index.phtml +++ b/app/views/console/webhooks/index.phtml @@ -1,6 +1,7 @@ getParam('events', []); +$patterns = []; foreach ($events as $name => $event) { foreach ($event as $key => $value) { @@ -83,22 +84,21 @@ foreach ($events as $name => $event) {
-
@@ -229,10 +229,10 @@ foreach ($events as $name => $event) {