Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
SecurityHeadersMiddleware
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
2 / 2
4
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 process
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3declare(strict_types=1);
4
5namespace BO\Zmscitizenapi\Middleware;
6
7use BO\Zmscitizenapi\Localization\ErrorMessages;
8use BO\Zmscitizenapi\Services\Core\LoggerService;
9use Psr\Http\Message\ResponseInterface;
10use Psr\Http\Message\ServerRequestInterface;
11use Psr\Http\Server\MiddlewareInterface;
12use Psr\Http\Server\RequestHandlerInterface;
13
14class SecurityHeadersMiddleware implements MiddlewareInterface
15{
16    private const ERROR_SECURITY_VIOLATION = 'securityHeaderViolation';
17    private array $securityHeaders = [
18        'X-Frame-Options' => 'DENY',
19        'X-Content-Type-Options' => 'nosniff',
20        'X-XSS-Protection' => '1; mode=block',
21        'Strict-Transport-Security' => 'max-age=31536000; includeSubDomains',
22        'Content-Security-Policy' => "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; connect-src 'self'",
23        'Referrer-Policy' => 'strict-origin-when-cross-origin',
24        'Permissions-Policy' => 'geolocation=(), microphone=(), camera=()',
25        'X-Permitted-Cross-Domain-Policies' => 'none'
26    ];
27    private LoggerService $logger;
28    public function __construct(LoggerService $logger)
29    {
30        $this->logger = $logger;
31    }
32
33    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
34    {
35        try {
36            $response = $handler->handle($request);
37            foreach ($this->securityHeaders as $header => $value) {
38                $response = $response->withHeader($header, $value);
39            }
40
41            /*$this->logger->logInfo('Security headers added', [
42                'uri' => (string)$request->getUri()
43            ]);*/
44
45            return $response;
46        } catch (\Throwable $e) {
47            $this->logger->logError($e, $request);
48            $response = \App::$slim->getResponseFactory()->createResponse();
49            $language = $request->getAttribute('language');
50            $response = $response->withStatus(ErrorMessages::get('securityHeaderViolation', $language)['statusCode'])
51                ->withHeader('Content-Type', 'application/json');
52            $response->getBody()->write(json_encode([
53                'errors' => [ErrorMessages::get('securityHeaderViolation', $language)]
54            ]));
55            return $response;
56        }
57    }
58}