1 | <?php |
||||
2 | |||||
3 | declare(strict_types=1); |
||||
4 | |||||
5 | namespace AbterPhp\Admin\Http\Middleware; |
||||
6 | |||||
7 | use AbterPhp\Admin\Config\Routes as RoutesConfig; |
||||
8 | use Closure; |
||||
9 | use Opulence\Framework\Configuration\Config; |
||||
10 | use Opulence\Framework\Http\CsrfTokenChecker; |
||||
11 | use Opulence\Http\InvalidCsrfTokenException; |
||||
12 | use Opulence\Http\Requests\Request; |
||||
13 | use Opulence\Http\Responses\Cookie; |
||||
14 | use Opulence\Http\Responses\Response; |
||||
15 | use Opulence\Routing\Middleware\IMiddleware; |
||||
16 | use Opulence\Sessions\ISession; |
||||
17 | |||||
18 | /** |
||||
19 | * Defines the middleware that checks the CSRF token |
||||
20 | */ |
||||
21 | class CheckCsrfToken implements IMiddleware |
||||
22 | { |
||||
23 | /** @var CsrfTokenChecker The CSRF token checker */ |
||||
24 | protected CsrfTokenChecker $csrfTokenChecker; |
||||
25 | |||||
26 | /** @var ISession The current session */ |
||||
27 | protected ISession $session; |
||||
28 | |||||
29 | private RoutesConfig $routesConfig; |
||||
30 | |||||
31 | /** |
||||
32 | * @param CsrfTokenChecker $csrfTokenChecker The CSRF token checker |
||||
33 | * @param ISession $session The current session |
||||
34 | * @param RoutesConfig $routesConfig |
||||
35 | */ |
||||
36 | public function __construct(CsrfTokenChecker $csrfTokenChecker, ISession $session, RoutesConfig $routesConfig) |
||||
37 | { |
||||
38 | $this->csrfTokenChecker = $csrfTokenChecker; |
||||
39 | $this->session = $session; |
||||
40 | |||||
41 | $this->routesConfig = $routesConfig; |
||||
42 | } |
||||
43 | |||||
44 | /** |
||||
45 | * @inheritdoc |
||||
46 | * @throws InvalidCsrfTokenException Thrown if the CSRF token is invalid |
||||
47 | */ |
||||
48 | public function handle(Request $request, Closure $next): Response |
||||
49 | { |
||||
50 | if ($this->isApiRequest($request)) { |
||||
51 | return $next($request); |
||||
52 | } |
||||
53 | |||||
54 | if (!$this->csrfTokenChecker->tokenIsValid($request, $this->session)) { |
||||
55 | throw new InvalidCsrfTokenException('Invalid CSRF token'); |
||||
56 | } |
||||
57 | |||||
58 | return $this->writeToResponse($next($request)); |
||||
59 | } |
||||
60 | |||||
61 | /** |
||||
62 | * @param Request $request |
||||
63 | * |
||||
64 | * @return bool |
||||
65 | */ |
||||
66 | protected function isApiRequest(Request $request): bool |
||||
67 | { |
||||
68 | $apiBasePath = $this->routesConfig->getApiBasePath(); |
||||
69 | |||||
70 | $path = $request->getPath(); |
||||
71 | |||||
72 | return substr($path, 0, strlen($apiBasePath)) === $apiBasePath; |
||||
73 | } |
||||
74 | |||||
75 | /** |
||||
76 | * @SuppressWarnings(PHPMD.StaticAccess) |
||||
77 | * |
||||
78 | * Writes data to the response |
||||
79 | * |
||||
80 | * @param Response $response The response to write to |
||||
81 | * |
||||
82 | * @return Response The response with the data written to it |
||||
83 | */ |
||||
84 | protected function writeToResponse(Response $response): Response |
||||
85 | { |
||||
86 | $sessionValue = $this->session->get(CsrfTokenChecker::TOKEN_INPUT_NAME); |
||||
87 | |||||
88 | $lifetime = Config::get('sessions', 'xsrfcookie.lifetime'); |
||||
89 | $expiration = time() + $lifetime; |
||||
90 | |||||
91 | $path = Config::get('sessions', 'cookie.path'); |
||||
92 | $domain = Config::get('sessions', 'cookie.domain'); |
||||
93 | $isSecure = Config::get('sessions', 'cookie.isSecure'); |
||||
94 | |||||
95 | // Add an XSRF cookie for JavaScript frameworks to use |
||||
96 | $response->getHeaders()->setCookie( |
||||
97 | new Cookie( |
||||
98 | 'XSRF-TOKEN', |
||||
99 | $sessionValue, |
||||
100 | $expiration, |
||||
101 | $path, |
||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||
102 | $domain, |
||||
0 ignored issues
–
show
It seems like
$domain can also be of type null ; however, parameter $domain of Opulence\Http\Responses\Cookie::__construct() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
103 | $isSecure, |
||||
0 ignored issues
–
show
It seems like
$isSecure can also be of type null ; however, parameter $isSecure of Opulence\Http\Responses\Cookie::__construct() does only seem to accept boolean , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
104 | false |
||||
105 | ) |
||||
106 | ); |
||||
107 | |||||
108 | return $response; |
||||
109 | } |
||||
110 | } |
||||
111 |