@ministryofjustice/hmpps-connect-dps-components 5.1.0 → 5.2.0

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.
Files changed (3) hide show
  1. package/README.md +19 -16
  2. package/package.json +27 -23
  3. package/scripts/patch.diff +170 -0
package/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # hmpps-connect-dps-components
2
2
 
3
- `hmpps-connect-dps-components` is a Node.js client library to simplify the process of incorporating global components
3
+ [![repo standards badge](https://img.shields.io/badge/endpoint.svg?&style=flat&logo=github&url=https%3A%2F%2Foperations-engineering-reports.cloud-platform.service.justice.gov.uk%2Fapi%2Fv1%2Fcompliant_public_repositories%2Fhmpps-connect-dps-components)](https://operations-engineering-reports.cloud-platform.service.justice.gov.uk/public-report/hmpps-connect-dps-components "Link to report")
4
+ [![Test, lint & publish](https://github.com/ministryofjustice/hmpps-connect-dps-components/actions/workflows/pipeline.yml/badge.svg?branch=main)](https://github.com/ministryofjustice/hmpps-connect-dps-components/actions/workflows/pipeline.yml)
5
+
6
+ `hmpps-connect-dps-components` is a Node.js client library to simplify the process of incorporating global components
4
7
  within DPS applications. We welcome feedback on this README [here](https://moj.enterprise.slack.com/archives/C04JFG3QJE6)
5
8
  in order to improve it.
6
9
 
@@ -84,7 +87,7 @@ It may be sufficient for you app to only request components for GET requests for
84
87
  may be more appropriate, especially if you use the [PRG pattern](https://en.wikipedia.org/wiki/Post/Redirect/Get) to
85
88
  handle form submission. This will help us to reduce the load on the micro frontend components API. You may wish to
86
89
  go even further, for example avoiding routes that don't need components - the Prisoner Profile does
87
- something like this to avoid the component API call for the following routes: `/api` (provides prisoner images) and `/`
90
+ something like this to avoid the component API call for the following routes: `/api` (provides prisoner images) and `/`
88
91
  (a redirect only route).
89
92
 
90
93
  ```javascript
@@ -152,7 +155,7 @@ Include reference to the components in your layout.njk file:
152
155
 
153
156
  ### Extra calls
154
157
 
155
- It may be that you need to add some extra requests for the page components for pages that do not fit the normal flow
158
+ It may be that you need to add some extra requests for the page components for pages that do not fit the normal flow
156
159
  of routes. e.g. in `setUpAuthentication.ts` on the `/autherror` path:
157
160
 
158
161
  ```javascript
@@ -175,13 +178,13 @@ This will provide a stripped down header for if there is no user object on `res.
175
178
 
176
179
  ### CSP
177
180
 
178
- The package updates the content-security-middleware to include references to the fe-components API. This package should
181
+ The package updates the content-security-middleware to include references to the fe-components API. This package should
179
182
  be run after Helmet to prevent this being overwritten.
180
183
 
181
- ### Shared Data
184
+ ### Shared Data
182
185
 
183
- An optional parameter `includeSharedData: true` can be passed into the `get` methods request options. Setting this will result in a
184
- `sharedData` object being added to `res.locals.feComponents` containing data the components have collected to render.
186
+ An optional parameter `includeSharedData: true` can be passed into the `get` methods request options. Setting this will result in a
187
+ `sharedData` object being added to `res.locals.feComponents` containing data the components have collected to render.
185
188
  This includes:
186
189
 
187
190
  - activeCaseLoad (the active caseload of the user)
@@ -189,19 +192,19 @@ This includes:
189
192
  - services (information on services the user has access to used for global navigation)
190
193
  - allocationJobResponsibilities (the allocation policy codes the user has the associated job responsibility for. Allocation policy codes are: `KEY_WORKER`, meaning the user is a key worker and `PERSONAL_OFFICER`, meaning the user is a personal officer.)
191
194
 
192
- This can be useful e.g. for when your service needs access to activeCaseLoad information to prevent extra calls to the
195
+ This can be useful e.g. for when your service needs access to activeCaseLoad information to prevent extra calls to the
193
196
  api and takes advantage of the caching that the micro frontend api does.
194
197
 
195
198
  ### Populating res.locals.user with the shared case load data
196
199
 
197
- Many services typically add case load information to the user object on `res.locals`. This library provides some
200
+ Many services typically add case load information to the user object on `res.locals`. This library provides some
198
201
  optional middleware which populates:
199
202
  - `res.locals.user.caseLoads` with all case loads the user has access to
200
203
  - `res.locals.user.activeCaseLoad` with the active case load of the user
201
204
  - `res.locals.user.activeCaseLoadId` with the id of the active case load
202
205
 
203
- It uses the `sharedData` object if it is present and caches in `req.session` so that any subsequent routes that do not
204
- use the component middleware can still use the data. If there is no data in the cache, it will fall back to making a
206
+ It uses the `sharedData` object if it is present and caches in `req.session` so that any subsequent routes that do not
207
+ use the component middleware can still use the data. If there is no data in the cache, it will fall back to making a
205
208
  call to Prison API to retrieve the data using the user token.
206
209
 
207
210
  To enable this, add the middleware after the component middleware as follows:
@@ -216,7 +219,7 @@ app.use(retrieveCaseLoadData({
216
219
  )
217
220
  ```
218
221
 
219
- This middleware checks the `res.locals.user.authSource` so ensure that any mock auth data used in tests includes
222
+ This middleware checks the `res.locals.user.authSource` so ensure that any mock auth data used in tests includes
220
223
  `auth_source: 'nomis'` in the response.
221
224
 
222
225
  ### Populating res.locals.user with the shared allocation job responsibilities
@@ -232,7 +235,7 @@ To enable this, add the middleware after the component middleware as follows:
232
235
 
233
236
  ```javascript
234
237
  import { retrieveAllocationJobResponsibilities } from '@ministryofjustice/hmpps-connect-dps-components'
235
- app.use(retrieveAllocationJobResponsibilities({
238
+ app.use(retrieveAllocationJobResponsibilities({
236
239
  logger,
237
240
  authenticationClient: new AuthenticationClient(config.apis.hmppsAuth, logger, services.dataAccess.tokenStore),
238
241
  allocationsApiConfig: config.apis.allocationsApi,
@@ -244,14 +247,14 @@ This should go after `retrieveCaseLoadData` so that `res.locals.user.activeCaseL
244
247
  This middleware checks the `res.locals.user.authSource` so ensure that any mock auth data used in tests includes
245
248
  `auth_source: 'nomis'` in the response. It also checks the `res.locals.user.activeCaseLoadId`, which is required for retrieving allocation job responsibilities.
246
249
 
247
- Your service will need to be set up with client credentials in order to use this middleware, although it currently
250
+ Your service will need to be set up with client credentials in order to use this middleware, although it currently
248
251
  does not need any specific role.
249
252
 
250
253
  ### Note
251
254
 
252
255
  In the event of a failure to retrieve the components, the package will populate the html fields with fallback components.
253
- The `feComponents.sharedData` will not be populated, but if you use the retrieveCaseLoadData middleware (see above) it
254
- will either take case load data from the cache or make a call to the Prison API to retrieve it.
256
+ The `feComponents.sharedData` will not be populated, but if you use the retrieveCaseLoadData middleware (see above) it
257
+ will either take case load data from the cache or make a call to the Prison API to retrieve it.
255
258
 
256
259
 
257
260
  ## For library developers:
package/package.json CHANGED
@@ -1,14 +1,18 @@
1
1
  {
2
2
  "name": "@ministryofjustice/hmpps-connect-dps-components",
3
- "version": "5.1.0",
3
+ "version": "5.2.0",
4
4
  "description": "A package to allow the inclusion of connect DPS micro frontend components within DPS applications",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.esm.js",
7
7
  "types": "./dist/index.d.ts",
8
8
  "files": [
9
- "dist/**/*"
9
+ "dist/**/*",
10
+ "scripts/**/*"
10
11
  ],
11
12
  "bin": "./scripts/install.ts",
13
+ "engines": {
14
+ "node": "20 || 22 || 24"
15
+ },
12
16
  "scripts": {
13
17
  "prepare": "hmpps-precommit-hooks-prepare",
14
18
  "build": "rollup -c rollup.config.ts --bundleConfigAsCjs && npm run copy:assets",
@@ -44,36 +48,36 @@
44
48
  },
45
49
  "homepage": "https://github.com/ministryofjustice/hmpps-connect-dps-components#readme",
46
50
  "devDependencies": {
47
- "@ministryofjustice/eslint-config-hmpps": "^0.0.5",
48
- "@ministryofjustice/hmpps-auth-clients": "^0.0.1",
49
- "@ministryofjustice/hmpps-precommit-hooks": "^0.0.3",
50
- "@rollup/plugin-commonjs": "^28.0.6",
51
- "@rollup/plugin-multi-entry": "^6.0.1",
52
- "@rollup/plugin-node-resolve": "^16.0.1",
53
- "@rollup/plugin-typescript": "^12.1.4",
54
- "@tsconfig/node22": "^22.0.2",
51
+ "@ministryofjustice/eslint-config-hmpps": "^1.0.0",
52
+ "@ministryofjustice/hmpps-auth-clients": "^1.0.0",
53
+ "@ministryofjustice/hmpps-precommit-hooks": "^1.0.2",
54
+ "@rollup/plugin-commonjs": "^29.0.0",
55
+ "@rollup/plugin-multi-entry": "^7.1.0",
56
+ "@rollup/plugin-node-resolve": "^16.0.3",
57
+ "@rollup/plugin-typescript": "^12.3.0",
58
+ "@tsconfig/node24": "^24.0.1",
55
59
  "@types/bunyan": "^1.8.11",
56
- "@types/express": "^4.17.22",
57
- "@types/jest": "^29.5.14",
60
+ "@types/express": "^5.0.5",
61
+ "@types/jest": "^30.0.0",
58
62
  "@types/superagent": "^8.1.9",
59
63
  "@types/supertest": "^6.0.3",
60
64
  "cheerio": "^1.0.0",
61
- "express": "^4.21.2",
62
- "govuk-frontend": "^5.10.1",
63
- "jest": "^29.7.0",
64
- "jest-html-reporter": "^3.10.2",
65
+ "express": "^5.1.0",
66
+ "govuk-frontend": "^5.13.0",
67
+ "jest": "^30.2.0",
68
+ "jest-html-reporter": "^4.3.0",
65
69
  "jest-junit": "^16.0.0",
66
- "lint-staged": "^16.1.2",
67
- "nock": "^13.5.6",
68
- "rollup": "^4.45.1",
69
- "rollup-plugin-dts": "^6.2.1",
70
+ "lint-staged": "^16.2.6",
71
+ "nock": "^14.0.10",
72
+ "rollup": "^4.53.2",
73
+ "rollup-plugin-dts": "^6.2.3",
70
74
  "supertest": "^7.1.1",
71
- "ts-jest": "^29.3.4",
75
+ "ts-jest": "^29.4.5",
72
76
  "tslib": "^2.8.1"
73
77
  },
74
78
  "dependencies": {
75
- "@ministryofjustice/hmpps-rest-client": "^0.0.3",
76
- "@types/node": "22.18.6",
79
+ "@ministryofjustice/hmpps-rest-client": "^1.0.0",
80
+ "@types/node": "^24.10.0",
77
81
  "@types/nunjucks": "^3.2.6",
78
82
  "nunjucks": "^3.2.4",
79
83
  "superagent": "^10.2.3"
@@ -0,0 +1,170 @@
1
+ diff --git a/assets/scss/index.scss b/assets/scss/index.scss
2
+ index 70feedd..a7cd9fd 100644
3
+ --- a/assets/scss/index.scss
4
+ +++ b/assets/scss/index.scss
5
+ @@ -6,6 +6,8 @@ $govuk-page-width: $moj-page-width;
6
+
7
+ @import "govuk-frontend/dist/govuk/index";
8
+ @import "@ministryofjustice/frontend/moj/all";
9
+ +@import "@ministryofjustice/hmpps-connect-dps-components/dist/assets/footer";
10
+ +@import "@ministryofjustice/hmpps-connect-dps-components/dist/assets/header-bar";
11
+
12
+ @import './components/header-bar';
13
+ @import './overrides/local';
14
+ diff --git a/feature.env b/feature.env
15
+ index 9a3f344..11b4654 100644
16
+ --- a/feature.env
17
+ +++ b/feature.env
18
+ @@ -1,6 +1,8 @@
19
+ PORT=3007
20
+ HMPPS_AUTH_URL=http://localhost:9091/auth
21
+ TOKEN_VERIFICATION_API_URL=http://localhost:9091/verification
22
+ +COMPONENT_API_URL=http://localhost:9091/frontend-components
23
+ +DPS_HOME_PAGE_URL=http://localhost:9091/dpshomepage
24
+ EXAMPLE_API_URL=http://localhost:9091/example-api
25
+ TOKEN_VERIFICATION_ENABLED=true
26
+ REDIS_ENABLED=false
27
+ diff --git a/helm_deploy/values-dev.yaml b/helm_deploy/values-dev.yaml
28
+ index f40e7d3..52b7431 100644
29
+ --- a/helm_deploy/values-dev.yaml
30
+ +++ b/helm_deploy/values-dev.yaml
31
+ @@ -11,6 +11,8 @@ generic-service:
32
+ INGRESS_URL: "https://template-typescript-dev.hmpps.service.justice.gov.uk"
33
+ HMPPS_AUTH_URL: "https://sign-in-dev.hmpps.service.justice.gov.uk/auth"
34
+ TOKEN_VERIFICATION_API_URL: "https://token-verification-api-dev.prison.service.justice.gov.uk"
35
+ + COMPONENT_API_URL: "https://frontend-components-dev.hmpps.service.justice.gov.uk"
36
+ + DPS_HOME_PAGE_URL: "https://digital-dev.prison.service.justice.gov.uk"
37
+ EXAMPLE_API_URL: 'https://template-kotlin-dev.hmpps.service.justice.gov.uk'
38
+ ENVIRONMENT_NAME: DEV
39
+ AUDIT_ENABLED: "false"
40
+ diff --git a/helm_deploy/values-preprod.yaml b/helm_deploy/values-preprod.yaml
41
+ index 554e19a..0d577b2 100644
42
+ --- a/helm_deploy/values-preprod.yaml
43
+ +++ b/helm_deploy/values-preprod.yaml
44
+ @@ -11,6 +11,8 @@ generic-service:
45
+ INGRESS_URL: "https://template-typescript-preprod.hmpps.service.justice.gov.uk"
46
+ HMPPS_AUTH_URL: "https://sign-in-preprod.hmpps.service.justice.gov.uk/auth"
47
+ TOKEN_VERIFICATION_API_URL: "https://token-verification-api-preprod.prison.service.justice.gov.uk"
48
+ + COMPONENT_API_URL: "https://frontend-components-preprod.hmpps.service.justice.gov.uk"
49
+ + DPS_HOME_PAGE_URL: "https://digital-preprod.prison.service.justice.gov.uk"
50
+ EXAMPLE_API_URL: 'https://template-kotlin-preprod.hmpps.service.justice.gov.uk'
51
+ ENVIRONMENT_NAME: PRE-PRODUCTION
52
+ AUDIT_ENABLED: "false"
53
+ diff --git a/helm_deploy/values-prod.yaml b/helm_deploy/values-prod.yaml
54
+ index 6bb4e41..3a2ae46 100644
55
+ --- a/helm_deploy/values-prod.yaml
56
+ +++ b/helm_deploy/values-prod.yaml
57
+ @@ -9,6 +9,8 @@ generic-service:
58
+ INGRESS_URL: "https://template-typescript.hmpps.service.justice.gov.uk"
59
+ HMPPS_AUTH_URL: "https://sign-in.hmpps.service.justice.gov.uk/auth"
60
+ TOKEN_VERIFICATION_API_URL: "https://token-verification-api.prison.service.justice.gov.uk"
61
+ + COMPONENT_API_URL: "https://frontend-components.hmpps.service.justice.gov.uk"
62
+ + DPS_HOME_PAGE_URL: "https://digital.prison.service.justice.gov.uk"
63
+ EXAMPLE_API_URL: 'https://template-kotlin.hmpps.service.justice.gov.uk'
64
+ AUDIT_ENABLED: "false"
65
+
66
+ diff --git a/server/app.ts b/server/app.ts
67
+ index eddaa67..0dfb1fe 100644
68
+ --- a/server/app.ts
69
+ +++ b/server/app.ts
70
+ @@ -1,7 +1,10 @@
71
+ import express from 'express'
72
+ +import { getFrontendComponents } from '@ministryofjustice/hmpps-connect-dps-components'
73
+
74
+ import createError from 'http-errors'
75
+
76
+ +import logger from '../logger'
77
+ +import config from './config'
78
+ import nunjucksSetup from './utils/nunjucksSetup'
79
+ import errorHandler from './errorHandler'
80
+ import { appInsightsMiddleware } from './utils/azureAppInsights'
81
+ @@ -38,6 +41,15 @@ export default function createApp(services: Services): express.Application {
82
+ app.use(setUpCsrf())
83
+ app.use(setUpCurrentUser())
84
+
85
+ + app.use(
86
+ + getFrontendComponents({
87
+ + logger,
88
+ + componentApiConfig: config.apis.componentApi,
89
+ + dpsUrl: config.serviceUrls.digitalPrison,
90
+ + requestOptions: { includeSharedData: true },
91
+ + }),
92
+ + )
93
+ +
94
+ app.use(routes(services))
95
+
96
+ app.use((req, res, next) => next(createError(404, 'Not found')))
97
+ diff --git a/server/config.ts b/server/config.ts
98
+ index e49a07b..9bbba57 100644
99
+ --- a/server/config.ts
100
+ +++ b/server/config.ts
101
+ @@ -72,6 +72,15 @@ export default {
102
+ agent: new AgentConfig(Number(get('TOKEN_VERIFICATION_API_TIMEOUT_RESPONSE', 5000))),
103
+ enabled: get('TOKEN_VERIFICATION_ENABLED', 'false') === 'true',
104
+ },
105
+ + componentApi: {
106
+ + url: get('COMPONENT_API_URL', 'http://localhost:8082', requiredInProduction),
107
+ + healthPath: '/ping',
108
+ + timeout: {
109
+ + response: Number(get('COMPONENT_API_TIMEOUT_RESPONSE', 2500)),
110
+ + deadline: Number(get('COMPONENT_API_TIMEOUT_DEADLINE', 2500)),
111
+ + },
112
+ + agent: new AgentConfig(Number(get('COMPONENT_TIMEOUT_DEADLINE', 10000))),
113
+ + },
114
+ exampleApi: {
115
+ url: get('EXAMPLE_API_URL', 'http://localhost:8080', requiredInProduction),
116
+ healthPath: '/health/ping',
117
+ @@ -82,6 +91,7 @@ export default {
118
+ agent: new AgentConfig(Number(get('EXAMPLE_API_TIMEOUT_RESPONSE', 5000))),
119
+ },
120
+ },
121
+ + serviceUrls: { digitalPrison: get('DPS_HOME_PAGE_URL', 'http://localhost:3001', requiredInProduction) },
122
+ sqs: {
123
+ audit: auditConfig(),
124
+ },
125
+ diff --git a/server/utils/nunjucksSetup.ts b/server/utils/nunjucksSetup.ts
126
+ index 1d00293..69a787c 100644
127
+ --- a/server/utils/nunjucksSetup.ts
128
+ +++ b/server/utils/nunjucksSetup.ts
129
+ @@ -30,6 +30,7 @@ export default function nunjucksSetup(app: express.Express): void {
130
+ path.join(__dirname, '../../server/views'),
131
+ 'node_modules/govuk-frontend/dist/',
132
+ 'node_modules/@ministryofjustice/frontend/',
133
+ + 'node_modules/@ministryofjustice/hmpps-connect-dps-components/dist/assets/',
134
+ ],
135
+ {
136
+ autoescape: true,
137
+ diff --git a/server/views/partials/layout.njk b/server/views/partials/layout.njk
138
+ index 63653a0..d87b07a 100644
139
+ --- a/server/views/partials/layout.njk
140
+ +++ b/server/views/partials/layout.njk
141
+ @@ -2,17 +2,28 @@
142
+
143
+ {% block head %}
144
+ <link href="{{ '/assets/css/index.css' | assetMap }}" rel="stylesheet"/>
145
+ +
146
+ + {% for js in feComponents.jsIncludes %}
147
+ + <script src="{{ js }}" nonce="{{ cspNonce }}"></script>
148
+ + {% endfor %}
149
+ + {% for css in feComponents.cssIncludes %}
150
+ + <link href="{{ css }}" nonce="{{ cspNonce }}" rel="stylesheet" />
151
+ + {% endfor %}
152
+ {% endblock %}
153
+
154
+ {% block pageTitle %}{{pageTitle | default(applicationName)}}{% endblock %}
155
+
156
+ {% block header %}
157
+ - {% include "./header.njk" %}
158
+ + {{ feComponents.header | safe }}
159
+ {% endblock %}
160
+
161
+ {% block bodyStart %}
162
+ {% endblock %}
163
+
164
+ +{% block footer %}
165
+ + {{ feComponents.footer | safe }}
166
+ +{% endblock %}
167
+ +
168
+ {% block bodyEnd %}
169
+ <script type="module" src="{{ '/assets/js/index.js' | assetMap }}"></script>
170
+ {% endblock %}