Skip to content

Commit

Permalink
keep previous cookies
Browse files Browse the repository at this point in the history
we recently fixed that we lose previous cookies. but the fix was keeping
the messages in the session and only setting the cookie on the last
redirect, which means the messages are lost if the session is destroyed
(e.g. redirect to page outside firewall)

changed to merge the flash messages cookie from requests into the
flashes. and using array_merge_recursive to keep multiple messages with
the same key.
  • Loading branch information
dbu committed Jan 26, 2021
1 parent 5df759a commit bd61d62
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 18 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
Changelog
=========

2.9.2
-----

### Fixed

* 2.9.1 fixed overwriting flash messages on multiple redirects, but introduced
a risk to lose flash messages when redirecting to a path that is outside the
firewall or destroys the session.
This version hopefully fixes both cases. Existing flash messages in a request
cookie are merged with new flash messages from the session.

2.9.1
-----

Expand Down
20 changes: 11 additions & 9 deletions src/EventListener/FlashMessageListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,26 +87,28 @@ public function onKernelResponse(FlashMessageResponseEvent $event)
return;
}

$response = $event->getResponse();

// If the response is a redirect, we should wait until the final response
// is reached
if ($response->isRedirect()) {
return;
}

$flashBag = $this->session->getFlashBag();
$flashes = $flashBag->all();

if (empty($flashes)) {
return;
}

$response = $event->getResponse();

$cookies = $response->headers->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
$host = (null === $this->options['host']) ? '' : $this->options['host'];
if (isset($cookies[$host][$this->options['path']][$this->options['name']])) {
$rawCookie = $cookies[$host][$this->options['path']][$this->options['name']]->getValue();
$flashes = array_merge($flashes, json_decode($rawCookie));
$flashes = array_merge_recursive($flashes, json_decode($rawCookie, true));
}

// Preserve existing flash message cookie from previous redirect if there was one.
// This covers multiple redirects where each redirect adds flash messages.
$request = $event->getRequest();
if ($request->cookies->has($this->options['name'])) {
$rawCookie = $request->cookies->get($this->options['name']);
$flashes = array_merge_recursive($flashes, json_decode($rawCookie, true));
}

$cookie = new Cookie(
Expand Down
11 changes: 2 additions & 9 deletions tests/Functional/EventListener/FlashMessageListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\HttpFoundation\Cookie;

class FlashMessageListenerTest extends WebTestCase
{
Expand All @@ -33,7 +32,6 @@ public function testFlashMessageCookieIsSet()

$found = false;
foreach ($cookies as $cookie) {
/** @var Cookie $cookie */
if ('flash_cookie_name' !== $cookie->getName()) {
continue;
}
Expand All @@ -45,9 +43,7 @@ public function testFlashMessageCookieIsSet()
$found = true;
}

if (!$found) {
$this->fail('Cookie flash_cookie_name not found in the cookie response header: '.implode(',', $cookies));
}
$this->assertTrue($found, 'Cookie "flash_cookie_name" not found in response cookies');
}

public function testFlashMessageCookieIsSetOnRedirect()
Expand All @@ -65,7 +61,6 @@ public function testFlashMessageCookieIsSetOnRedirect()

$found = false;
foreach ($cookies as $cookie) {
/** @var Cookie $cookie */
if ('flash_cookie_name' !== $cookie->getName()) {
continue;
}
Expand All @@ -77,8 +72,6 @@ public function testFlashMessageCookieIsSetOnRedirect()
$found = true;
}

if (!$found) {
$this->fail('Cookie flash_cookie_name not found in the cookie response header: '.implode(',', $cookies));
}
$this->assertTrue($found, 'Cookie "flash_cookie_name" not found in response cookies');
}
}

0 comments on commit bd61d62

Please sign in to comment.