diff options
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rw-r--r-- | cpanfile | 2 | ||||
-rw-r--r-- | cpanfile.snapshot | 24 | ||||
-rw-r--r-- | perllib/FixMyStreet/App.pm | 1 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Around.pm | 2 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Engine.pm | 68 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Response.pm | 2 | ||||
-rw-r--r-- | t/app/controller/around.t | 21 | ||||
-rw-r--r-- | t/app/engine.t | 9 | ||||
-rw-r--r-- | web/cobrands/fixmystreet/fixmystreet.js | 6 | ||||
-rw-r--r-- | web/js/lazyload.js | 2 |
11 files changed, 119 insertions, 22 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 271728446..82c86bffd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,11 @@ ## Releases * Unreleased + - Front end improvements: + - Include "SameSite=Lax" with all cookies. - Bugfixes: + - Fix bug specifying category in URL on /around. #1950 + - Fix bug with multiple select-multiples on a page. #1951 - Make sure dashboard filters all fit onto one line. - Fix issue with red bars on bar graph of many categories. - Prefetch translations in /reports list of bodies. @@ -13,6 +13,7 @@ requires 'PadWalker', '2.2'; requires 'aliased', '0.34'; requires 'Net::SSLeay', '1.81'; requires 'Module::ScanDeps', '1.24'; +requires 'CGI', '4.38'; # Catalyst itself, and modules/plugins used requires 'Catalyst', '5.80031'; @@ -32,7 +33,6 @@ requires 'Catalyst::View::TT'; requires 'Authen::SASL'; requires 'Cache::Memcached'; requires 'Carp'; -requires 'CGI'; requires 'Crypt::Eksblowfish::Bcrypt'; requires 'DateTime'; requires 'DateTime::Format::HTTP'; diff --git a/cpanfile.snapshot b/cpanfile.snapshot index 5bc776606..c5e5b2a46 100644 --- a/cpanfile.snapshot +++ b/cpanfile.snapshot @@ -75,19 +75,19 @@ DISTRIBUTIONS perl 5.008001 strict 0 warnings 0 - CGI-4.28 - pathname: L/LE/LEEJO/CGI-4.28.tar.gz + CGI-4.38 + pathname: L/LE/LEEJO/CGI-4.38.tar.gz provides: - CGI 4.28 - CGI::Carp 4.28 - CGI::Cookie 4.28 - CGI::File::Temp 4.28 + CGI 4.38 + CGI::Carp 4.38 + CGI::Cookie 4.38 + CGI::File::Temp 4.38 CGI::HTML::Functions undef - CGI::Pretty 4.28 - CGI::Push 4.28 - CGI::Util 4.28 - Fh 4.28 - MultipartBuffer 4.28 + CGI::MultipartBuffer 4.38 + CGI::Pretty 4.38 + CGI::Push 4.38 + CGI::Util 4.38 + Fh 4.38 requirements: Carp 0 Config 0 @@ -95,7 +95,7 @@ DISTRIBUTIONS Exporter 0 ExtUtils::MakeMaker 0 File::Spec 0.82 - File::Temp 0 + File::Temp 0.17 HTML::Entities 3.69 base 0 if 0 diff --git a/perllib/FixMyStreet/App.pm b/perllib/FixMyStreet/App.pm index e47336b7c..390300093 100644 --- a/perllib/FixMyStreet/App.pm +++ b/perllib/FixMyStreet/App.pm @@ -98,6 +98,7 @@ __PACKAGE__->config( ); __PACKAGE__->response_class('FixMyStreet::App::Response'); +__PACKAGE__->engine_class('FixMyStreet::App::Engine'); # Start the application __PACKAGE__->setup(); diff --git a/perllib/FixMyStreet/App/Controller/Around.pm b/perllib/FixMyStreet/App/Controller/Around.pm index 7cef7ccaa..e4932ecd5 100644 --- a/perllib/FixMyStreet/App/Controller/Around.pm +++ b/perllib/FixMyStreet/App/Controller/Around.pm @@ -240,7 +240,7 @@ sub check_and_stash_category : Private { )->all; my @categories = map { { name => $_->category, value => $_->category_display } } @contacts; $c->stash->{filter_categories} = \@categories; - my %categories_mapped = map { $_ => 1 } @categories; + my %categories_mapped = map { $_->{name} => 1 } @categories; my $categories = [ $c->get_param_list('filter_category', 1) ]; my %valid_categories = map { $_ => 1 } grep { $_ && $categories_mapped{$_} } @$categories; diff --git a/perllib/FixMyStreet/App/Engine.pm b/perllib/FixMyStreet/App/Engine.pm new file mode 100644 index 000000000..b73701f49 --- /dev/null +++ b/perllib/FixMyStreet/App/Engine.pm @@ -0,0 +1,68 @@ +package FixMyStreet::App::Engine; + +use Moose; +extends 'Catalyst::Engine'; + +use CGI::Cookie; +use utf8; + +use namespace::clean -except => 'meta'; + +=head1 NAME + +FixMyStreet::App::Engine - Catalyst Engine wrapper + +=head1 SYNOPSIS + +See L<Catalyst::Engine>. + +=head1 METHODS + +=head2 $self->finalize_cookies($c) + +Create CGI::Cookie objects from C<< $c->res->cookies >>, and set them as +response headers. Adds a C<samesite=lax> part. + +=cut + +sub finalize_cookies { + my ( $self, $c ) = @_; + + my @cookies; + my $response = $c->response; + + foreach my $name (keys %{ $response->cookies }) { + + my $val = $response->cookies->{$name}; + + my $cookie = ( + blessed($val) + ? $val + : CGI::Cookie->new( + -name => $name, + -value => $val->{value}, + -expires => $val->{expires}, + -domain => $val->{domain}, + -path => $val->{path}, + -secure => $val->{secure} || 0, + -httponly => $val->{httponly} || 0, + -samesite => 'Lax', + ) + ); + if (!defined $cookie) { + $c->log->warn("undef passed in '$name' cookie value - not setting cookie") + if $c->debug; + next; + } + + push @cookies, $cookie->as_string; + } + + for my $cookie (@cookies) { + $response->headers->push_header( 'Set-Cookie' => $cookie ); + } +} + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/perllib/FixMyStreet/App/Response.pm b/perllib/FixMyStreet/App/Response.pm index 16ebf995f..6b32e6ebb 100644 --- a/perllib/FixMyStreet/App/Response.pm +++ b/perllib/FixMyStreet/App/Response.pm @@ -13,7 +13,7 @@ around 'redirect' => sub { return $self->$orig() unless @_; # getter my $agent = $self->_context->request->user_agent; - return $self->$orig(@_) unless $agent =~ /Edge\/14/; # Only care about Edge + return $self->$orig(@_) unless $agent && $agent =~ /Edge\/14/; # Only care about Edge # Instead of a redirect, output HTML that redirects $self->body(<<END diff --git a/t/app/controller/around.t b/t/app/controller/around.t index d1254edb7..618998513 100644 --- a/t/app/controller/around.t +++ b/t/app/controller/around.t @@ -137,25 +137,28 @@ subtest 'check non public reports are not displayed on around page' => sub { }; -subtest 'check category and status filtering works on /around?ajax' => sub { +subtest 'check category and status filtering works on /around' => sub { + my $body = $mech->create_body_ok(2237, "Oxfordshire"); + my $categories = [ 'Pothole', 'Vegetation', 'Flytipping' ]; my $params = { - postcode => 'OX1 1ND', - latitude => 51.7435918829363, - longitude => -1.23201966270446, + postcode => 'OX20 1SZ', + latitude => 51.754926, + longitude => -1.256179, }; my $bbox = ($params->{longitude} - 0.01) . ',' . ($params->{latitude} - 0.01) . ',' . ($params->{longitude} + 0.01) . ',' . ($params->{latitude} + 0.01); # Create one open and one fixed report in each category foreach my $category ( @$categories ) { + $mech->create_contact_ok( category => $category, body_id => $body->id, email => "$category\@example.org" ); foreach my $state ( 'confirmed', 'fixed' ) { my %report_params = ( %$params, category => $category, state => $state, ); - $mech->create_problems_for_body( 1, 2237, 'Around page', \%report_params ); + $mech->create_problems_for_body( 1, $body->id, 'Around page', \%report_params ); } } @@ -163,6 +166,14 @@ subtest 'check category and status filtering works on /around?ajax' => sub { my $pins = $json->{pins}; is scalar @$pins, 6, 'correct number of reports when no filters'; + # Regression test for filter_category in /around URL + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->get_ok( '/around?filter_category=Pothole&bbox=' . $bbox ); + $mech->content_contains('<option value="Pothole" selected>'); + }; + $json = $mech->get_ok_json( '/around?ajax=1&filter_category=Pothole&bbox=' . $bbox ); $pins = $json->{pins}; is scalar @$pins, 2, 'correct number of Pothole reports'; diff --git a/t/app/engine.t b/t/app/engine.t new file mode 100644 index 000000000..d99c5e087 --- /dev/null +++ b/t/app/engine.t @@ -0,0 +1,9 @@ +use FixMyStreet::Test; + +use Catalyst::Test 'FixMyStreet::App'; + +my $res = request("/?_override_foo=bar"); + +like $res->headers->header('Set-Cookie'), qr/SameSite=Lax/; + +done_testing; diff --git a/web/cobrands/fixmystreet/fixmystreet.js b/web/cobrands/fixmystreet/fixmystreet.js index d6ea9de18..be8500729 100644 --- a/web/cobrands/fixmystreet/fixmystreet.js +++ b/web/cobrands/fixmystreet/fixmystreet.js @@ -112,8 +112,9 @@ function isR2L() { }, make_multi: function() { - // A convenience wrapper around $.multiSelect() that translates HTML - // data-* attributes into settings for the multiSelect constructor. + // A convenience wrapper around $.multiSelect() that translates HTML + // data-* attributes into settings for the multiSelect constructor. + return this.each(function() { var $select = $(this); var settings = {}; @@ -144,6 +145,7 @@ function isR2L() { } $select.multiSelect(settings); + }); } }); diff --git a/web/js/lazyload.js b/web/js/lazyload.js index 50cc8c46e..770fc62d4 100644 --- a/web/js/lazyload.js +++ b/web/js/lazyload.js @@ -1,3 +1,5 @@ +// jshint esversion: 6 + (function(){ if (!('IntersectionObserver' in window)) { return; |