Commit Graph

324 Commits

Author SHA1 Message Date
Chris Hill-Scott
5c9a886edc Preview content as hint for broadcast templates
Broadcast services only have broadcast templates. But we show the
template type under the name of the template. This is redundant. It
would be better to preview the content of the template instead.

This then makes the templates page consistent with the dashboard.

Depends on:
- [ ] https://github.com/alphagov/notifications-api/pull/2996
2020-10-14 13:21:19 +01:00
Katie Smith
a67ea9a623 Fix the display of sms statuses 2020-09-18 16:26:08 +01:00
karlchillmaid
60a63c69ee Merge pull request #3578 from alphagov/update-sent-status-label
Update sent status label
2020-09-17 13:16:41 +01:00
Chris Hill-Scott
daaa3d69a3 Make sent international status display on 2 lines
Otherwise it wraps awkwardly
2020-09-17 12:33:46 +01:00
Tom Byers
04160800f0 Update call to api_key component across pages
Includes the following pages:
- letter contact (in service settings)
- sms-senders page (in service settings)
- email reply-to (in service settings)
- API key page

Note: the call on the letter contact page uses
the first line of the contact address as the
unique identifier for each button.
2020-08-25 10:54:42 +01:00
karlchillmaid
5eebbbc04f Update 'sent' label 2020-08-17 19:26:22 +01:00
Katie Smith
756a17f8db Add filter for formatting a number as currency
This is used on the usage page, but is likely to become useful in other
places now that letter rates can be greater than £1.
2020-07-15 14:09:49 +01:00
Chris Hill-Scott
effe24893e Make the broadcast flow talk to the API
This commit removes the code the puts areas into the session and instead
creates and then updates a draft broadcast in the database.

This is so we can avoid session-related bugs, and potentially having a
large session when we start adding personalisation etc.

Once a broadcast is ready to go it is set to `broadcasting` straight
away with no approval. We’ll revisit this as we learn more about how
users might want to manage who can create and approve broadcasts.

The tests are a bit light in terms of checking what’s on the page, but
clicking through the pages is probably good enough for now.
2020-07-09 14:31:12 +01:00
Chris Hill-Scott
d0d3fc6857 Add a map
So you can check you’ve chosen the right areas, and to give you a clear
idea of where the boundaries of an area are.

The Javascript and CSS for the map is only loaded on this page because
it adds quite a few kb, and we don’t want to be sending assets to the
majority of our users who will never see them.
2020-07-08 10:27:50 +01:00
David McDonald
9c82e61eaa Move init of gds metrics before csrf
This solves two problems
- it makes our response times more accurate as it means we start
  measuring the response time earlier (otherwise we aren't recording the
  time spent by `csrf` and `login_manager`s `before_request` functions
- is a temporary fix for a bug in the gds python metrics library as
  explained below.

Currently, when a request comes in it goes through various
`before_request` functions. Currently it goes through the function
introduced by the csrf client and then the one introduced by the metrics
client. If an exception is thrown by the csrf.before_request function
then we do not run the `metrics.before_request` function. This would
happen in the case that a CSRF token is invalid and then the main body
of the request would not process but then all `teardown_request`
functions will run. When the `metrics.teardown_request` function runs it
looks for `g._gds_metrics_start_time`, however this attribute is not
availble on the flask global object as it was not created as the
`metrics.before_request` function that creates it did not run. This then
throws an `AttributeError` and results in a 500 for the user. The short
term solution for this (initing metrics before csrf) means that
`_gds_metrics_start_time` will be set before csrf is at risk of throwing
an exception.

A separate PR will be put into the gds metrics python library to remove
the risk of an `AttributeError` and instead to log a warning instead of
throwing an uncaught exception.
2020-07-01 14:07:47 +01:00
David McDonald
d4ed909d0f Revert "Revert "Statsd to prometheus"" 2020-07-01 13:27:12 +01:00
David McDonald
5fb58260e2 Revert "Statsd to prometheus" 2020-07-01 10:00:39 +01:00
David McDonald
043e6ac69c Add GDS metrics package to admin app
Follows the code from the API
2020-06-30 14:24:34 +01:00
David McDonald
6958c0d677 Remove statsd
We don't expose these metrics anywhere anyway and we want to move to
prometheus too (which will be done in the next commit)
2020-06-30 11:08:11 +01:00
karlchillmaid
221a32441b Update permanent failure error name 2020-06-05 17:34:54 +01:00
Chris Hill-Scott
34f5417844 Group uploaded letters by day of printing
Some teams have started uploading quite a lot of letters (in the
hundreds per week). They’re also uploading CSVs of emails. This means
the uploads page ends up quite jumbled.

This is because:
- there’s just a lot of items to scan through
- conceptually it’s a bit odd to have batches of things displayed
  alongside individual things on the same page

So instead we’re going to start grouping together uploaded letters. This
will be by the date on which we ‘start’ printing them, or in other
words the time at which they can no longer be cancelled.

This feels like a natural grouping, and it matches what we know about
people’s mental models of ‘batches’ and ‘runs’ when talking about
printing.

This grouping will be done in the API, so all this commit need to do is:
- be ready to display this new type of pseudo-job
- link to the page that displays all the uploaded letters for a given
  print day
2020-05-11 14:29:03 +01:00
Chris Hill-Scott
2800b0a0c3 Add page to show all uploaded letters
Because we won’t be showing uploaded letters individually on the uploads
page any more we need a way of listing them. This should be by printing
day, to match how we’re grouping them on the uploads page.

This code reuses the notifications.html template, but flips the
precedence of the filename and recipient because I reckon when you’re
looking at uploads you’re thinking filename-first.
2020-05-11 14:27:43 +01:00
Chris Hill-Scott
e8b5de533d Fix relative date for returned letters
It was saying ‘16 hours ago’ instead of today. This is because, in
strftime:
- `%M` means minute, not month
- `%D` means short MM/DD/YY date, not day of the month

The test wasn’t catching this because the freeze time and mocked value
from the API were set to the same minute.
2020-04-01 17:38:06 +01:00
Chris Hill-Scott
3895794208 Merge branch 'master' into flask-login-again 2020-04-01 14:29:16 +01:00
Chris Hill-Scott
11cdf58256 Use the same form for problems and questions 2020-03-24 17:48:11 +00:00
Chris Hill-Scott
1c02476ee7 Let users upload a contact list to use later
We increasingly have teams wanting to do business-continuity type
messaging. They might be without access to their normal systems, which
is where they would otherwise go to get the list of email addresses or
phone numbers.

So we want to give them a place in Notify where they can store their
spreadsheets and use them at a later date.

For the initial pass we’re going to scope this to only allowing
spreadsheets with one column, ie just phone numbers/email addresses.
This is because:
- it minimises the amount of personal info we’re storing
- it reduces the chance of getting a placeholder error when you go to
  send the message, which is probably a high-stress situation where you
  might not be able to re-generate the file

The code for this is mostly copied from the existing upload CSV journey.
It’s quite duplicative, but that’s what I needed to do to get this out
quickly. There are opportunities for refactoring later.

Similarly, I would have liked to split this up into better commit
messages, but it really was a case of just bashing code out until it
worked 😳

This commit does not:
- implement the ‘view a contact list page’ (it just has a placeholder
  because the API isn’t ready at the moment)
- link to this page (because it’s not ready to use yet)
2020-03-16 13:07:28 +00:00
Leo Hemsted
4808509139 make flask_login upgrade backwards compatible
flask_login moves from `user_id` to `_user_id`. unfortunately, this
isn't backwards compatible as if an old cookie only has the old
`user_id`, then flask_login won't find `_user_id` so will mark the user
as unauthenticated.

this code will manually migrate the three flask login cookie variables,
before the flask_login code runs, so that it doesn't freak out
2020-03-13 15:16:12 +00:00
Leo Hemsted
2d8d2d712a move invite error handler to top level
ensure we catch org errors as well as regular errors
2020-03-06 13:20:31 +00:00
Leo Hemsted
106228ed09 Merge pull request #3320 from alphagov/remove-generic-400-error-page
remove admin 400 error handler
2020-02-21 13:08:53 +00:00
Chris Hill-Scott
60ea2eaa40 Merge pull request #3297 from alphagov/returned-letters-on-dashboard
Put a count of recently returned letters on the dashboard
2020-02-21 12:37:35 +00:00
Leo Hemsted
d83250c7c2 remove the generic 400 error page handler
it just shows a h1, so isn't helpful for people. We can re-use the 500
error page, which includes instructings "Try again later" and
instructions on what to do next (check the status page, email notify
support).

this required refactoring to ensure we can show the 500 error page while
still returning the required status code
2020-02-21 11:58:37 +00:00
Leo Hemsted
f64f5725d1 Treat 400s from the api as internal server errors
if we expect a 400 (for example, the api returns 400 if the service name
is already in use) then we should handle that from the view function so
we can correctly display a relevation error message to the user. But if
it returns a 400 that we didn't expect (for example, because we sent
variables of the wrong type through to an endpoint with a schema), then
that is a bug that we should fix as any other raised exception. By
treating it as a 500 we encourage users to report it to us, and also
will get an alert email
2020-02-20 17:51:05 +00:00
Chris Hill-Scott
64074eed03 Say ‘1 hour/month ago’ not ‘an hour/a month ago’
I think it read better without the indefinite article when it’s, for
example, placed alongside messages that read ‘2 hours ago’.
2020-02-20 11:58:57 +00:00
Chris Hill-Scott
9590643527 Use humanize for fuzzy time differences
It seems to do a bit better than ago (e.g. 4 months vs 146 days), and
looks like it’s maintained more often.
2020-02-20 11:58:57 +00:00
Chris Hill-Scott
f369f76ae4 Count recently-returned letters on the dashboard
Currently you have no way of getting to the returned letter page. This
commit adds a link to it from the dashboard, following the pattern of
the new received text messages banner.
2020-02-20 11:58:57 +00:00
Chris Hill-Scott
904007201f Make date of sending relative
This is a friendlier and better way of showing dates anywhere except in
a report which might be archived and referred back to later.

Bit trickier to implement here because a dat requires ‘on’ beforehand,
but we don’t say ‘on today’ in English.
2020-02-19 17:11:31 +00:00
Chris Hill-Scott
78ac345148 Put day of week on
This helps people understand how delivery dates fit into the week,
because if sending a letter spans the weekend it will take a bit longer.

We can remove `|string` now because `utc_string_to_aware_gmt_datetime`
now accepts datetimes.
2020-02-17 13:01:37 +00:00
Leo Hemsted
5bbbdc3cd9 fix xss with service letter contact blocks
service contact blocks contain new lines - and jinja2 normally ignores
newlines (as in it keeps them as new lines) - but we need to turn them
into `<br>` tags so that we can show the formatting that the user has
added. We were previously just doing `{{ block | nl2br | safe }}`. nl2br
turns the new lines into `<br>` tags, and then `safe` tells jinja that
it doesn't need to escape the html.

this causes issues if the user adds `<script>alert(1)</script>` to their
contact block (or some other evil xss hack), where that will get let
through due to the safe flag

To solve this, use `Markup(html='escape')` to sanitise any html, and
then convert new lines to <br>.

bump utils

another xss
2020-01-21 17:34:49 +00:00
Rebecca Law
03fe7674bf Add a url_converter to check the date format. 2019-12-30 16:53:32 +00:00
Tom Byers
869bd16536 Merge pull request #3225 from alphagov/fix-details
Add GOV.UK Frontend details component - second attempt
2019-12-23 09:47:56 +00:00
Chris Hill-Scott
eb87548632 Serve video from a domain that doesn’t set cookies
Then it’s one less cookie we have to get users to opt in to. We don’t
derive any value from Youtube setting cookies.

`youtube-nocookie.com` is a domain provided by Google for this purpose.
2019-12-19 13:43:44 +00:00
Tom Byers
810e880bb5 Update all, but one, <details> to component
Includes:

- in gulpfile.js:
  - add details macro to list of those copied from GOVUK Frontend
  - remove existing details polyfill
- convert all, but one, <details> tags to use GOVUK Frontend details component
- add jinja boolean filter to help setting 'open' attribute of <details> tags

Notes on the `<details>` not included in this:

The `<details>` used for notifications items on
the API integration page is not possible to
reproduce with the GOV.UK Frontend macro so I'm
splitting the resulting work out into it's own
commit.
2019-12-17 10:26:16 +00:00
Tom Byers
de6281bc0e Revert "Add GOVUK Frontend details component" 2019-12-16 16:20:03 +00:00
Tom Byers
61eaad9a9f Update all, but one, <details> to component
Includes:

- in gulpfile.js:
  - add details macro to list of those copied from GOVUK Frontend
  - remove existing details polyfill
- convert all, but one, <details> tags to use GOVUK Frontend details component
- add jinja boolean filter to help setting 'open' attribute of <details> tags

Notes on the `<details>` not included in this:

The `<details>` used for notifications items on
the API integration page is not possible to
reproduce with the GOV.UK Frontend macro so I'm
splitting the resulting work out into it's own
commit.
2019-12-06 08:20:49 +00:00
Leo Hemsted
72acc4ebdc add no_cookie blueprint
we have a hunch that some session related issues that we've seen over
the last few weeks might be related to weird race conditions where
cookies set by subresources (image previews of letters on the send flow)
arrive just as the img request is cancelled because the user has clicked
on a button to navigate to a new page, but still manage to set the
cookie? We're not entirely sure what's going on, but we've got a hunch
that not setting cookies on image fetches sounds sensible. Images are
always loaded as a subresource (ie: through a `src` tag in an html
element), so they should never need to change the cookies, so this seems
sensible. We've done this by creating a new blueprint that doesn't set
session.permanent, and doesn't call `save_serivce_or_org_after_request`
either.

cookies are sent back to the browser if:
`sesion.modified or (session.permanent and 'REFRESH_EVERY_REQUEST')`
(where the latter is a config setting).

Turning off REFRESH_EVERY_REQUEST (which is True by default) means that
we will only update the sesion if it's been modified. In practice,
literally every request is modified in the after_request handler
`save_service_or_org_after_request`. This is accidentally convenient,
as it guarantees that we'll still send back the cookie normally even
though refresh_every_request is disabled. Sending back the cookie
updates the expiry time (20 hours), so we need to keep doing this to
preserve existing session timeout behaviour.
2019-12-03 17:06:14 +00:00
Tom Byers
3c208a8b11 Move GOVUK Frontend templates from node_modules
`node_modules` isn't available in a live
environment so the `.njk` templates we're now
using from GOVUK Frontend need to go in the repo'
code.

Adds them in a new `app/templates/vendor` folder
to match how we do that in
`app/assets/stylesheets`.
2019-11-27 14:15:32 +00:00
Tom Byers
e09d510ab8 Revert "Replace govuk template with govuk frontend components - rewrite" 2019-11-26 12:14:09 +00:00
Tom Byers
73d846cc61 Move GOVUK Frontend templates from node_modules
`node_modules` isn't available in a live
environment so the `.njk` templates we're now
using from GOVUK Frontend need to go in the repo'
code.

Adds them in a new `app/templates/vendor` folder
to match how we do that in
`app/assets/stylesheets`.
2019-11-26 11:01:06 +00:00
Chris Hill-Scott
545b485d86 Add URL converters for template and file types
Sometimes we manually check that a URL parameter is in a required set.
Sometimes we don’t bother.

This commit adds a URL converter to do this so that:
- we don’t have to re-write the same code every time
- it’s easier to apply this check to other endpoints

This means endpoints that previously allowed a `template_type` or
`message_type` of `None` now 404. So I’ve had to add new routes for
with URLs that don’t include such parameters.

So this…:
```
/services/128b91b6-2996-4107-bb65-51b7c24a728d/notifications/sms.csv
/services/128b91b6-2996-4107-bb65-51b7c24a728d/notifications/None.csv
```

…becomes:
```
/services/128b91b6-2996-4107-bb65-51b7c24a728d/notifications/sms.csv
/services/128b91b6-2996-4107-bb65-51b7c24a728d/notifications.csv
```

This matches what we do for the HTML-responding equivalent (see
265931d217/app/main/views/jobs.py (L215-L216))
2019-11-07 13:48:09 +00:00
Chris Hill-Scott
554a852e2d Don’t return UUID objects from the UUID convertor
Because it means you often have to cast to string in your application
code just to get your tests passing.

The method being monkey patched is originally defined here: b81aa0f18c/src/werkzeug/routing.py (L1272)
2019-11-07 13:46:24 +00:00
Chris Hill-Scott
a765920f65 Add years to old dates
Just to disambiguate things without introducing unnecessary noise.
2019-10-23 13:18:58 +01:00
Chris Hill-Scott
b2ebaf153a Chunk events by day
Scanning the page is difficult at the moment because it’s hard to tell
how far apart in time events are, and thereby determine which events
might be related.

Grouping the events by day quickly lets users narrow their focus to
a meaningful subset of the events.
2019-10-23 13:06:25 +01:00
Chris Hill-Scott
59b4d60c91 Munge stuff into a consistent event data type
We store our audit history in two ways:

  1. A list of versions of a service
  2. A list of events to do with API keys

In the future there could be auditing data which we want to display that
is stored in other formats (for example the event table).

This commit adds some objects which wrap around the different types of
auditing data, and expose a consistent interface to them. This
architecture will let us:
- write clean code in the presentation layer to display these events on
  a page
- add more types of events in the future by subclassing the `Event` data
  type, without having to rewrite anything in the presentation layer
2019-10-23 13:02:11 +01:00
Tom Byers
f6a0026d67 Add extension initialisation in app init 2019-10-07 16:35:56 +01:00
karlchillmaid
535fb0e024 Replace doesn't with does not 2019-09-23 13:22:17 +01:00