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