From 16e05ce819b72a9f477b841da9816a6ea4be345d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20L=C3=BCcke?= Date: Mon, 12 Apr 2021 15:56:35 +0200 Subject: [PATCH 1/9] =?UTF-8?q?Die=20API-Tests=20wurden=20um=20eine=20Pref?= =?UTF-8?q?light-=C3=9Cberpr=C3=BCfung=20erweitert,=20um=20CORS-Probleme?= =?UTF-8?q?=20zu=20vermindern.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/.env.example | 5 ++++- api/tests/_support/Helper/Api.php | 2 ++ api/tests/api/Views/BrowseWorkingHoursMonthlyCest.php | 2 ++ api/tests/api/Views/BrowseWorkingHoursWeeklyCest.php | 2 ++ api/tests/api/Views/BrowseWorkingHoursYearlyCest.php | 2 ++ api/tests/api/WorkingHours/BrowseWorkingHoursCest.php | 2 ++ api/tests/api/WorkingHours/CreateWorkingHoursCest.php | 6 ++++++ api/tests/api/WorkingHours/ReadWorkingHoursCest.php | 4 ++++ api/tests/api/WorkingHours/UpdateWorkingHoursCest.php | 6 ++++++ 9 files changed, 30 insertions(+), 1 deletion(-) diff --git a/api/.env.example b/api/.env.example index dbd9974..ccf54d0 100644 --- a/api/.env.example +++ b/api/.env.example @@ -2,4 +2,7 @@ DATABASES_HOST=psql.domain.tld DATABASES_NAME=db DATABASES_USER=user -DATABASES_PASS=1234 \ No newline at end of file +DATABASES_PASS=1234 + +## CORS Einstellungen +CORS_ALLOW_ORIGIN=localhost:* \ No newline at end of file diff --git a/api/tests/_support/Helper/Api.php b/api/tests/_support/Helper/Api.php index 3656476..0cc4f73 100644 --- a/api/tests/_support/Helper/Api.php +++ b/api/tests/_support/Helper/Api.php @@ -32,4 +32,6 @@ class Api extends Module "message" => "string", "path" => "string", ]; + + const TEST_ORIGIN = 'localhost:1234'; } diff --git a/api/tests/api/Views/BrowseWorkingHoursMonthlyCest.php b/api/tests/api/Views/BrowseWorkingHoursMonthlyCest.php index 5614233..178b85d 100644 --- a/api/tests/api/Views/BrowseWorkingHoursMonthlyCest.php +++ b/api/tests/api/Views/BrowseWorkingHoursMonthlyCest.php @@ -13,8 +13,10 @@ class BrowseWorkingHoursMonthlyCest */ public function browseWorkingHoursView(ApiTester $I): void { + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); $I->sendGet('/views/working-hours/monthly'); $I->seeResponseCodeIs(HttpCode::OK); + $I->canSeeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); $I->seeResponseIsJson(); $I->seeResponseMatchesJsonType(Api::WORKING_HOURS_VIEW_JSON_FORMAT); } diff --git a/api/tests/api/Views/BrowseWorkingHoursWeeklyCest.php b/api/tests/api/Views/BrowseWorkingHoursWeeklyCest.php index 6a751c5..8c00e5c 100644 --- a/api/tests/api/Views/BrowseWorkingHoursWeeklyCest.php +++ b/api/tests/api/Views/BrowseWorkingHoursWeeklyCest.php @@ -13,8 +13,10 @@ class BrowseWorkingHoursWeeklyCest */ public function browseWorkingHoursView(ApiTester $I): void { + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); $I->sendGet('/views/working-hours/weekly'); $I->seeResponseCodeIs(HttpCode::OK); + $I->canSeeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); $I->seeResponseIsJson(); $I->seeResponseMatchesJsonType(Api::WORKING_HOURS_VIEW_JSON_FORMAT); } diff --git a/api/tests/api/Views/BrowseWorkingHoursYearlyCest.php b/api/tests/api/Views/BrowseWorkingHoursYearlyCest.php index 4a4c0c1..96b8dd1 100644 --- a/api/tests/api/Views/BrowseWorkingHoursYearlyCest.php +++ b/api/tests/api/Views/BrowseWorkingHoursYearlyCest.php @@ -13,8 +13,10 @@ class BrowseWorkingHoursYearlyCest */ public function browseWorkingHoursView(ApiTester $I): void { + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); $I->sendGet('/views/working-hours/yearly'); $I->seeResponseCodeIs(HttpCode::OK); + $I->canSeeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); $I->seeResponseIsJson(); $I->seeResponseMatchesJsonType(Api::WORKING_HOURS_VIEW_JSON_FORMAT); } diff --git a/api/tests/api/WorkingHours/BrowseWorkingHoursCest.php b/api/tests/api/WorkingHours/BrowseWorkingHoursCest.php index bcfff03..e3d2895 100644 --- a/api/tests/api/WorkingHours/BrowseWorkingHoursCest.php +++ b/api/tests/api/WorkingHours/BrowseWorkingHoursCest.php @@ -13,8 +13,10 @@ class BrowseWorkingHoursCest */ public function browseWorkingHours(ApiTester $I): void { + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); $I->sendGet('/working-hours'); $I->seeResponseCodeIs(HttpCode::OK); + $I->canSeeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); $I->seeResponseIsJson(); $I->seeResponseMatchesJsonType(Api::WORKING_HOURS_JSON_FORMAT); } diff --git a/api/tests/api/WorkingHours/CreateWorkingHoursCest.php b/api/tests/api/WorkingHours/CreateWorkingHoursCest.php index 725b895..803952c 100644 --- a/api/tests/api/WorkingHours/CreateWorkingHoursCest.php +++ b/api/tests/api/WorkingHours/CreateWorkingHoursCest.php @@ -12,11 +12,13 @@ class CreateWorkingHoursCest { $I->haveHttpHeader('accept', 'application/json'); $I->haveHttpHeader('content-type', 'application/json'); + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); $I->sendPost('/working-hours', [ 'workingDay' => '2020-04-01', 'workingTime' => '08:00:00', ]); $I->seeResponseCodeIs(HttpCode::CREATED); + $I->canSeeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); $I->seeResponseIsJson(); $I->seeResponseMatchesJsonType(Api::WORKING_HOURS_JSON_FORMAT); } @@ -26,11 +28,13 @@ class CreateWorkingHoursCest { $I->haveHttpHeader('accept', 'application/json'); $I->haveHttpHeader('content-type', 'application/json'); + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); $I->sendPost('/working-hours', [ 'workingDay' => '2020-04-01', 'workingTime' => 8.0, ]); $I->seeResponseCodeIs(HttpCode::BAD_REQUEST); + $I->canSeeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); $I->seeResponseIsJson(); $I->seeResponseMatchesJsonType(Api::ERROR_JSON_FORMAT); } @@ -40,11 +44,13 @@ class CreateWorkingHoursCest { $I->haveHttpHeader('accept', 'application/json'); $I->haveHttpHeader('content-type', 'application/json'); + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); $I->sendPost('/working-hours', [ 'workingDay' => '2020-01-15', 'workingTime' => '08:00:00', ]); $I->seeResponseCodeIs(HttpCode::CONFLICT); + $I->canSeeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); $I->seeResponseIsJson(); $I->seeResponseMatchesJsonType(Api::ERROR_JSON_FORMAT); } diff --git a/api/tests/api/WorkingHours/ReadWorkingHoursCest.php b/api/tests/api/WorkingHours/ReadWorkingHoursCest.php index af212be..1f47db1 100644 --- a/api/tests/api/WorkingHours/ReadWorkingHoursCest.php +++ b/api/tests/api/WorkingHours/ReadWorkingHoursCest.php @@ -10,16 +10,20 @@ class ReadWorkingHoursCest { public function readExistingWorkingHours(ApiTester $I): void { + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); $I->sendGet('/working-hours/2020-01-15'); $I->seeResponseCodeIs(HttpCode::OK); + $I->canSeeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); $I->seeResponseIsJson(); $I->seeResponseMatchesJsonType(Api::WORKING_HOURS_JSON_FORMAT); } public function readNotExistingWorkingHours(ApiTester $I): void { + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); $I->sendGet('/working-hours/2020-04-15'); $I->seeResponseCodeIs(HttpCode::NOT_FOUND); + $I->canSeeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); $I->seeResponseIsJson(); $I->seeResponseMatchesJsonType(Api::ERROR_JSON_FORMAT); } diff --git a/api/tests/api/WorkingHours/UpdateWorkingHoursCest.php b/api/tests/api/WorkingHours/UpdateWorkingHoursCest.php index a4e433b..cfa27e1 100644 --- a/api/tests/api/WorkingHours/UpdateWorkingHoursCest.php +++ b/api/tests/api/WorkingHours/UpdateWorkingHoursCest.php @@ -12,11 +12,13 @@ class UpdateWorkingHoursCest { $I->haveHttpHeader('accept', 'application/json'); $I->haveHttpHeader('content-type', 'application/json'); + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); $I->sendPut('/working-hours/2020-01-15', [ 'workingDay' => '2020-01-15', 'workingTime' => '10:00:00', ]); $I->seeResponseCodeIs(HttpCode::OK); + $I->canSeeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); $I->seeResponseIsJson(); $I->seeResponseMatchesJsonType(Api::WORKING_HOURS_JSON_FORMAT); } @@ -25,11 +27,13 @@ class UpdateWorkingHoursCest { $I->haveHttpHeader('accept', 'application/json'); $I->haveHttpHeader('content-type', 'application/json'); + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); $I->sendPut('/working-hours/2020-04-15', [ 'workingDay' => '2020-04-15', 'workingTime' => '10:00:00', ]); $I->seeResponseCodeIs(HttpCode::NOT_FOUND); + $I->canSeeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); $I->seeResponseIsJson(); $I->seeResponseMatchesJsonType(Api::ERROR_JSON_FORMAT); } @@ -38,11 +42,13 @@ class UpdateWorkingHoursCest { $I->haveHttpHeader('accept', 'application/json'); $I->haveHttpHeader('content-type', 'application/json'); + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); $I->sendPut('/working-hours/2020-01-15', [ 'workingDay' => '2020-01-15', 'workingTime' => 8.0, ]); $I->seeResponseCodeIs(HttpCode::BAD_REQUEST); + $I->canSeeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); $I->seeResponseIsJson(); $I->seeResponseMatchesJsonType(Api::ERROR_JSON_FORMAT); } From edcb80421bbdc6d9c9516e00a4c558432300f871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20L=C3=BCcke?= Date: Mon, 12 Apr 2021 18:26:12 +0200 Subject: [PATCH 2/9] Der Browser sendet auch das Protokoll mit. --- api/tests/_support/Helper/Api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/tests/_support/Helper/Api.php b/api/tests/_support/Helper/Api.php index 0cc4f73..677c203 100644 --- a/api/tests/_support/Helper/Api.php +++ b/api/tests/_support/Helper/Api.php @@ -33,5 +33,5 @@ class Api extends Module "path" => "string", ]; - const TEST_ORIGIN = 'localhost:1234'; + const TEST_ORIGIN = 'http://localhost:1234'; } From 8ee9666250b712b1e2b01eb289605c27d50aae6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20L=C3=BCcke?= Date: Mon, 12 Apr 2021 18:26:57 +0200 Subject: [PATCH 3/9] Die Tests wurden um die Preflight-Tests erweitert. --- api/tests/api/Views/BrowseWorkingHoursMonthlyCest.php | 8 ++++++++ api/tests/api/Views/BrowseWorkingHoursWeeklyCest.php | 8 ++++++++ api/tests/api/Views/BrowseWorkingHoursYearlyCest.php | 8 ++++++++ api/tests/api/WorkingHours/BrowseWorkingHoursCest.php | 8 ++++++++ api/tests/api/WorkingHours/CreateWorkingHoursCest.php | 8 ++++++++ api/tests/api/WorkingHours/ReadWorkingHoursCest.php | 8 ++++++++ api/tests/api/WorkingHours/UpdateWorkingHoursCest.php | 8 ++++++++ 7 files changed, 56 insertions(+) diff --git a/api/tests/api/Views/BrowseWorkingHoursMonthlyCest.php b/api/tests/api/Views/BrowseWorkingHoursMonthlyCest.php index 178b85d..2ba0d98 100644 --- a/api/tests/api/Views/BrowseWorkingHoursMonthlyCest.php +++ b/api/tests/api/Views/BrowseWorkingHoursMonthlyCest.php @@ -8,6 +8,14 @@ use Helper\Api; class BrowseWorkingHoursMonthlyCest { + public static function preflight(ApiTester $I): void + { + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); + $I->haveHttpHeader('Access-Control-Request-Method', 'GET'); + $I->sendOptions('/views/working-hours/monthly'); + $I->seeResponseCodeIs(HttpCode::OK); + } + /** * @param ApiTester $I */ diff --git a/api/tests/api/Views/BrowseWorkingHoursWeeklyCest.php b/api/tests/api/Views/BrowseWorkingHoursWeeklyCest.php index 8c00e5c..d3dace9 100644 --- a/api/tests/api/Views/BrowseWorkingHoursWeeklyCest.php +++ b/api/tests/api/Views/BrowseWorkingHoursWeeklyCest.php @@ -8,6 +8,14 @@ use Helper\Api; class BrowseWorkingHoursWeeklyCest { + public static function preflight(ApiTester $I): void + { + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); + $I->haveHttpHeader('Access-Control-Request-Method', 'GET'); + $I->sendOptions('/views/working-hours/weekly'); + $I->seeResponseCodeIs(HttpCode::OK); + } + /** * @param ApiTester $I */ diff --git a/api/tests/api/Views/BrowseWorkingHoursYearlyCest.php b/api/tests/api/Views/BrowseWorkingHoursYearlyCest.php index 96b8dd1..45d0b49 100644 --- a/api/tests/api/Views/BrowseWorkingHoursYearlyCest.php +++ b/api/tests/api/Views/BrowseWorkingHoursYearlyCest.php @@ -8,6 +8,14 @@ use Helper\Api; class BrowseWorkingHoursYearlyCest { + public static function preflight(ApiTester $I): void + { + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); + $I->haveHttpHeader('Access-Control-Request-Method', 'GET'); + $I->sendOptions('/views/working-hours/yearly'); + $I->seeResponseCodeIs(HttpCode::OK); + } + /** * @param ApiTester $I */ diff --git a/api/tests/api/WorkingHours/BrowseWorkingHoursCest.php b/api/tests/api/WorkingHours/BrowseWorkingHoursCest.php index e3d2895..0cd7872 100644 --- a/api/tests/api/WorkingHours/BrowseWorkingHoursCest.php +++ b/api/tests/api/WorkingHours/BrowseWorkingHoursCest.php @@ -8,6 +8,14 @@ use Helper\Api; class BrowseWorkingHoursCest { + public static function preflight(ApiTester $I): void + { + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); + $I->haveHttpHeader('Access-Control-Request-Method', 'GET'); + $I->sendOptions('/working-hours'); + $I->seeResponseCodeIs(HttpCode::OK); + } + /** * @param ApiTester $I */ diff --git a/api/tests/api/WorkingHours/CreateWorkingHoursCest.php b/api/tests/api/WorkingHours/CreateWorkingHoursCest.php index 803952c..79e0819 100644 --- a/api/tests/api/WorkingHours/CreateWorkingHoursCest.php +++ b/api/tests/api/WorkingHours/CreateWorkingHoursCest.php @@ -8,6 +8,14 @@ use Helper\Api; class CreateWorkingHoursCest { + public static function preflight(ApiTester $I): void + { + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); + $I->haveHttpHeader('Access-Control-Request-Method', 'POST'); + $I->sendOptions('/working-hours'); + $I->seeResponseCodeIs(HttpCode::OK); + } + public function createWorkingHoursWithNewValidRecord(ApiTester $I): void { $I->haveHttpHeader('accept', 'application/json'); diff --git a/api/tests/api/WorkingHours/ReadWorkingHoursCest.php b/api/tests/api/WorkingHours/ReadWorkingHoursCest.php index 1f47db1..1d95243 100644 --- a/api/tests/api/WorkingHours/ReadWorkingHoursCest.php +++ b/api/tests/api/WorkingHours/ReadWorkingHoursCest.php @@ -8,6 +8,14 @@ use Helper\Api; class ReadWorkingHoursCest { + public static function preflight(ApiTester $I): void + { + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); + $I->haveHttpHeader('Access-Control-Request-Method', 'GET'); + $I->sendOptions('/working-hours/2020-04-15'); + $I->seeResponseCodeIs(HttpCode::OK); + } + public function readExistingWorkingHours(ApiTester $I): void { $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); diff --git a/api/tests/api/WorkingHours/UpdateWorkingHoursCest.php b/api/tests/api/WorkingHours/UpdateWorkingHoursCest.php index cfa27e1..c6cc08c 100644 --- a/api/tests/api/WorkingHours/UpdateWorkingHoursCest.php +++ b/api/tests/api/WorkingHours/UpdateWorkingHoursCest.php @@ -8,6 +8,14 @@ use Helper\Api; class UpdateWorkingHoursCest { + public static function preflight(ApiTester $I): void + { + $I->haveHttpHeader('Origin', Api::TEST_ORIGIN); + $I->haveHttpHeader('Access-Control-Request-Method', 'PUT'); + $I->sendOptions('/working-hours/2020-01-15'); + $I->seeResponseCodeIs(HttpCode::OK); + } + public function updateWorkingHoursWithExistingValidRecord(ApiTester $I): void { $I->haveHttpHeader('accept', 'application/json'); From e29a6dcab9262262991b0cd732f9a32aacf6a1ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20L=C3=BCcke?= Date: Mon, 12 Apr 2021 18:45:16 +0200 Subject: [PATCH 4/9] =?UTF-8?q?Der=20Regex=20ist=20nun=20vollst=C3=A4ndig.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/.env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/.env.example b/api/.env.example index ccf54d0..10a3d48 100644 --- a/api/.env.example +++ b/api/.env.example @@ -5,4 +5,4 @@ DATABASES_USER=user DATABASES_PASS=1234 ## CORS Einstellungen -CORS_ALLOW_ORIGIN=localhost:* \ No newline at end of file +CORS_ALLOW_ORIGIN_REGEX=/https?:\/\/localhost:\d+/ \ No newline at end of file From b5af0c5a5489ac329b305c1d165973978f6cb97d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20L=C3=BCcke?= Date: Mon, 12 Apr 2021 18:46:37 +0200 Subject: [PATCH 5/9] =?UTF-8?q?Vorbereitung=20f=C3=BCr=20Preflight-=20und?= =?UTF-8?q?=20CORS-Abfragen.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/src/Controller/PreflightController.php | 18 ++++++ api/src/Middleware/ErrorHandler.php | 4 +- .../Middleware/OriginAccessControlHandler.php | 60 +++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 api/src/Controller/PreflightController.php create mode 100644 api/src/Middleware/OriginAccessControlHandler.php diff --git a/api/src/Controller/PreflightController.php b/api/src/Controller/PreflightController.php new file mode 100644 index 0000000..1ac6bf9 --- /dev/null +++ b/api/src/Controller/PreflightController.php @@ -0,0 +1,18 @@ +originAccessControl($request, $response); + } +} \ No newline at end of file diff --git a/api/src/Middleware/ErrorHandler.php b/api/src/Middleware/ErrorHandler.php index 9693206..80d5f15 100644 --- a/api/src/Middleware/ErrorHandler.php +++ b/api/src/Middleware/ErrorHandler.php @@ -84,7 +84,9 @@ class ErrorHandler json_encode($payload, JSON_UNESCAPED_UNICODE) ); - return $response; + $originAccessControlHandler = new OriginAccessControlHandler(); + + return $originAccessControlHandler->originAccessControl($request, $response); } } \ No newline at end of file diff --git a/api/src/Middleware/OriginAccessControlHandler.php b/api/src/Middleware/OriginAccessControlHandler.php new file mode 100644 index 0000000..d29d7f0 --- /dev/null +++ b/api/src/Middleware/OriginAccessControlHandler.php @@ -0,0 +1,60 @@ +handle($request); + + + return $this->originAccessControl($request, $response); + } + + public function originAccessControl(Request $request, Response $response): Response + { + + $routeContext = RouteContext::fromRequest($request); + $routingResults = $routeContext->getRoutingResults(); + $methods = $routingResults->getAllowedMethods(); + $requestHeaders = $request->getHeaderLine('Access-Control-Request-Headers'); + + if ($this->testRoute($request)) { + $response = $response->withHeader('Access-Control-Allow-Origin', $this->buildOrigin($request)); + $response = $response->withHeader('Access-Control-Allow-Methods', implode(',', $methods)); + $response = $response->withHeader('Access-Control-Allow-Headers', $requestHeaders); + + // Optional: Allow Ajax CORS requests with Authorization header + $response = $response->withHeader('Access-Control-Allow-Credentials', 'true'); + } + return $response; + } + + protected function testRoute(Request $request): bool + { + $corsAllowOriginRegex = $_ENV['CORS_ALLOW_ORIGIN_REGEX'] ?? '/https?:\/\/.*:.*/'; + return preg_match($corsAllowOriginRegex, $this->buildOrigin($request)); + } + + protected function buildOrigin(Request $request): string + { + return $request->getHeaderLine('Origin') ?? ''; + } +} \ No newline at end of file From 3fe73f3b10f8c17bab4c16d47489ad93fbf4acb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20L=C3=BCcke?= Date: Mon, 12 Apr 2021 18:47:48 +0200 Subject: [PATCH 6/9] Preflight- und CORS-Abfragen werden verarbeitet. --- api/html/index.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/api/html/index.php b/api/html/index.php index d9a872c..cbd9aca 100644 --- a/api/html/index.php +++ b/api/html/index.php @@ -7,10 +7,12 @@ $dotenv->load(); use DI\Container; use Slim\Factory\AppFactory; use Slim\Routing\RouteCollectorProxy; +use TorstenHettstedt\TimekeepingApi\Controller\PreflightController; use TorstenHettstedt\TimekeepingApi\Controller\WorkingHoursController; use TorstenHettstedt\TimekeepingApi\Controller\WorkingHoursViewController; use TorstenHettstedt\TimekeepingApi\Middleware\ErrorHandler; use TorstenHettstedt\TimekeepingApi\Middleware\JsonBodyParserMiddleware; +use TorstenHettstedt\TimekeepingApi\Middleware\OriginAccessControlHandler; $container = new Container(); @@ -22,17 +24,25 @@ $container->set('databases', function () { AppFactory::setContainer($container); $app = AppFactory::create(); $app->add(new JsonBodyParserMiddleware()); +$app->addBodyParsingMiddleware(); +$app->add(new OriginAccessControlHandler()); +$app->addRoutingMiddleware(); $app->group('/views/working-hours', function (RouteCollectorProxy $group) { + $group->options('/weekly', PreflightController::class . ':preflight'); $group->get('/weekly', WorkingHoursViewController::class . ':browseWeekly'); + $group->options('/monthly', PreflightController::class . ':preflight'); $group->get('/monthly', WorkingHoursViewController::class . ':browseMonthly'); + $group->options('/yearly', PreflightController::class . ':preflight'); $group->get('/yearly', WorkingHoursViewController::class . ':browseYearly'); }); $app->group('/working-hours', function (RouteCollectorProxy $group) { + $group->options('', PreflightController::class . ':preflight'); $group->get('', WorkingHoursController::class . ':browse'); $group->post('', WorkingHoursController::class . ':creat'); $group->group('/{id:\d\d\d\d-\d\d-\d\d}', function (RouteCollectorProxy $group) { + $group->options('', PreflightController::class . ':preflight'); $group->get('', WorkingHoursController::class . ':read'); $group->put('', WorkingHoursController::class . ':update'); }); From 8d00e0c1042ffa38c11db84eeeed9c0ed714fcef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20L=C3=BCcke?= Date: Tue, 13 Apr 2021 12:29:27 +0200 Subject: [PATCH 7/9] zu viele Zeilen --- api/src/Middleware/OriginAccessControlHandler.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/api/src/Middleware/OriginAccessControlHandler.php b/api/src/Middleware/OriginAccessControlHandler.php index d29d7f0..215a019 100644 --- a/api/src/Middleware/OriginAccessControlHandler.php +++ b/api/src/Middleware/OriginAccessControlHandler.php @@ -23,8 +23,6 @@ class OriginAccessControlHandler implements MiddlewareInterface public function process(Request $request, RequestHandler $handler): Response { $response = $handler->handle($request); - - return $this->originAccessControl($request, $response); } From 87f3bb3f0e4310e468f329040f61cc0f53d243c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20L=C3=BCcke?= Date: Tue, 13 Apr 2021 12:34:25 +0200 Subject: [PATCH 8/9] Es sollte auf die notwendigen Header geachtet werden (https://developer.mozilla.org/de/docs/Web/HTTP/CORS) --- api/tests/api/Views/BrowseWorkingHoursMonthlyCest.php | 4 ++++ api/tests/api/Views/BrowseWorkingHoursWeeklyCest.php | 4 ++++ api/tests/api/Views/BrowseWorkingHoursYearlyCest.php | 4 ++++ api/tests/api/WorkingHours/BrowseWorkingHoursCest.php | 4 ++++ api/tests/api/WorkingHours/CreateWorkingHoursCest.php | 4 ++++ api/tests/api/WorkingHours/ReadWorkingHoursCest.php | 4 ++++ api/tests/api/WorkingHours/UpdateWorkingHoursCest.php | 4 ++++ 7 files changed, 28 insertions(+) diff --git a/api/tests/api/Views/BrowseWorkingHoursMonthlyCest.php b/api/tests/api/Views/BrowseWorkingHoursMonthlyCest.php index 2ba0d98..4208663 100644 --- a/api/tests/api/Views/BrowseWorkingHoursMonthlyCest.php +++ b/api/tests/api/Views/BrowseWorkingHoursMonthlyCest.php @@ -14,6 +14,10 @@ class BrowseWorkingHoursMonthlyCest $I->haveHttpHeader('Access-Control-Request-Method', 'GET'); $I->sendOptions('/views/working-hours/monthly'); $I->seeResponseCodeIs(HttpCode::OK); + $I->seeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); + $I->seeHttpHeader('Access-Control-Allow-Methods'); + $I->seeHttpHeader('Access-Control-Allow-Headers'); + $I->seeHttpHeader('Access-Control-Max-Age'); } /** diff --git a/api/tests/api/Views/BrowseWorkingHoursWeeklyCest.php b/api/tests/api/Views/BrowseWorkingHoursWeeklyCest.php index d3dace9..2ba0c72 100644 --- a/api/tests/api/Views/BrowseWorkingHoursWeeklyCest.php +++ b/api/tests/api/Views/BrowseWorkingHoursWeeklyCest.php @@ -14,6 +14,10 @@ class BrowseWorkingHoursWeeklyCest $I->haveHttpHeader('Access-Control-Request-Method', 'GET'); $I->sendOptions('/views/working-hours/weekly'); $I->seeResponseCodeIs(HttpCode::OK); + $I->seeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); + $I->seeHttpHeader('Access-Control-Allow-Methods'); + $I->seeHttpHeader('Access-Control-Allow-Headers'); + $I->seeHttpHeader('Access-Control-Max-Age'); } /** diff --git a/api/tests/api/Views/BrowseWorkingHoursYearlyCest.php b/api/tests/api/Views/BrowseWorkingHoursYearlyCest.php index 45d0b49..c42bfaa 100644 --- a/api/tests/api/Views/BrowseWorkingHoursYearlyCest.php +++ b/api/tests/api/Views/BrowseWorkingHoursYearlyCest.php @@ -14,6 +14,10 @@ class BrowseWorkingHoursYearlyCest $I->haveHttpHeader('Access-Control-Request-Method', 'GET'); $I->sendOptions('/views/working-hours/yearly'); $I->seeResponseCodeIs(HttpCode::OK); + $I->seeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); + $I->seeHttpHeader('Access-Control-Allow-Methods'); + $I->seeHttpHeader('Access-Control-Allow-Headers'); + $I->seeHttpHeader('Access-Control-Max-Age'); } /** diff --git a/api/tests/api/WorkingHours/BrowseWorkingHoursCest.php b/api/tests/api/WorkingHours/BrowseWorkingHoursCest.php index 0cd7872..65a5d1b 100644 --- a/api/tests/api/WorkingHours/BrowseWorkingHoursCest.php +++ b/api/tests/api/WorkingHours/BrowseWorkingHoursCest.php @@ -14,6 +14,10 @@ class BrowseWorkingHoursCest $I->haveHttpHeader('Access-Control-Request-Method', 'GET'); $I->sendOptions('/working-hours'); $I->seeResponseCodeIs(HttpCode::OK); + $I->seeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); + $I->seeHttpHeader('Access-Control-Allow-Methods'); + $I->seeHttpHeader('Access-Control-Allow-Headers'); + $I->seeHttpHeader('Access-Control-Max-Age'); } /** diff --git a/api/tests/api/WorkingHours/CreateWorkingHoursCest.php b/api/tests/api/WorkingHours/CreateWorkingHoursCest.php index 79e0819..c2707bc 100644 --- a/api/tests/api/WorkingHours/CreateWorkingHoursCest.php +++ b/api/tests/api/WorkingHours/CreateWorkingHoursCest.php @@ -14,6 +14,10 @@ class CreateWorkingHoursCest $I->haveHttpHeader('Access-Control-Request-Method', 'POST'); $I->sendOptions('/working-hours'); $I->seeResponseCodeIs(HttpCode::OK); + $I->seeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); + $I->seeHttpHeader('Access-Control-Allow-Methods'); + $I->seeHttpHeader('Access-Control-Allow-Headers'); + $I->seeHttpHeader('Access-Control-Max-Age'); } public function createWorkingHoursWithNewValidRecord(ApiTester $I): void diff --git a/api/tests/api/WorkingHours/ReadWorkingHoursCest.php b/api/tests/api/WorkingHours/ReadWorkingHoursCest.php index 1d95243..2f2eafb 100644 --- a/api/tests/api/WorkingHours/ReadWorkingHoursCest.php +++ b/api/tests/api/WorkingHours/ReadWorkingHoursCest.php @@ -14,6 +14,10 @@ class ReadWorkingHoursCest $I->haveHttpHeader('Access-Control-Request-Method', 'GET'); $I->sendOptions('/working-hours/2020-04-15'); $I->seeResponseCodeIs(HttpCode::OK); + $I->seeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); + $I->seeHttpHeader('Access-Control-Allow-Methods'); + $I->seeHttpHeader('Access-Control-Allow-Headers'); + $I->seeHttpHeader('Access-Control-Max-Age'); } public function readExistingWorkingHours(ApiTester $I): void diff --git a/api/tests/api/WorkingHours/UpdateWorkingHoursCest.php b/api/tests/api/WorkingHours/UpdateWorkingHoursCest.php index c6cc08c..176eb88 100644 --- a/api/tests/api/WorkingHours/UpdateWorkingHoursCest.php +++ b/api/tests/api/WorkingHours/UpdateWorkingHoursCest.php @@ -14,6 +14,10 @@ class UpdateWorkingHoursCest $I->haveHttpHeader('Access-Control-Request-Method', 'PUT'); $I->sendOptions('/working-hours/2020-01-15'); $I->seeResponseCodeIs(HttpCode::OK); + $I->seeHttpHeader('Access-Control-Allow-Origin', Api::TEST_ORIGIN); + $I->seeHttpHeader('Access-Control-Allow-Methods'); + $I->seeHttpHeader('Access-Control-Allow-Headers'); + $I->seeHttpHeader('Access-Control-Max-Age'); } public function updateWorkingHoursWithExistingValidRecord(ApiTester $I): void From 6203f98e93fa8df9dbf9d614f2d991cebbd0b3de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20L=C3=BCcke?= Date: Tue, 13 Apr 2021 12:43:31 +0200 Subject: [PATCH 9/9] Alle notwendigen Header werden mitgeliefert. --- api/src/Middleware/OriginAccessControlHandler.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/src/Middleware/OriginAccessControlHandler.php b/api/src/Middleware/OriginAccessControlHandler.php index 215a019..a62de79 100644 --- a/api/src/Middleware/OriginAccessControlHandler.php +++ b/api/src/Middleware/OriginAccessControlHandler.php @@ -35,12 +35,12 @@ class OriginAccessControlHandler implements MiddlewareInterface $requestHeaders = $request->getHeaderLine('Access-Control-Request-Headers'); if ($this->testRoute($request)) { + // Stunden Minuten Sekunden + $accessControlMaxAge = 24 * 60 * 60; $response = $response->withHeader('Access-Control-Allow-Origin', $this->buildOrigin($request)); $response = $response->withHeader('Access-Control-Allow-Methods', implode(',', $methods)); $response = $response->withHeader('Access-Control-Allow-Headers', $requestHeaders); - - // Optional: Allow Ajax CORS requests with Authorization header - $response = $response->withHeader('Access-Control-Allow-Credentials', 'true'); + $response = $response->withHeader('Access-Control-Max-Age', (string)$accessControlMaxAge); } return $response; }