Skip to content

Commit

Permalink
HOFF-737: Session timeout warning
Browse files Browse the repository at this point in the history
- configure session timeout warning in frontend/themes/gov-uk/client-js/session-timeout-dialog.js
- add frontend/template-partials/partials/session-timeout-warning.html
- amend frontend/template-partials/partials/page.html to include session timeout warning in pages with forms.
- add styling for session timeout warning
- add leave form button in dialog box which resets session and goes to exit page informing user info has not been saved. This is for non save and return forms.
- create session timeout component exit page customisable and session timeout warning dialog content customisable
- add JSDoc and try/catch block to session timeout warning component
- add hof logger to session timeout warning component
- add session timeout warning component documentation to readme
- amend sub heading levels for components in readme
- amend confirmation page so it doesn't show popup
- amend pr template name so it is picked up
- add tests
- update change log
- update yarn.lock
  • Loading branch information
Rhodine-orleans-lindsay committed Jan 9, 2025
1 parent a135ac9 commit db0b465
Show file tree
Hide file tree
Showing 24 changed files with 997 additions and 41 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## 2024, Version 22.0.0, @Rhodine-orleans-lindsay
* Adds session timeout warning
- user can stay on page or exit form
- adds exit html
- updates confirmation html to a static page
- allows for customisation of session timeout warning dialog content and exit page content
* Fixes accessibility issues
* Sandbox area for testing hof changes
* Updates patch and minor dependency versions

## 2024-07-22, Version 21.0.0 (Stable), @Rhodine-orleans-lindsay
* Replaces deprecated request module with axios
- refactors the hof model and apis to use axios instead of request
Expand Down
101 changes: 74 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -945,11 +945,11 @@ Using the translation key `fields.field-name.label` will return different values
# HOF Components
## Date Component
## Date Component
A component for handling the rendering and processing of 3-input date fields used in HOF Applications.
## Usage
### Usage
In your fields config:
Expand All @@ -965,7 +965,7 @@ module.exports = {
The above example will create a new date component with the key `'date-field'` and will apply the validators `required` and `before` (before today).
## Configuration
### Configuration
The following optional configuration options are supported:
Expand All @@ -974,7 +974,7 @@ The following optional configuration options are supported:
- `dayOptional {Boolean}` - day defaults to `01` if omitted. Defaults to `false`
- `monthOptional {Boolean}` - month defaults to `01` if omitted. If true then also forces `dayOptional` to be true. Defaults to `false`
## Labels
### Labels
The three intermedate fields have fallback labels of Day, Month and Year, however custom labels can be used by including the translation at the following path:
Expand All @@ -998,13 +998,13 @@ fields.json
}
```
# Summary Page Component
## Summary Page Component
HOF behaviour for showing summary pages
The behaviour mixin will create a set of "locals" data which is compatible with [the `confirm` view from `hof-template-partials`](https://github.com/UKHomeOfficeForms/hof-template-partials/blob/master/views/confirm.html).
## Usage
### Usage
If no sections config is passed, then the mixin will create a section for each step that has fields, and a row within each section for each field on that step.
Expand Down Expand Up @@ -1043,11 +1043,11 @@ Alternatively, sections can be defined manually as follows:
}
```
## Configuration
### Configuration
The `sections` configuration should be a map of arrays, where the entries in the array are the fields that should be shown within that section.
### Field configuration
#### Field configuration
Fields can be defined as simple strings of the field key, in which case all default configuration will be used.
Expand Down Expand Up @@ -1087,30 +1087,30 @@ The `location-addresses` field is one that the application has setup to aggregat
This allows the creation of summary rows based on unknown dynamic user input, i.e. we can not predict in advance how many addresses a user wants to input, what the addresses are and how many categories the user wants to attach to each address. This allows you to easily list them this way.
## Translations
### Translations
The content for section headings and field labels will be loaded from translation files based on the keys.
### Section headings
#### Section headings
Translations for section headings are looked for in the following order:
- `pages.confirm.sections.${key}.header`
- `pages.${key}.header`
### Field labels
#### Field labels
Translations for field labels are looked for in the following order:
- `pages.confirm.fields.${key}.label`
- `fields.${key}.label`
- `fields.${key}.legend`
# Emailer Component
## Emailer Component
HOF behaviour to send emails
## Usage
### Usage
```js
const EmailBehaviour = require('hof').components.emailer;
Expand Down Expand Up @@ -1140,7 +1140,7 @@ steps: {
}
```
## Options
### Options
In addition to the options passed to `hof-emailer`, the following options can be used:
Expand All @@ -1159,17 +1159,17 @@ const emailer = EmailBehaviour({
});
```
# HOF Emailer
## HOF Emailer
An emailer service for HOF applications.
## Installation
### Installation
```bash
$ npm install hof-emailer --save
```
## Usage
### Usage
```js
// first create an emailer instance
Expand All @@ -1192,22 +1192,22 @@ emailer.send(to, body, subject).then(() => {
});
```
## Options
### Options
- `from`: <String>: Address to send emails from. Required.
- `transport`: <String>: Select what mechanism to use to send emails. Defaults: 'smtp'.
- `transportOptions`: <Object>: Set the options for the chosen transport, as defined below. Required.
- `layout`: <String>: Optional path to use a custom layout for email content.
## Transports
### Transports
The following transport options are available:
### `smtp`
#### `smtp`
[nodemailer-smtp-transport](https://github.com/andris9/nodemailer-smtp-transport)
#### Options
##### Options
- `host` <String>: Address of the mailserver. Required.
- `port` <String|Number>: Port of the mailserver. Required.
Expand All @@ -1216,11 +1216,11 @@ The following transport options are available:
- `auth.user` <String>: Mailserver authorisation username.
- `auth.pass` <String>: Mailserver authorisation password.
### `ses`
#### `ses`
[nodemailer-ses-transport](https://github.com/andris9/nodemailer-ses-transport)
#### Options
##### Options
- `accessKeyId` <String>: AWS accessKeyId. Required.
- `secretAccessKey` <String>: AWS accessKeyId. Required.
Expand All @@ -1230,18 +1230,18 @@ The following transport options are available:
- `rateLimit` <String>
- `maxConnections` <String>
### `debug`
#### `debug`
A development option to write the html content of the email to a file for inspection.
`transport: 'debug'`
#### debug options
##### debug options
- `dir` <String>: The location to save html to. Default: `./.emails`. This directory will be created if it does not exist.
- `open` <Boolean>: If set to true, will automatically open the created html file in a browser.
#### debug example
##### debug example
```
transport: 'debug'
Expand All @@ -1251,10 +1251,57 @@ transportOptions: {
}
```
### `stub`
#### `stub`
Disables sending email. No options are required.
## Session Timeout Warning Component
HOF component for customising session timeout related pages
This feature allows you to customise the content related to the session timeout warning, including the messages displayed in the session timeout warning dialog and on the exit page after a user exits the form due to a session timeout.
### Usage
To enable and customize the session timeout behavior, you need to set the component in your project's `hof.settings.json` file:
```js
"behaviours": [
"hof/components/session-timeout-warning"
]
```
By default, the framework uses the standard content provided by HOF. If you wish to override this with custom content at the project level, you must set the following variables to `true` in `hof.settings.json`:
```js
behaviours: [
require('../').components.sessionTimeoutWarning
],
sessionTimeoutWarningContent: true,
exitFormContent: true
```
### Customising content in `pages.json`
Once the variables are set, you can customize the session timeout warning and exit messages in your project's pages.json:
```json
"exit": {
"message": "We have cleared your information to keep it secure. Your information has not been saved."
},
"session-timeout-warning": {
"dialog-title": "Your application will close soon",
"dialog-text": "If that happens, your progress will not be saved.",
"timeout-continue-button": "Stay on this page",
"dialog-exit-link": "Exit this form"
}
```
### Editing content on the Exit Page Header and Title
To edit the exit page's header and title, create an `exit.json` file in your project and set the desired content:
```json
{
"header": "You have left this form",
"title": "You have left this form"
}
```
# UTILITIES
# Autofill Utility
Expand Down
3 changes: 2 additions & 1 deletion components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ module.exports = {
emailer: require('./emailer'),
homeOfficeCountries: require('./homeoffice-countries'),
notify: require('./notify'),
summary: require('./summary')
summary: require('./summary'),
sessionTimeoutWarning: require('./session-timeout-warning')
};
56 changes: 56 additions & 0 deletions components/session-timeout-warning/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
*
* @fileOverview
* Provides custom behavior for handling session timeout warnings and exit actions. This includes
* - Resetting the session if the user exits due to a session timeout.
* - Customizing the session timeout warning dialog content.
* - Setting custom content and titles on the exit page.
*
* @module SessionTimeoutWarningBehavior
* @requires ../../config/hof-defaults
* @param {Class} superclass - The class to be extended.
* @returns {Class} - The extended class with session timeout handling functionality.
*/

'use strict';
const config = require('../../config/hof-defaults');
const logger = require('../../lib/logger')(config);

module.exports = superclass => class extends superclass {
configure(req, res, next) {
try {
// Reset the session if the user chooses to exit on session timeout warning
if (req.form.options.route === '/exit') {
req.sessionModel.reset();
logger.log('info', 'Session has been reset on exit');
}
return super.configure(req, res, next);
} catch (error) {
logger.error('Error during session reset:', error);
return next(error); // Pass the error to the next middleware for centralised handling
}
}

locals(req, res) {
// set the custom session dialog message
const superLocals = super.locals(req, res);
if (res.locals.sessionTimeoutWarningContent === true) {
superLocals.dialogTitle = true;
superLocals.dialogText = true;
superLocals.timeoutContinueButton = true;
superLocals.dialogExitLink = true;
}

// set the content on /exit page
if (req.form.options.route === '/exit' && config.exitFormContent === true) {
superLocals.exitFormContent = true;
return superLocals;
} else if (req.form.options.route === '/exit' && config.exitFormContent === false) {
superLocals.header = req.translate('exit.header');
superLocals.title = req.translate('exit.title');
superLocals.message = req.translate('exit.message');
return superLocals;
}
return superLocals;
}
};
5 changes: 4 additions & 1 deletion config/hof-defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const defaults = {
getCookies: true,
getTerms: true,
getAccessibility: false,
sessionTimeoutWarningContent: false,
exitFormContent: false,
viewEngine: 'html',
protocol: process.env.PROTOCOL || 'http',
noCache: process.env.NO_CACHE || false,
Expand Down Expand Up @@ -47,7 +49,8 @@ const defaults = {
apis: {
pdfConverter: process.env.PDF_CONVERTER_URL
},
serveStatic: process.env.SERVE_STATIC_FILES !== 'false'
serveStatic: process.env.SERVE_STATIC_FILES !== 'false',
sessionTimeOutWarning: process.env.SESSION_TIMEOUT_WARNING || 300
};

module.exports = Object.assign({}, defaults, rateLimits);
5 changes: 5 additions & 0 deletions frontend/template-partials/translations/src/en/exit.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"header": "You have left this form",
"title": "You have left this form",
"message": "We have cleared your information to keep it secure. Your information has not been saved."
}
21 changes: 17 additions & 4 deletions frontend/template-partials/views/confirmation.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
{{<partials-page}}
{{$page-content}}
{{<layout}}
{{$journeyHeader}}
{{#t}}journey.header{{/t}}
{{/journeyHeader}}

{{$propositionHeader}}
{{> partials-navigation}}
{{/propositionHeader}}

{{$header}}
{{header}}
{{/header}}

{{$content}}
{{>partials-confirmation-alert}}
{{#markdown}}what-happens-next{{/markdown}}
{{/page-content}}
{{/partials-page}}
{{/content}}
{{/layout}}

9 changes: 9 additions & 0 deletions frontend/template-partials/views/exit.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{{<layout}}
{{$header}}
{{header}}
{{/header}}
{{$content}}
<h2 class="govuk-heading-m">{{#exitFormContent}}{{#t}}pages.exit.message{{/t}}{{/exitFormContent}}{{^exitFormContent}}{{#t}}{{message}}{{/t}}{{/exitFormContent}}</h2>
<a href="/" class="govuk-button" role="button">{{#t}}buttons.start-again{{/t}}</a>
{{/content}}
{{/layout}}
3 changes: 3 additions & 0 deletions frontend/template-partials/views/partials/head.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,7 @@
<meta name="robots" content="noindex">
{{/deIndex}}
<meta name="format-detection" content="telephone=no">
<noscript>
<meta http-equiv="refresh" content="{{sessionTimeOut}};url='/session-timeout'"/>
</noscript>
<link rel="stylesheet" href="{{assetPath}}/css/app.css">
Loading

0 comments on commit db0b465

Please sign in to comment.