1
0
mirror of https://github.com/typemill/typemill.git synced 2025-07-30 02:40:42 +02:00

Add separate cors header middleware to all api endpoints

This commit is contained in:
trendschau
2023-12-30 20:53:51 +01:00
parent fb3f5f4673
commit c3517fde58
5 changed files with 135 additions and 46 deletions

View File

@@ -0,0 +1,62 @@
<?php
namespace Typemill\Middleware;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Psr7\Response;
class CorsHeadersMiddleware implements MiddlewareInterface
{
protected $settings;
protected $urlinfo;
public function __construct($settings, $urlinfo)
{
$this->settings = $settings;
$this->urlinfo = $urlinfo;
}
public function process(Request $request, RequestHandler $handler) :response
{
# add the custom headers to the response after everything is processed
$response = $handler->handle($request);
###################
# CORS HEADER #
###################
$origin = $request->getHeaderLine('Origin');
$corsdomains = isset($this->settings['corsdomains']) ? trim($this->settings['corsdomains']) : false;
$whitelist = [];
if($corsdomains && $corsdomains != '')
{
$corsdomains = explode(",", $corsdomains);
foreach($corsdomains as $domain)
{
$domain = trim($domain);
if($domain != '')
{
$whitelist[] = $domain;
}
}
}
if(!$origin OR $origin == '' OR !isset($whitelist[$origin]))
{
# set current website as default origin and block all cross origin calls
$origin = $this->urlinfo['baseurl'];
}
$response = $response->withHeader('Access-Control-Allow-Origin', $origin)
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS')
->withHeader('Access-Control-Allow-Credentials', 'true');
return $response;
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace Typemill\Middleware;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Psr7\Response;
class CspHeadersMiddleware implements MiddlewareInterface
{
protected $settings;
protected $urlinfo;
public function __construct($settings, $urlinfo)
{
$this->settings = $settings;
$this->urlinfo = $urlinfo;
}
public function process(Request $request, RequestHandler $handler) :response
{
$scheme = $request->getUri()->getScheme();
# add the custom headers to the response after everything is processed
$response = $handler->handle($request);
###################
# CSP HEADER #
###################
$cspdomains = isset($this->settings['cspdomains']) ? trim($this->settings['cspdomains']) : false;
$defaultsrc = "default-src 'unsafe-inline' 'unsafe-eval' 'self'";
if($cspdomains && $cspdomains != '')
{
$cspdomains = explode(",", $cspdomains);
foreach($cspdomains as $cspdomain)
{
$cspdomain = trim($cspdomain);
if($cspdomain != '')
{
$defaultsrc .= ' ' . $cspdomain;
}
}
}
# dispatch to get from plugins
# get yaml from current theme
# Define the Content Security Policy header
$cspHeader = $defaultsrc . ";"; // Default source is restricted to 'self'
# $cspHeader .= "frame-src 'self' https://www.youtube.com;"; // Allowing embedding YouTube videos
# $cspHeader .= "img-src *";
# $cspHeader .= "media-src *";
# $cspHeader .= "script-src *";
# $cspHeader .= "style-src *";
# $cspHeader .= "object-src 'none'";
# Add the Content Security Policy header to the response
$response = $response->withHeader('Content-Security-Policy', $cspHeader);
return $response;
}
}

View File

@@ -10,14 +10,10 @@ use Slim\Psr7\Response;
class CustomHeadersMiddleware implements MiddlewareInterface
{
protected $settings;
protected $urlinfo;
public function __construct($settings, $urlinfo)
public function __construct($settings)
{
$this->settings = $settings;
$this->urlinfo = $urlinfo;
}
public function process(Request $request, RequestHandler $handler) :response
@@ -32,11 +28,6 @@ class CustomHeadersMiddleware implements MiddlewareInterface
$headersOff = $this->settings['headersoff'] ?? false;
###################
# SECURITY HEADER #
###################
if(!$headersOff)
{
$response = $response
@@ -51,38 +42,6 @@ class CustomHeadersMiddleware implements MiddlewareInterface
}
}
###################
# CORS HEADER #
###################
$origin = $request->getHeaderLine('Origin');
$corsdomains = isset($this->settings['corsdomains']) ? trim($this->settings['corsdomains']) : false;
$whitelist = [];
if($corsdomains && $corsdomains != '')
{
$corsdomains = explode(",", $corsdomains);
foreach($corsdomains as $domain)
{
$domain = trim($domain);
if($domain != '')
{
$whitelist[] = $domain;
}
}
}
if(!$origin OR $origin == '' OR !isset($whitelist[$origin]))
{
# set current website as default origin and block all cross origin calls
$origin = $this->urlinfo['baseurl'];
}
$response = $response->withHeader('Access-Control-Allow-Origin', $origin)
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS')
->withHeader('Access-Control-Allow-Credentials', 'true');
return $response;
}
}

View File

@@ -3,6 +3,7 @@
use Slim\Routing\RouteCollectorProxy;
use Typemill\Middleware\ApiAuthentication;
use Typemill\Middleware\ApiAuthorization;
use Typemill\Middleware\CorsHeadersMiddleware;
use Typemill\Controllers\ControllerApiGlobals;
use Typemill\Controllers\ControllerApiMedia;
use Typemill\Controllers\ControllerApiSystemSettings;
@@ -85,7 +86,7 @@ $app->group('/api/v1', function (RouteCollectorProxy $group) use ($acl) {
$group->get('/meta', ControllerApiAuthorMeta::class . ':getMeta')->setName('api.meta.get')->add(new ApiAuthorization($acl, 'mycontent', 'view'));
$group->post('/meta', ControllerApiAuthorMeta::class . ':updateMeta')->setName('api.metadata.update')->add(new ApiAuthorization($acl, 'mycontent', 'update'));
})->add(new ApiAuthentication());
})->add(new CorsHeadersMiddleware($settings, $urlinfo))->add(new ApiAuthentication());
# api-routes from plugins
if(isset($routes['api']) && !empty($routes['api']))
@@ -102,12 +103,12 @@ if(isset($routes['api']) && !empty($routes['api']))
if($resources && $privilege)
{
# protected api requires authentication and authorization
$app->{$method}($route, $class)->setName($name)->add(new ApiAuthorization($acl, $resource, $privilege))->add(new ApiAuthentication());
$app->{$method}($route, $class)->setName($name)->add(new ApiAuthorization($acl, $resource, $privilege))->add(new CorsHeadersMiddleware($settings, $urlinfo))->add(new ApiAuthentication());
}
else
{
# public api routes
$app->{$method}($route, $class)->setName($name);
$app->{$method}($route, $class)->setName($name)->add(new CorsHeadersMiddleware($settings, $urlinfo));
}
}
}

View File

@@ -323,7 +323,7 @@ foreach($middleware as $pluginMiddleware)
}
}
$app->add(new CustomHeadersMiddleware($settings, $urlinfo));
$app->add(new CustomHeadersMiddleware($settings));
$app->add(new AssetMiddleware($assets, $container->get('view')));