Skip to content
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
48 changes: 30 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,21 @@ Clone the [opal-frontend-common-ui-lib](https://github.com/hmcts/opal-frontend-c

```bash
yarn
yarn build
yarn pack:local
```

This is required if you want to develop the frontend against the local version of the UI library using `yarn dev:local-lib:ssr`.
This is required if you want to develop the frontend against the local version of the UI library using `yarn dev:local-lib:ssr`. It generates a local `.tgz` package in the repository root.

#### 3. Clone opal-frontend-common-node-lib

Clone the [opal-frontend-common-node-lib](https://github.com/hmcts/opal-frontend-common-node-lib) repository and run:

```bash
yarn
yarn build
yarn pack:local
```

This is required if you want to develop the frontend against the local version of the Node library using `yarn dev:local-lib:ssr`.
This is required if you want to develop the frontend against the local version of the Node library using `yarn dev:local-lib:ssr`. It generates a local `.tgz` package in the repository root.

#### 4. Development server

Expand All @@ -95,22 +95,22 @@ There are two ways to run the Angular SSR application depending on whether you a

- To use **local** versions of the libraries:

First, ensure you've built the libraries locally and set the environment variables:
First, ensure you've run `yarn pack:local` in both libraries and set the environment variables:

```bash
export COMMON_UI_LIB_PATH="[INSERT PATH TO COMMON UI LIB DIST FOLDER]"
export COMMON_NODE_LIB_PATH="[INSERT PATH TO COMMON NODE LIB DIST FOLDER]"
export COMMON_UI_LIB_PATH="[INSERT PATH TO COMMON UI LIB REPOSITORY ROOT]"
export COMMON_NODE_LIB_PATH="[INSERT PATH TO COMMON NODE LIB REPOSITORY ROOT]"
```

**Ensure you've built both libraries and exported the environment variables before running this command.**
**Ensure you've run `yarn pack:local` in both libraries and exported the environment variables before running this command.**

Then run:

```bash
yarn dev:local-lib:ssr
```

This will import the local builds and start the SSR dev server with those versions.
This will install local `.tgz` packages and start the SSR dev server with those versions.

The application's home page will be available at **http://localhost:4200**.

Expand All @@ -132,14 +132,14 @@ There are two options depending on whether you're working with local or publishe

- To build and serve the application using **local** libraries:

First, ensure you've built both common libraries and set the environment variables:
First, ensure you've run `yarn pack:local` in both common libraries and set the environment variables:

```bash
export COMMON_UI_LIB_PATH="[INSERT PATH TO COMMON UI LIB DIST FOLDER]"
export COMMON_NODE_LIB_PATH="[INSERT PATH TO COMMON NODE LIB DIST FOLDER]"
export COMMON_UI_LIB_PATH="[INSERT PATH TO COMMON UI LIB REPOSITORY ROOT]"
export COMMON_NODE_LIB_PATH="[INSERT PATH TO COMMON NODE LIB REPOSITORY ROOT]"
```

**Ensure you've built both libraries and exported the environment variables before running this command.**
**Ensure you've run `yarn pack:local` in both libraries and exported the environment variables before running this command.**

Then run:

Expand All @@ -148,7 +148,7 @@ There are two options depending on whether you're working with local or publishe
```

This will:
- Import the local builds of the common libraries
- Install local `.tgz` packages for the common libraries
- Build the application for production
- Serve it on **http://localhost:4000**

Expand Down Expand Up @@ -317,12 +317,12 @@ This project supports switching between local and published versions of the `opa

### Switching to Local Versions

First, ensure you've built the libraries locally and exported the paths to the built `dist` folders:
First, ensure you've run `yarn pack:local` in both library repos and exported the repository root paths (where the `.tgz` files are created):

```bash
# In your shell config file (.zshrc, .bash_profile, etc.)
export COMMON_UI_LIB_PATH="[INSERT PATH TO COMMON UI LIB FOLDER]"
export COMMON_NODE_LIB_PATH="[INSERT PATH TO COMMON NODE LIB DIST FOLDER]"
export COMMON_NODE_LIB_PATH="[INSERT PATH TO COMMON NODE LIB FOLDER]"
```

Then, run the following scripts:
Expand All @@ -332,21 +332,33 @@ yarn import:local:common-ui-lib
yarn import:local:common-node-lib
```

These commands will remove the published versions and install the local builds from the paths you specified.
These commands will remove the published versions and install local `.tgz` packages from each configured path.

### Switching to Published Versions

To reinstall the published packages **at the exact versions declared in `package.json`** (not the latest):
If you have installed local `.tgz` packages and want to return to npm-published packages, first ensure your `package.json` dependencies are semver values (not `file:` tarball paths), then reinstall.

```bash
yarn add @hmcts/opal-frontend-common@<VERSION> @hmcts/opal-frontend-common-node@<VERSION>
yarn install
```

You can also use:

```bash
yarn import:published:common-ui-lib
yarn import:published:common-node-lib
```

These scripts read the target version from package.json.
If package.json still contains `file:...tgz` values, they will reinstall local tarballs rather than npm-published versions.

This is useful when you're no longer working on the libraries directly or want to verify against the published versions that your project is pinned to.

**Note:** Version upgrades should come via Renovate PRs. These commands do **not** upgrade to the latest; they reinstall the exact versions specified in `package.json`. For extra safety in CI, consider using `yarn install --immutable` to prevent lockfile drift.

**Platform note:** `import:*` scripts use Unix shell commands (`rm`, `ls`, `grep`) and are intended for macOS/Linux environments.

## Angular code scaffolding

Run `yarn ng generate component component-name` to generate a new component. You can also use `yarn ng generate directive|pipe|service|class|guard|interface|enum|module`.
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@
"build:ssr": "ng build --configuration production && ng run opal-frontend:server",
"build:serve:ssr": "yarn run build:ssr && yarn run serve:ssr",
"build:serve:local-lib:ssr": "yarn run import:local:common-ui-lib && yarn run import:local:common-node-lib && yarn run build:ssr && yarn run serve:ssr",
"import:local:common-ui-lib": "yarn remove @hmcts/opal-frontend-common && rm -rf .angular/cache && yarn add @hmcts/opal-frontend-common@file:$COMMON_UI_LIB_PATH",
"import:local:common-node-lib": "yarn remove @hmcts/opal-frontend-common-node && rm -rf .angular/cache && yarn add @hmcts/opal-frontend-common-node@file:$COMMON_NODE_LIB_PATH",
"import:local:common-ui-lib": "yarn remove @hmcts/opal-frontend-common && rm -rf .angular/cache && yarn add @hmcts/opal-frontend-common@file:$COMMON_UI_LIB_PATH/$(ls $COMMON_UI_LIB_PATH | grep .tgz | tail -1)",
"import:local:common-node-lib": "yarn remove @hmcts/opal-frontend-common-node && rm -rf .angular/cache && yarn add @hmcts/opal-frontend-common-node@file:$COMMON_NODE_LIB_PATH/$(ls $COMMON_NODE_LIB_PATH | grep .tgz | tail -1)",
"import:local:zephyr-automation-nodejs": "yarn remove @hmcts/zephyr-automation-nodejs && rm -rf .angular/cache && yarn add @hmcts/zephyr-automation-nodejs@file:$ZEPHYR_LIB_PATH",
"import:published:common-ui-lib": "yarn remove @hmcts/opal-frontend-common && rm -rf .angular/cache && VERSION=$(node -p \"require('./package.json').dependencies['@hmcts/opal-frontend-common']\") && yarn add @hmcts/opal-frontend-common@\"$VERSION\"",
"import:published:common-node-lib": "yarn remove @hmcts/opal-frontend-common-node && rm -rf .angular/cache && VERSION=$(node -p \"require('./package.json').dependencies['@hmcts/opal-frontend-common-node']\") && yarn add @hmcts/opal-frontend-common-node@\"$VERSION\"",
Expand Down Expand Up @@ -118,12 +118,12 @@
"@hmcts/info-provider": "^1.1.0",
"@hmcts/nodejs-healthcheck": "^1.8.5",
"@hmcts/nodejs-logging": "^4.0.4",
"@hmcts/opal-frontend-common": "^0.0.66",
"@hmcts/opal-frontend-common-node": "^0.0.27",
"@hmcts/opal-frontend-common": "^0.0.69",
"@hmcts/opal-frontend-common-node": "^0.0.28",
"@hmcts/properties-volume": "^1.1.0",
"@hmcts/zephyr-automation-nodejs": "0.0.6",
"@microsoft/applicationinsights-web": "^3.3.5",
"@ministryofjustice/frontend": "^8.0.0",
"@ministryofjustice/frontend": "^9.0.0",
"@ngrx/signals": "^21.0.0",
"accessible-autocomplete": "^3.0.0",
"applicationinsights": "~2.9.6",
Expand All @@ -137,7 +137,7 @@
"express": "^5.0.0",
"express-session": "^1.17.3",
"fast-sort": "^3.4.1",
"govuk-frontend": "^5.0.0",
"govuk-frontend": "^6.0.0",
"helmet": "^8.0.0",
"home-office-kit": "^1.2.0",
"http-proxy-middleware": "^3.0.0",
Expand Down
2 changes: 1 addition & 1 deletion src/styles.scss
Original file line number Diff line number Diff line change
@@ -1 +1 @@
@import '../node_modules/@hmcts/opal-frontend-common/styles/styles.scss';
@use '../node_modules/@hmcts/opal-frontend-common/styles/styles.scss';
4 changes: 2 additions & 2 deletions tsconfig.server.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
},
"files": [
"src/main.server.ts",
"node_modules/@hmcts/opal-frontend-common-node/global.d.ts",
"node_modules/@hmcts/opal-frontend-common-node/session.d.ts",
"node_modules/@hmcts/opal-frontend-common-node/dist/global.d.ts",
"node_modules/@hmcts/opal-frontend-common-node/dist/session.d.ts",
"server.ts"
]
}
8 changes: 8 additions & 0 deletions yarn-audit-known-issues
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
{"value":"@angular/compiler","children":{"ID":1114735,"Issue":"Angular vulnerable to XSS in i18n attribute bindings","URL":"https://github.com/advisories/GHSA-g93w-mfhg-p222","Severity":"high","Vulnerable Versions":">=21.0.0-next.0 <21.2.4","Tree Versions":["21.1.5"],"Dependents":["opal-frontend@workspace:."]}}
{"value":"@angular/core","children":{"ID":1113590,"Issue":"Angular i18n vulnerable to Cross-Site Scripting","URL":"https://github.com/advisories/GHSA-prjf-86w9-mfqv","Severity":"high","Vulnerable Versions":">=21.0.0-next.0 <=21.1.5","Tree Versions":["21.1.5"],"Dependents":["opal-frontend@workspace:."]}}
{"value":"@angular/core","children":{"ID":1114738,"Issue":"Angular vulnerable to XSS in i18n attribute bindings","URL":"https://github.com/advisories/GHSA-g93w-mfhg-p222","Severity":"high","Vulnerable Versions":">=21.0.0-next.0 <21.2.4","Tree Versions":["21.1.5"],"Dependents":["opal-frontend@workspace:."]}}
{"value":"@angular/ssr","children":{"ID":1113509,"Issue":"Angular SSR is vulnerable to SSRF and Header Injection via request handling pipeline","URL":"https://github.com/advisories/GHSA-x288-3778-4hhx","Severity":"critical","Vulnerable Versions":">=21.0.0-next.0 <21.1.5","Tree Versions":["21.1.4"],"Dependents":["opal-frontend@workspace:."]}}
{"value":"@angular/ssr","children":{"ID":1113513,"Issue":"Angular SSR has an Open Redirect via X-Forwarded-Prefix","URL":"https://github.com/advisories/GHSA-xh43-g2fq-wjrj","Severity":"moderate","Vulnerable Versions":">=21.0.0-next.0 <21.1.5","Tree Versions":["21.1.4"],"Dependents":["opal-frontend@workspace:."]}}
{"value":"@angular/ssr","children":{"ID":1115534,"Issue":"Protocol-Relative URL Injection via Single Backslash Bypass in Angular SSR","URL":"https://github.com/advisories/GHSA-vfx2-hv2g-xj5f","Severity":"moderate","Vulnerable Versions":">=21.0.0-next.0 <21.2.3","Tree Versions":["21.1.4"],"Dependents":["opal-frontend@workspace:."]}}
{"value":"ajv","children":{"ID":1113715,"Issue":"ajv has ReDoS when using `$data` option","URL":"https://github.com/advisories/GHSA-2g4f-4pwh-qvx6","Severity":"moderate","Vulnerable Versions":">=7.0.0-alpha.0 <8.18.0","Tree Versions":["8.17.1"],"Dependents":["schema-utils@npm:4.3.3"]}}
{"value":"bn.js","children":{"ID":1113442,"Issue":"bn.js affected by an infinite loop","URL":"https://github.com/advisories/GHSA-378v-28hj-76wf","Severity":"moderate","Vulnerable Versions":"<4.12.3","Tree Versions":["4.12.0"],"Dependents":["asn1.js@npm:5.4.1"]}}
{"value":"brace-expansion","children":{"ID":1115543,"Issue":"brace-expansion: Zero-step sequence causes process hang and memory exhaustion","URL":"https://github.com/advisories/GHSA-f886-m6hf-6m8v","Severity":"moderate","Vulnerable Versions":">=4.0.0 <5.0.5","Tree Versions":["5.0.3"],"Dependents":["minimatch@npm:3.1.2"]}}
{"value":"minimatch","children":{"ID":1113459,"Issue":"minimatch has a ReDoS via repeated wildcards with non-matching literal in pattern","URL":"https://github.com/advisories/GHSA-3ppc-4f35-3m26","Severity":"high","Vulnerable Versions":"<3.1.3","Tree Versions":["3.1.2"],"Dependents":["find-cypress-specs@npm:1.47.2"]}}
{"value":"minimatch","children":{"ID":1113465,"Issue":"minimatch has a ReDoS via repeated wildcards with non-matching literal in pattern","URL":"https://github.com/advisories/GHSA-3ppc-4f35-3m26","Severity":"high","Vulnerable Versions":">=9.0.0 <9.0.6","Tree Versions":["9.0.5"],"Dependents":["mocha@npm:11.7.5"]}}
{"value":"minimatch","children":{"ID":1113538,"Issue":"minimatch has ReDoS: matchOne() combinatorial backtracking via multiple non-adjacent GLOBSTAR segments","URL":"https://github.com/advisories/GHSA-7r86-cg39-jmmj","Severity":"high","Vulnerable Versions":"<3.1.3","Tree Versions":["3.1.2"],"Dependents":["find-cypress-specs@npm:1.47.2"]}}
Expand All @@ -18,9 +23,12 @@
{"value":"picomatch","children":{"ID":1115554,"Issue":"Picomatch has a ReDoS vulnerability via extglob quantifiers","URL":"https://github.com/advisories/GHSA-c2c7-rcm5-vvqj","Severity":"high","Vulnerable Versions":">=4.0.0 <4.0.4","Tree Versions":["4.0.2"],"Dependents":["tinyglobby@npm:0.2.10"]}}
{"value":"serialize-javascript","children":{"ID":1113686,"Issue":"Serialize JavaScript is Vulnerable to RCE via RegExp.flags and Date.prototype.toISOString()","URL":"https://github.com/advisories/GHSA-5c6j-r48x-rmvq","Severity":"high","Vulnerable Versions":"<=7.0.2","Tree Versions":["6.0.2"],"Dependents":["mocha@npm:11.7.5"]}}
{"value":"serialize-javascript","children":{"ID":1115723,"Issue":"Serialize JavaScript has CPU Exhaustion Denial of Service via crafted array-like objects","URL":"https://github.com/advisories/GHSA-qj8w-gfj5-8c6v","Severity":"moderate","Vulnerable Versions":"<7.0.5","Tree Versions":["6.0.2"],"Dependents":["mocha@npm:11.7.5"]}}
{"value":"tar","children":{"ID":1114200,"Issue":"tar has Hardlink Path Traversal via Drive-Relative Linkpath","URL":"https://github.com/advisories/GHSA-qffp-2rhf-9h96","Severity":"high","Vulnerable Versions":"<=7.5.9","Tree Versions":["7.5.9"],"Dependents":["node-gyp@npm:10.2.0"]}}
{"value":"tar","children":{"ID":1114302,"Issue":"node-tar Symlink Path Traversal via Drive-Relative Linkpath","URL":"https://github.com/advisories/GHSA-9ppj-qmqm-q256","Severity":"high","Vulnerable Versions":"<=7.5.10","Tree Versions":["7.5.9"],"Dependents":["node-gyp@npm:10.2.0"]}}
{"value":"undici","children":{"ID":1114591,"Issue":"Undici: Malicious WebSocket 64-bit length overflows parser and crashes the client","URL":"https://github.com/advisories/GHSA-f269-vfmq-vjvj","Severity":"high","Vulnerable Versions":">=7.0.0 <7.24.0","Tree Versions":["7.22.0"],"Dependents":["@actions/http-client@npm:2.2.3"]}}
{"value":"undici","children":{"ID":1114593,"Issue":"Undici has an HTTP Request/Response Smuggling issue","URL":"https://github.com/advisories/GHSA-2mjp-6q6p-2qxm","Severity":"moderate","Vulnerable Versions":">=7.0.0 <7.24.0","Tree Versions":["7.22.0"],"Dependents":["@actions/http-client@npm:2.2.3"]}}
{"value":"undici","children":{"ID":1114637,"Issue":"Undici has Unbounded Memory Consumption in WebSocket permessage-deflate Decompression","URL":"https://github.com/advisories/GHSA-vrm6-8vpv-qv8q","Severity":"high","Vulnerable Versions":">=7.0.0 <7.24.0","Tree Versions":["7.22.0"],"Dependents":["@actions/http-client@npm:2.2.3"]}}
{"value":"undici","children":{"ID":1114639,"Issue":"Undici has Unhandled Exception in WebSocket Client Due to Invalid server_max_window_bits Validation","URL":"https://github.com/advisories/GHSA-v9p9-hfj2-hcw8","Severity":"high","Vulnerable Versions":">=7.0.0 <7.24.0","Tree Versions":["7.22.0"],"Dependents":["@actions/http-client@npm:2.2.3"]}}
{"value":"undici","children":{"ID":1114641,"Issue":"Undici has CRLF Injection in undici via `upgrade` option","URL":"https://github.com/advisories/GHSA-4992-7rv2-5pvq","Severity":"moderate","Vulnerable Versions":">=7.0.0 <7.24.0","Tree Versions":["7.22.0"],"Dependents":["@actions/http-client@npm:2.2.3"]}}
{"value":"undici","children":{"ID":1114643,"Issue":"Undici has Unbounded Memory Consumption in its DeduplicationHandler via Response Buffering that leads to DoS","URL":"https://github.com/advisories/GHSA-phc3-fgpg-7m6h","Severity":"moderate","Vulnerable Versions":">=7.17.0 <7.24.0","Tree Versions":["7.22.0"],"Dependents":["@actions/http-client@npm:2.2.3"]}}
{"value":"yaml","children":{"ID":1115556,"Issue":"yaml is vulnerable to Stack Overflow via deeply nested YAML collections","URL":"https://github.com/advisories/GHSA-48c2-rrv3-qjmp","Severity":"moderate","Vulnerable Versions":">=2.0.0 <2.8.3","Tree Versions":["2.4.5"],"Dependents":["@cucumber/cucumber@npm:12.2.0"]}}
Loading
Loading