WyriHaximus /
reactphp-http-middleware-session
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php declare(strict_types=1); |
||
| 2 | |||
| 3 | namespace WyriHaximus\React\Http\Middleware; |
||
| 4 | |||
| 5 | use HansOtt\PSR7Cookies\RequestCookies; |
||
| 6 | use HansOtt\PSR7Cookies\SetCookie; |
||
| 7 | use Psr\Http\Message\ResponseInterface; |
||
| 8 | use Psr\Http\Message\ServerRequestInterface; |
||
| 9 | use React\Cache\CacheInterface; |
||
| 10 | use React\Promise\PromiseInterface; |
||
| 11 | use function React\Promise\resolve; |
||
| 12 | use Throwable; |
||
| 13 | use WyriHaximus\React\Http\Middleware\SessionId\RandomBytes; |
||
| 14 | |||
| 15 | final class SessionMiddleware |
||
| 16 | { |
||
| 17 | const ATTRIBUTE_NAME = 'wyrihaximus.react.http.middleware.session'; |
||
| 18 | |||
| 19 | const DEFAULT_COOKIE_PARAMS = [ |
||
| 20 | 0, |
||
| 21 | '', |
||
| 22 | '', |
||
| 23 | false, |
||
| 24 | false, |
||
| 25 | ]; |
||
| 26 | |||
| 27 | /** |
||
| 28 | * @var string |
||
| 29 | */ |
||
| 30 | private $cookieName; |
||
| 31 | |||
| 32 | /** |
||
| 33 | * @var CacheInterface |
||
| 34 | */ |
||
| 35 | private $cache; |
||
| 36 | |||
| 37 | /** |
||
| 38 | * @var array |
||
| 39 | */ |
||
| 40 | private $cookieParams = []; |
||
| 41 | |||
| 42 | /** |
||
| 43 | * @var SessionIdInterface |
||
| 44 | */ |
||
| 45 | private $sessionId; |
||
| 46 | |||
| 47 | /** |
||
| 48 | * @param string $cookieName |
||
| 49 | * @param CacheInterface $cache |
||
| 50 | * @param array $cookieParams |
||
| 51 | * @param SessionIdInterface|null $sessionId |
||
| 52 | */ |
||
| 53 | 19 | public function __construct( |
|
| 54 | string $cookieName, |
||
| 55 | CacheInterface $cache, |
||
| 56 | array $cookieParams = [], |
||
| 57 | ?SessionIdInterface $sessionId = null |
||
| 58 | ) { |
||
| 59 | 19 | $this->cookieName = $cookieName; |
|
| 60 | 19 | $this->cache = $cache; |
|
| 61 | 19 | $this->cookieParams = \array_replace(self::DEFAULT_COOKIE_PARAMS, $cookieParams) ?? []; |
|
| 62 | |||
| 63 | 19 | if ($sessionId === null) { |
|
| 64 | 19 | $sessionId = new RandomBytes(); |
|
| 65 | } |
||
| 66 | 19 | $this->sessionId = $sessionId; |
|
| 67 | 19 | } |
|
| 68 | |||
| 69 | /** |
||
| 70 | * @param ServerRequestInterface $request |
||
| 71 | * @param callable $next |
||
| 72 | * @return PromiseInterface |
||
| 73 | */ |
||
| 74 | 19 | public function __invoke(ServerRequestInterface $request, callable $next) |
|
| 75 | { |
||
| 76 | return $this->fetchSessionFromRequest($request)->then(function (Session $session) use ($next, $request) { |
||
| 77 | 18 | $request = $request->withAttribute(self::ATTRIBUTE_NAME, $session); |
|
|
0 ignored issues
–
show
|
|||
| 78 | |||
| 79 | 18 | return resolve( |
|
| 80 | 18 | $next($request) |
|
| 81 | )->then(function (ResponseInterface $response) use ($session) { |
||
| 82 | return $this->updateCache($session)->then(function () use ($response) { |
||
| 83 | 18 | return $response; |
|
| 84 | 18 | }); |
|
| 85 | })->then(function ($response) use ($session) { |
||
| 86 | 18 | $cookie = $this->getCookie($session); |
|
| 87 | 18 | $response = $cookie->addToResponse($response); |
|
| 88 | |||
| 89 | 18 | return $response; |
|
| 90 | 18 | }); |
|
| 91 | 19 | }); |
|
| 92 | } |
||
| 93 | |||
| 94 | 19 | private function fetchSessionFromRequest(ServerRequestInterface $request): PromiseInterface |
|
| 95 | { |
||
| 96 | 19 | $id = ''; |
|
| 97 | 19 | $cookies = RequestCookies::createFromRequest($request); |
|
| 98 | |||
| 99 | try { |
||
| 100 | 19 | if (!$cookies->has($this->cookieName)) { |
|
| 101 | 11 | return resolve(new Session($id, [], $this->sessionId)); |
|
| 102 | } |
||
| 103 | 8 | $id = $cookies->get($this->cookieName)->getValue(); |
|
| 104 | |||
| 105 | return $this->fetchSessionDataFromCache($id)->then(function (array $sessionData) use ($id) { |
||
| 106 | 6 | return new Session($id, $sessionData, $this->sessionId); |
|
| 107 | 7 | }); |
|
| 108 | 1 | } catch (Throwable $et) { |
|
| 109 | // Do nothing, only a not found will be thrown so generating our own id now |
||
| 110 | } |
||
| 111 | |||
| 112 | 1 | return resolve(new Session($id, [], $this->sessionId)); |
|
| 113 | } |
||
| 114 | |||
| 115 | 8 | private function fetchSessionDataFromCache(string $id): PromiseInterface |
|
| 116 | { |
||
| 117 | 8 | if ($id === '') { |
|
| 118 | return resolve([]); |
||
| 119 | } |
||
| 120 | |||
| 121 | return $this->cache->get($id)->then(function ($result) { |
||
| 122 | 6 | if ($result === null) { |
|
| 123 | 5 | return resolve([]); |
|
| 124 | } |
||
| 125 | |||
| 126 | 1 | return $result; |
|
| 127 | 7 | }); |
|
| 128 | } |
||
| 129 | |||
| 130 | 18 | private function updateCache(Session $session): PromiseInterface |
|
| 131 | { |
||
| 132 | 18 | foreach ($session->getOldIds() as $oldId) { |
|
| 133 | 2 | $this->cache->delete($oldId); |
|
| 134 | } |
||
| 135 | |||
| 136 | 18 | if ($session->isActive()) { |
|
| 137 | 16 | return resolve($this->cache->set($session->getId(), $session->getContents())); |
|
| 138 | } |
||
| 139 | |||
| 140 | 2 | return resolve(); |
|
| 141 | } |
||
| 142 | |||
| 143 | 18 | private function getCookie(Session $session): SetCookie |
|
| 144 | { |
||
| 145 | 18 | $cookieParams = $this->cookieParams; |
|
| 146 | |||
| 147 | 18 | if ($session->isActive()) { |
|
| 148 | // Only set time when expires is set in the future |
||
| 149 | 16 | if ($cookieParams[0] > 0) { |
|
| 150 | 11 | $cookieParams[0] += \time(); |
|
| 151 | } |
||
| 152 | |||
| 153 | 16 | return new SetCookie($this->cookieName, $session->getId(), ...$cookieParams); |
|
|
0 ignored issues
–
show
$cookieParams is of type array, but the function expects a integer.
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
| 154 | } |
||
| 155 | 2 | unset($cookieParams[0]); |
|
| 156 | |||
| 157 | 2 | return SetCookie::thatDeletesCookie($this->cookieName, ...$cookieParams); |
|
|
0 ignored issues
–
show
$cookieParams is of type array, but the function expects a string.
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
| 158 | } |
||
| 159 | } |
||
| 160 |
It seems like you are assigning to a variable which was imported through a
usestatement which was not imported by reference.For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.
Change not visible in outer-scope
Change visible in outer-scope