hof 22.10.5-fix-error-page-journey-header-bug-beta.1 → 22.11.0-custom-session-timeout-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## 2025-11-11, Version 22.11.0 , @Rhodine-orleans-lindsay
2
+
3
+ ### Changed
4
+ - Updated custom session-timeout handling so that custom behaviours are not blocked by a `404` middleware error.
5
+
6
+ ### Added
7
+ - Added a `CUSTOM_SESSION_EXPIRY` environment variable so that a time other than the redis session ttl can be used for the session timeout. **IMPORTANT**: The `CUSTOM_SESSION_EXPIRY` variable must always a time before the redis session ttl would expire so that behaviours can run before the `SESSION_TIMEOUT` middleware is triggered.
8
+ - Added a `CUSTOM_SESSION_TIMEOUT` that is `false` by default. When set to `true` the the '/session-timeout' page can run before the session expires without triggering a `404` middleware error.
9
+
10
+ - 🎬 Action:
11
+ - For custom session timeout handling that is not linked to the redis session ttl, The following variables must be set: `CUSTOM_SESSION_EXPIRY` to the relevant expiry time e.g.600 and `CUSTOM_SESSION_TIMEOUT` to true.
12
+ - If a behaviour is required on the '/session-timeout` step, the '/session-timeout' step must be set in the project's index.js, along with any relevant behaviours.
13
+
14
+
1
15
  ## 2025-10-10, Version 22.10.4 (Stable), @dk4g
2
16
  ### Security
3
17
  - Upgraded axios version to address a security vulnerability
package/README.md CHANGED
@@ -867,7 +867,7 @@ Kubernetes healthcheck URLs are provided as defaults if no overrides are supplie
867
867
  |----------|-------------|---------|---------|
868
868
  | `SHOW_COOKIES_BANNER` | Controls whether the cookies banner is displayed | Auto-detected based on GA tags | `true`, `false` |
869
869
 
870
- **Behavior:**
870
+ **Behaviour:**
871
871
  - If `SHOW_COOKIES_BANNER` is explicitly set, that value is used
872
872
  - If not set, banner is automatically shown when `GA_TAG` or `GA_4_TAG` is present
873
873
  - If no GA tags are configured, banner is hidden by default
@@ -1328,7 +1328,11 @@ This feature allows you to customise the content related to the session timeout
1328
1328
 
1329
1329
  ### Usage
1330
1330
 
1331
- To enable and customise the session timeout behavior, you need to set the component and translations in your project's `hof.settings.json` file:
1331
+ By default, the session timeout is set to the redis session ttl. To bypass this and display the session timeout message before the redis session ttl the following evironment variables must be set:
1332
+ `CUSTOM_SESSION_EXPIRY` - e.g. `600`. Configured to expire before thte project's redis session ttl.
1333
+ `CUSTOM_SESSION_TIMEOUT` - `False` by default. When set to `true` the the '/session-timeout' page can run before the session expires without triggering a `404` middleware error.
1334
+
1335
+ To enable and customise the session timeout behaviour, you need to set the component and translations in your project's `hof.settings.json` file:
1332
1336
  ```json
1333
1337
  "behaviours": [
1334
1338
  "hof/components/session-timeout-warning"
@@ -1348,6 +1352,20 @@ By default, the framework uses the standard content provided by HOF. If you wish
1348
1352
  "saveExitFormContent": true // allows you to customise the content on the save-and-exit page
1349
1353
  ```
1350
1354
 
1355
+ To override the default session-timeout page completely, the path to the session-timeout.html should be set in the views property in the hof.settings.json file e.g. 
1356
+ ```json
1357
+ "behaviours": [
1358
+ "hof/components/session-timeout-warning"
1359
+ ],
1360
+ "translations": "./apps/common/translations",
1361
+ "views": ["./apps/common/views"], // allows you to overide the HOF default session-timeout page and use a custom one from the specified views
1362
+ ...
1363
+ ```
1364
+ or in the project's `server.js` e.g.
1365
+ ```js
1366
+ settings.views = path.resolve(__dirname, './apps/common/views');
1367
+ ```
1368
+
1351
1369
  ### Customising content in `pages.json`
1352
1370
  Once the variables are set, you can customise the session timeout warning and exit messages in your project's pages.json:
1353
1371
 
@@ -59,6 +59,7 @@ const defaults = {
59
59
  pdfConverter: process.env.PDF_CONVERTER_URL
60
60
  },
61
61
  serveStatic: process.env.SERVE_STATIC_FILES !== 'false',
62
+ customSessionTimeout: parseBoolean(process.env.CUSTOM_SESSION_TIMEOUT, false, 'CUSTOM_SESSION_TIMEOUT'),
62
63
  sessionTimeOutWarning: process.env.SESSION_TIMEOUT_WARNING || 300,
63
64
  serviceUnavailable: parseBoolean(process.env.SERVICE_UNAVAILABLE, false, 'SERVICE_UNAVAILABLE')
64
65
  };
@@ -1,6 +1,6 @@
1
1
  {{<layout}}
2
2
  {{$journeyHeader}}
3
- {{#serviceName}}{{serviceName}}{{/serviceName}}
3
+ {{#t}}journey.header{{/t}}
4
4
  {{/journeyHeader}}
5
5
  {{$propositionHeader}}
6
6
  {{> partials-navigation}}
package/index.js CHANGED
@@ -156,7 +156,7 @@ function bootstrap(options) {
156
156
  res.locals.htmlLang = config.htmlLang;
157
157
  res.locals.cookieName = config.session.name;
158
158
  // session timeout warning configs
159
- res.locals.sessionTimeOut = config.session.ttl;
159
+ res.locals.sessionTimeOut = process.env.CUSTOM_SESSION_EXPIRY || config.session.ttl;
160
160
  res.locals.sessionTimeOutWarning = config.sessionTimeOutWarning;
161
161
  res.locals.sessionTimeoutWarningContent = config.sessionTimeoutWarningContent;
162
162
  res.locals.exitFormContent = config.exitFormContent;
@@ -252,26 +252,32 @@ function bootstrap(options) {
252
252
 
253
253
  /**
254
254
  * Handles requests to the session timeout page.
255
+ * For custom session timeout handling that is not linked to the redis session ttl,
256
+ * set `CUSTOM_SESSION_EXPIRY` variables to the relevant time and `CUSTOM_SESSION_TIMEOUT`variables to true.
257
+ * If `CUSTOM_SESSION_EXPIRY` and `CUSTOM_SESSION_TIMEOUT` envs are set,
258
+ * include '/session-timeout' step in the project's index.js.
255
259
  * - If the user has a session cookie but their session is missing or inactive,
256
260
  * this triggers a session timeout error handled by error middleware.
257
261
  * - Otherwise, responds with a 404 "Page Not Found" error.
258
262
  * This route ensures the timeout page only appears after an actual session expiry.
259
263
  */
260
- app.get('/session-timeout', (req, res, next) => {
261
- if ((req.cookies['hof-wizard-sc']) && (!req.session || req.session.exists !== true)) {
262
- const err = new Error('Session expired');
263
- err.code = 'SESSION_TIMEOUT';
264
- return next(err);
265
- }
266
- const err = new Error('Not Found');
267
- err.status = 404;
268
- const locals = Object.assign({}, req.translate('errors'));
269
- if (locals && locals['404']) {
270
- return res.status(404).render('404', locals['404']);
271
- }
272
- // Fallback: render a basic 404 page if translation is missing
273
- return res.status(404).send('Page Not Found');
274
- });
264
+ if (!config.customSessionTimeout) {
265
+ app.get('/session-timeout', (req, res, next) => {
266
+ if ((req.cookies['hof-wizard-sc']) && (!req.session || req.session.exists !== true)) {
267
+ const err = new Error('Session expired');
268
+ err.code = 'SESSION_TIMEOUT';
269
+ return next(err);
270
+ }
271
+ const err = new Error('Not Found');
272
+ err.status = 404;
273
+ const locals = Object.assign({}, req.translate('errors'));
274
+ if (locals && locals['404']) {
275
+ return res.status(404).render('404', locals['404']);
276
+ }
277
+ // Fallback: render a basic 404 page if translation is missing
278
+ return res.status(404).send('Page Not Found');
279
+ });
280
+ }
275
281
 
276
282
  if (config.getAccessibility === true) {
277
283
  deprecate(
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hof",
3
3
  "description": "A bootstrap for HOF projects",
4
- "version": "22.10.5-fix-error-page-journey-header-bug-beta.1",
4
+ "version": "22.11.0-custom-session-timeout-beta.1",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
7
7
  "author": "HomeOffice",
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ module.exports = SuperClass => class extends SuperClass {
4
+ configure(req, res, next) {
5
+ // Simple behaviour to log to console when run
6
+ console.log('***************** console log behaviour executed************************');
7
+ return super.configure(req, res, next);
8
+ }
9
+ };
@@ -4,6 +4,7 @@
4
4
  const CountrySelect = require('./behaviours/country-select')
5
5
  const SummaryPageBehaviour = require('../../../').components.summary;
6
6
  const InternationalPhoneNumber = require('./behaviours/international-number');
7
+ const TestConsoleLog = require('./behaviours/test-console-log');
7
8
 
8
9
  module.exports = {
9
10
  name: 'sandbox',
@@ -92,6 +93,9 @@ module.exports = {
92
93
  ],
93
94
  next: '/confirm'
94
95
  },
96
+ '/session-timeout': {
97
+ behaviours: TestConsoleLog
98
+ },
95
99
  '/exit': {},
96
100
  '/save-and-exit': {}
97
101
  }
@@ -2,6 +2,10 @@
2
2
  "errors": {
3
3
  "service-unavailable": {
4
4
  "contact": "You can email for more information"
5
+ },
6
+ "session": {
7
+ "title": "Custom title translation - Your session has timed out",
8
+ "message": "Custom message translation - For your security, we have timed you out due to inactivity."
5
9
  }
6
10
  },
7
11
  "exit": {
@@ -1,5 +1,9 @@
1
1
  {
2
2
  "service-unavailable": {
3
3
  "contact": "You can email for more information"
4
+ },
5
+ "session": {
6
+ "title": "Custom title translation - Your session has timed out",
7
+ "message": "Custom message translation - For your security, we have timed you out due to inactivity."
4
8
  }
5
9
  }
@@ -0,0 +1,7 @@
1
+ {{<error}}
2
+ {{$content}}
3
+ <h1 class="govuk-heading-l">{{#t}}errors.session.title{{/t}}</h1>
4
+ <h2 class="govuk-heading-m">{{#t}}errors.session.message{{/t}}</h2>
5
+ <a href="/" class="govuk-button" role="button">{{#t}}buttons.start-again{{/t}}</a>
6
+ {{/content}}
7
+ {{/error}}
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "scripts": {
10
10
  "start": "node server.js",
11
- "start:dev": "HOF_SANDBOX=true ../bin/hof-build watch",
11
+ "start:dev": "HOF_SANDBOX=true ../bin/hof-build watch --env",
12
12
  "dev": "yarn && GA_TAG=test nodemon server",
13
13
  "build": "HOF_SANDBOX=true ../bin/hof-build",
14
14
  "postinstall": "yarn run build"