Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hoff 737: session timeout continue form #464

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


## 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.
*/

sulthan-ahmed marked this conversation as resolved.
Show resolved Hide resolved
'use strict';
sulthan-ahmed marked this conversation as resolved.
Show resolved Hide resolved
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