diff options
-rw-r--r-- | perllib/FixMyStreet/App.pm | 4 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Admin.pm | 6 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Around.pm | 26 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Contact.pm | 2 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/My.pm | 11 | ||||
-rwxr-xr-x | perllib/FixMyStreet/App/Controller/Questionnaire.pm | 2 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Reports.pm | 10 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Tokens.pm | 35 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/Problem.pm | 2 | ||||
-rw-r--r-- | t/app/controller/admin.t | 7 | ||||
-rw-r--r-- | t/app/helpers/send_email.t | 3 | ||||
-rwxr-xr-x | templates/web/default/faq/faq-en-gb.html | 2 | ||||
-rwxr-xr-x | templates/web/default/reports/council.html | 2 | ||||
-rw-r--r-- | web/cobrands/lichfielddc/css/layout.css | 19 |
14 files changed, 90 insertions, 41 deletions
diff --git a/perllib/FixMyStreet/App.pm b/perllib/FixMyStreet/App.pm index 68bfc728b..beea8bb11 100644 --- a/perllib/FixMyStreet/App.pm +++ b/perllib/FixMyStreet/App.pm @@ -296,6 +296,10 @@ sub send_email { $email->header_set( ucfirst($_), $vars->{$_} ) for grep { $vars->{$_} } qw( to from subject); + $email->header_set( 'Message-ID', sprintf('<fms-%s-%s@%s>', + time(), unpack('h*', random_bytes(5, 1)), $c->config->{EMAIL_DOMAIN} + ) ); + # pass the email into mySociety::Email to construct the on the wire 7bit # format - this should probably happen in the transport instead but hohum. my $email_text = mySociety::Locale::in_gb_locale { mySociety::Email::construct_email( diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index 3f2b62f6f..3854e27aa 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -173,7 +173,7 @@ sub questionnaire : Path('questionnaire') : Args(0) { ); - my %questionnaire_counts = map { $_->get_column( 'reported' ) => $_->get_column( 'questionnaire_count' ) } $questionnaires->all; + my %questionnaire_counts = map { ( $_->get_column( 'reported' ) || -1 ) => $_->get_column( 'questionnaire_count' ) } $questionnaires->all; $questionnaire_counts{1} ||= 0; $questionnaire_counts{0} ||= 0; $questionnaire_counts{total} = $questionnaire_counts{0} + $questionnaire_counts{1}; @@ -746,6 +746,10 @@ sub update_edit : Path('update_edit') : Args(1) { $update->user($user); } + if ( $new_state eq 'confirmed' and $old_state eq 'unconfirmed' ) { + $update->confirmed( \'ms_current_timestamp()' ); + } + $update->update; $status_message = '<p><em>' . _('Updated!') . '</em></p>'; diff --git a/perllib/FixMyStreet/App/Controller/Around.pm b/perllib/FixMyStreet/App/Controller/Around.pm index fcf91123e..b29415566 100644 --- a/perllib/FixMyStreet/App/Controller/Around.pm +++ b/perllib/FixMyStreet/App/Controller/Around.pm @@ -235,14 +235,23 @@ the map. sub ajax : Path('/ajax') { my ( $self, $c ) = @_; + $c->res->content_type('text/javascript; charset=utf-8'); + + unless ( $c->req->param('bbox') ) { + $c->res->status(404); + $c->res->body(''); + return; + } + + # assume this is not cacheable - may need to be more fine-grained later + $c->res->header( 'Cache_Control' => 'max-age=0' ); + # how far back should we go? my $all_pins = $c->req->param('all_pins') ? 1 : undef; my $interval = $all_pins ? undef : $c->cobrand->on_map_default_max_pin_age; # Need to be the class that can handle it - if ($c->req->param('bbox')) { - FixMyStreet::Map::set_map_class( 'OSM' ); - } + FixMyStreet::Map::set_map_class( 'OSM' ); # extract the data from the map my ( $pins, $on_map, $around_map, $dist ) = @@ -268,16 +277,7 @@ sub ajax : Path('/ajax') { } ); - # assume this is not cacheable - may need to be more fine-grained later - $c->res->content_type('text/javascript; charset=utf-8'); - $c->res->header( 'Cache_Control' => 'max-age=0' ); - - if ( $c->req->param('bbox') ) { - $c->res->body($body); - } else { - # The JS needs the surrounding brackets for Tilma - $c->res->body("($body)"); - } + $c->res->body($body); } __PACKAGE__->meta->make_immutable; diff --git a/perllib/FixMyStreet/App/Controller/Contact.pm b/perllib/FixMyStreet/App/Controller/Contact.pm index 88ac4987f..9d7051e2f 100644 --- a/perllib/FixMyStreet/App/Controller/Contact.pm +++ b/perllib/FixMyStreet/App/Controller/Contact.pm @@ -39,6 +39,8 @@ Handle contact us form submission sub submit : Path('submit') : Args(0) { my ( $self, $c ) = @_; + $c->res->redirect( '/contact' ) and return unless $c->req->method eq 'POST'; + return unless $c->forward('setup_request') && $c->forward('determine_contact_type') diff --git a/perllib/FixMyStreet/App/Controller/My.pm b/perllib/FixMyStreet/App/Controller/My.pm index 19b3ffee0..e6062fe6c 100644 --- a/perllib/FixMyStreet/App/Controller/My.pm +++ b/perllib/FixMyStreet/App/Controller/My.pm @@ -30,8 +30,10 @@ sub my : Path : Args(0) { my $pins = []; my $problems = {}; - my $rs = $c->user->problems->search( undef, - { rows => 50 } )->page( $p_page ); + my $rs = $c->user->problems->search( undef, { + order_by => { -desc => 'confirmed' }, + rows => 50 + } )->page( $p_page ); while ( my $problem = $rs->next ) { push @$pins, { @@ -48,7 +50,10 @@ sub my : Path : Args(0) { $rs = $c->user->comments->search( { state => 'confirmed' }, - { rows => 50 } )->page( $u_page ); + { + order_by => { -desc => 'confirmed' }, + rows => 50 + } )->page( $u_page ); my @updates = $rs->all; $c->stash->{updates} = \@updates; $c->stash->{updates_pager} = $rs->pager; diff --git a/perllib/FixMyStreet/App/Controller/Questionnaire.pm b/perllib/FixMyStreet/App/Controller/Questionnaire.pm index acb1628cf..a87aff330 100755 --- a/perllib/FixMyStreet/App/Controller/Questionnaire.pm +++ b/perllib/FixMyStreet/App/Controller/Questionnaire.pm @@ -252,7 +252,7 @@ sub process_questionnaire : Private { } # Sent here from email token action. Simply load and display questionnaire. -sub index : Private { +sub show : Private { my ( $self, $c ) = @_; $c->forward( 'check_questionnaire' ); $c->forward( 'display' ); diff --git a/perllib/FixMyStreet/App/Controller/Reports.pm b/perllib/FixMyStreet/App/Controller/Reports.pm index 61d7d5cb1..feafc4b77 100644 --- a/perllib/FixMyStreet/App/Controller/Reports.pm +++ b/perllib/FixMyStreet/App/Controller/Reports.pm @@ -124,7 +124,9 @@ sub ward : Path : Args(2) { # List of wards unless ($c->stash->{ward}) { - my $children = mySociety::MaPit::call('area/children', $c->stash->{council}->{id} ); + my $children = mySociety::MaPit::call('area/children', $c->stash->{council}->{id}, + type => $mySociety::VotingArea::council_child_types, + ); foreach (values %$children) { $_->{url} = $c->uri_for( $c->stash->{council_url} . '/' . $c->cobrand->short_name( $_ ) @@ -269,9 +271,9 @@ sub ward_check : Private { type => $mySociety::VotingArea::council_child_types, min_generation => $c->cobrand->area_min_generation ); - foreach my $id (sort keys %$qw) { - if ($qw->{$id}->{parent_area} == $council->{id}) { - $c->stash->{ward} = $qw->{$id}; + foreach my $area (sort { $a->{name} cmp $b->{name} } values %$qw) { + if ($area->{parent_area} == $council->{id}) { + $c->stash->{ward} = $area; return; } } diff --git a/perllib/FixMyStreet/App/Controller/Tokens.pm b/perllib/FixMyStreet/App/Controller/Tokens.pm index 9abef591d..26a1a1459 100644 --- a/perllib/FixMyStreet/App/Controller/Tokens.pm +++ b/perllib/FixMyStreet/App/Controller/Tokens.pm @@ -33,11 +33,17 @@ sub confirm_problem : Path('/P') { # Load the problem my $data = $auth_token->data; - my $problem_id = $data->{id}; + my $problem_id = ref $data ? $data->{id} : $data; my $problem = $c->cobrand->problems->find( { id => $problem_id } ) || $c->detach('token_error'); $c->stash->{problem} = $problem; + if ( $problem->state eq 'unconfirmed' && $auth_token->created < DateTime->now->subtract( months => 1 ) ) { + $c->stash->{template} = 'errors/generic.html'; + $c->stash->{message} = _("I'm afraid we couldn't validate that token, as the report was made too long ago."); + return; + } + # check that this email or domain are not the cause of abuse. If so hide it. if ( $problem->is_from_abuser ) { $problem->update( @@ -47,6 +53,7 @@ sub confirm_problem : Path('/P') { } # We have a problem - confirm it if needed! + my $old_state = $problem->state; $problem->update( { state => 'confirmed', @@ -60,7 +67,7 @@ sub confirm_problem : Path('/P') { $c->forward( '/report/new/create_reporter_alert' ); # log the problem creation user in to the site - if ( $data->{name} || $data->{password} ) { + if ( ref($data) && ( $data->{name} || $data->{password} ) ) { $problem->user->name( $data->{name} ) if $data->{name}; $problem->user->password( $data->{password}, 1 ) if $data->{password}; $problem->user->update; @@ -68,6 +75,11 @@ sub confirm_problem : Path('/P') { $c->authenticate( { email => $problem->user->email }, 'no_password' ); $c->set_session_cookie_expire(0); + if ( $old_state eq 'confirmed' || $old_state eq 'fixed' ) { + my $report_uri = $c->uri_for( '/report', $problem->id ); + $c->res->redirect($report_uri); + } + return 1; } @@ -169,10 +181,6 @@ sub confirm_update : Path('/C') { sub load_questionnaire : Private { my ( $self, $c, $token_code ) = @_; - # Set up error handling - $c->stash->{error_template} = 'errors/generic.html'; - $c->stash->{message} = _("I'm afraid we couldn't validate that token. If you've copied the URL from an email, please check that you copied it exactly.\n"); - my $auth_token = $c->forward( 'load_auth_token', [ $token_code, 'questionnaire' ] ); $c->stash->{id} = $auth_token->data; $c->stash->{token} = $token_code; @@ -191,7 +199,7 @@ sub questionnaire : Path('/Q') : Args(1) { $c->authenticate( { email => $c->stash->{questionnaire}->problem->user->email }, 'no_password' ); $c->set_session_cookie_expire(0); - $c->forward( '/questionnaire/index'); + $c->forward( '/questionnaire/show' ); } =head2 load_auth_token @@ -218,21 +226,26 @@ sub load_auth_token : Private { scope => $scope, token => $token_code, } - ) || $c->detach('token_error'); + ); + + unless ( $token ) { + $c->stash->{template} = 'errors/generic.html'; + $c->stash->{message} = _("I'm afraid we couldn't validate that token. If you've copied the URL from an email, please check that you copied it exactly.\n"); + $c->detach; + } return $token; } =head2 token_error -Display an error page saying that there is something wrong with the token. +Display an error page saying that there is something wrong with the token (our end). =cut sub token_error : Private { my ( $self, $c ) = @_; - $c->stash->{template} = $c->stash->{error_template} || 'tokens/error.html'; - $c->detach; + $c->stash->{template} = 'tokens/error.html'; } __PACKAGE__->meta->make_immutable; diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm index ff730958a..2df26fde3 100644 --- a/perllib/FixMyStreet/DB/Result/Problem.pm +++ b/perllib/FixMyStreet/DB/Result/Problem.pm @@ -104,7 +104,7 @@ __PACKAGE__->has_many( # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:3sw/1dqxlTvcWEI/eJTm4w # Add fake relationship to stored procedure table -__PACKAGE__->has_many( +__PACKAGE__->has_one( "nearby", "FixMyStreet::DB::Result::Nearby", { "foreign.problem_id" => "self.id" }, diff --git a/t/app/controller/admin.t b/t/app/controller/admin.t index 7f8590747..4e2ec82fe 100644 --- a/t/app/controller/admin.t +++ b/t/app/controller/admin.t @@ -136,7 +136,7 @@ subtest 'check summary counts' => sub { my $host = FixMyStreet->config('BASE_URL'); $mech->get_ok('/admin/council_contacts/2650'); $mech->content_contains('Aberdeen City Council'); -$mech->content_contains('AB15 8RN'); +$mech->content_like(qr{AB\d\d}); $mech->content_contains("$host/around"); subtest 'check contact creation' => sub { @@ -602,7 +602,7 @@ for my $test ( }, changes => { text => 'this is a twice changed update', - state => 'hidden', + state => 'confirmed', }, log_count => 7, log_entries => [qw/edit state_change state_change edit edit edit edit/], @@ -629,6 +629,9 @@ for my $test ( $update->discard_changes; is $update->$_, $test->{changes}->{$_} for grep { $_ ne 'email' } keys %{ $test->{changes} }; + if ( $test->{changes}{state} && $test->{changes}{state} eq 'confirmed' ) { + isnt $update->confirmed, undef; + } if ( $test->{user} ) { is $update->user->id, $test->{user}->id, 'update user'; diff --git a/t/app/helpers/send_email.t b/t/app/helpers/send_email.t index ac7e5b5c2..8c043f701 100644 --- a/t/app/helpers/send_email.t +++ b/t/app/helpers/send_email.t @@ -9,7 +9,7 @@ BEGIN { FixMyStreet->test_mode(1); } -use Test::More tests => 5; +use Test::More tests => 6; use Email::Send::Test; use Path::Class; @@ -44,6 +44,7 @@ is scalar(@emails), 1, "caught one email"; # Get the email, check it has a date and then strip it out my $email_as_string = $emails[0]->as_string; ok $email_as_string =~ s{\s+Date:\s+\S.*?$}{}xms, "Found and stripped out date"; +ok $email_as_string =~ s{\s+Message-ID:\s+\S.*?$}{}xms, "Found and stripped out message ID (contains epoch)"; my $expected_email_content = file(__FILE__)->dir->file('send_email_sample.txt')->slurp; my $name = FixMyStreet->config('CONTACT_NAME'); diff --git a/templates/web/default/faq/faq-en-gb.html b/templates/web/default/faq/faq-en-gb.html index e943bf28f..355369009 100755 --- a/templates/web/default/faq/faq-en-gb.html +++ b/templates/web/default/faq/faq-en-gb.html @@ -29,7 +29,7 @@ or clearing</strong>, such as: issues – please use FixMyStreet only for problems such as the above. We often route problem reports via cleansing services or highways and so using FixMyStreet for other matters may result in a delay in your report getting - to the right department. <strong>You will need to contact your council + to the right department. <strong>You will need to contact [% c.cobrand.moniker == 'southampton' ? 'the' : 'your' %] council directly for problems such as</strong>: <ul><li>Anti-social behaviour diff --git a/templates/web/default/reports/council.html b/templates/web/default/reports/council.html index 2b004cf50..0739e84e8 100755 --- a/templates/web/default/reports/council.html +++ b/templates/web/default/reports/council.html @@ -23,7 +23,7 @@ <p>[% loc('Follow a ward link to view only reports within that ward.') %]</p> <ul> [% FOR child IN children.values.sort('name') %] -<li><a href="[% child.url %]">[% child.name %]</a></p> +<li><a href="[% child.url %]">[% child.name %]</a></li> [% END %] </ul> [% END %] diff --git a/web/cobrands/lichfielddc/css/layout.css b/web/cobrands/lichfielddc/css/layout.css index 98bf5b88a..e671ef61c 100644 --- a/web/cobrands/lichfielddc/css/layout.css +++ b/web/cobrands/lichfielddc/css/layout.css @@ -115,7 +115,7 @@ #mysociety #fixed { padding: 5px !important; margin: 70px 0 10px 0 !important; - width: 540px; + width: 405px; position: relative; top: 7px } @@ -125,9 +125,24 @@ } #mysociety #updates div { - border: none; + border-bottom: 1px dotted #ccc; + padding: 0 0 17px 0; + margin: 17px 0 0 0; +} + +#mysociety #updates { + margin-bottom: 40px; + } + +#mysociety #updates p { + margin-bottom: 15px; } +#map_box ul li p { + margin: 0; + padding: 0; +} + #mysociety input[type='text'], #mysociety input[type='password'], #mysociety input[type='email'] { background: #F9F9F1; border: 1px solid #666 !important; |