diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index 6bc11bbd255..1820407c7ce 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -3949,6 +3949,14 @@ function drupal_setcookie($name, $value, $options) { setcookie($name, $value, $options); } else { + $defaults = array( + 'expires' => 0, + 'path' => '', + 'domain' => '', + 'secure' => FALSE, + 'httponly' => FALSE, + ); + $options += $defaults; setcookie($name, $value, $options['expires'], $options['path'], $options['domain'], $options['secure'], $options['httponly']); } } diff --git a/misc/tabledrag.js b/misc/tabledrag.js index 836568f529e..24ccc1476ce 100644 --- a/misc/tabledrag.js +++ b/misc/tabledrag.js @@ -165,7 +165,8 @@ Drupal.tableDrag.prototype.initColumns = function () { // Set a cookie if it is not already present. if ($.cookie('Drupal.tableDrag.showWeight') === null) { $.cookie('Drupal.tableDrag.showWeight', 0, { - path: Drupal.settings.basePath, + // Workaround lack of support for the SameSite attribute in jQuery Cookie. + path: Drupal.settings.basePath + '; SameSite=Lax', // The cookie expires in one year. expires: 365 }); @@ -197,9 +198,9 @@ Drupal.tableDrag.prototype.hideColumns = function () { }); // Change link text. $('.tabledrag-toggle-weight').text(Drupal.t('Show row weights')); - // Change cookie. + // Change cookie (including workaround for SameSite attribute). $.cookie('Drupal.tableDrag.showWeight', 0, { - path: Drupal.settings.basePath, + path: Drupal.settings.basePath + '; SameSite=Lax', // The cookie expires in one year. expires: 365 }); @@ -222,9 +223,9 @@ Drupal.tableDrag.prototype.showColumns = function () { }); // Change link text. $('.tabledrag-toggle-weight').text(Drupal.t('Hide row weights')); - // Change cookie. + // Change cookie (including workaround for SameSite attribute). $.cookie('Drupal.tableDrag.showWeight', 1, { - path: Drupal.settings.basePath, + path: Drupal.settings.basePath + '; SameSite=Lax', // The cookie expires in one year. expires: 365 }); diff --git a/modules/toolbar/toolbar.info b/modules/toolbar/toolbar.info index 2c5abbb2e25..e9bee47904e 100644 --- a/modules/toolbar/toolbar.info +++ b/modules/toolbar/toolbar.info @@ -3,3 +3,4 @@ description = Provides a toolbar that shows the top-level administration menu it core = 7.x package = Core version = VERSION +files[] = toolbar.test diff --git a/modules/toolbar/toolbar.js b/modules/toolbar/toolbar.js index d50f20566e4..63289454510 100644 --- a/modules/toolbar/toolbar.js +++ b/modules/toolbar/toolbar.js @@ -52,7 +52,8 @@ Drupal.toolbar.collapse = function() { 'Drupal.toolbar.collapsed', 1, { - path: Drupal.settings.basePath, + // Workaround lack of support for the SameSite attribute in jQuery Cookie. + path: Drupal.settings.basePath + '; SameSite=Lax', // The cookie should "never" expire. expires: 36500 } @@ -74,7 +75,8 @@ Drupal.toolbar.expand = function() { 'Drupal.toolbar.collapsed', 0, { - path: Drupal.settings.basePath, + // Workaround lack of support for the SameSite attribute in jQuery Cookie. + path: Drupal.settings.basePath + '; SameSite=Lax', // The cookie should "never" expire. expires: 36500 } diff --git a/modules/toolbar/toolbar.module b/modules/toolbar/toolbar.module index 070dd52c21d..7097263390e 100644 --- a/modules/toolbar/toolbar.module +++ b/modules/toolbar/toolbar.module @@ -70,7 +70,12 @@ function toolbar_menu() { function toolbar_toggle_page() { global $base_path; // Toggle the value in the cookie. - setcookie('Drupal.toolbar.collapsed', !_toolbar_is_collapsed(), NULL, $base_path); + drupal_setcookie('Drupal.toolbar.collapsed', !_toolbar_is_collapsed(), + array( + 'samesite' => 'Lax', + 'path' => $base_path, + ) + ); // Redirect the user from where he used the toggle element. drupal_goto(); } diff --git a/modules/toolbar/toolbar.test b/modules/toolbar/toolbar.test new file mode 100644 index 00000000000..b4daa9151f0 --- /dev/null +++ b/modules/toolbar/toolbar.test @@ -0,0 +1,42 @@ + 'Toolbar', + 'description' => 'Test toolbar functionality.', + 'group' => 'Toolbar (core)', + ); + } + + function setUp() { + parent::setUp(); + + // Setup users. + $this->admin_user = $this->drupalCreateUser(array('access toolbar')); + $this->drupalLogin($this->admin_user); + } + + /** + * Tests toggling the toolbar collapsed cookie. + */ + function testToolbarCollapsedCookie() { + $this->drupalGet('toolbar/toggle'); + $set_cookie = $this->drupalGetHeader('set-cookie', TRUE); + $this->assertTrue((strpos('Drupal.toolbar.collapsed=1; path=/; SameSite=Lax', $set_cookie) !== FALSE), 'Toolbar cookie set to collapsed by default.'); + + // The next request should toggle the toolbar.collapsed cookie to off. + $this->drupalGet('toolbar/toggle'); + $set_cookie = $this->drupalGetHeader('set-cookie', TRUE); + $this->assertTrue((bool) preg_match('#Drupal.toolbar.collapsed=deleted; expires=Thu, 01.Jan.1970 00:00:01 GMT;( Max-Age=0;)? path=\/; SameSite=Lax#', $set_cookie), 'Toolbar cookie toggled to off (deleted).'); + + // The next request should toggle the toolbar.collapsed cookie back to 1. + $this->drupalGet('toolbar/toggle'); + $set_cookie = $this->drupalGetHeader('set-cookie', TRUE); + $this->assertTrue((strpos('Drupal.toolbar.collapsed=1; path=/; SameSite=Lax', $set_cookie) !== FALSE), 'Toolbar cookie toggled to 1.'); + } + +}