diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index 5c98d4afb7..a57d6df041 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -64,14 +64,14 @@ jobs: - name: Set up Docker Buildx if: success() - uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0 + uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 - name: Set up QEMU - uses: docker/setup-qemu-action@1f40c72289eff860ee54a304f1438e3cff362e0a # v4.3.0 + uses: docker/setup-qemu-action@99012661954931238ded8c8b007157a8430204e1 # v4.4.0 - name: Production Image Build if: success() id: build-image - uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 + uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 with: platforms: linux/amd64,linux/arm64,linux/arm/v7 diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml index 8ee02c1e9b..fdde86dd07 100644 --- a/.github/workflows/releases.yml +++ b/.github/workflows/releases.yml @@ -58,10 +58,10 @@ jobs: xvfb-run --server-args="-screen 0 1200x800x24" npx grunt testui - name: Set up Docker Buildx - uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0 + uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 - name: Set up QEMU - uses: docker/setup-qemu-action@1f40c72289eff860ee54a304f1438e3cff362e0a # v4.3.0 + uses: docker/setup-qemu-action@99012661954931238ded8c8b007157a8430204e1 # v4.4.0 - name: Image Metadata id: image-metadata @@ -81,7 +81,7 @@ jobs: password: ${{ env.REGISTRY_PASSWORD }} - name: Publish to GHCR - uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 + uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 with: context: . push: true diff --git a/Dockerfile b/Dockerfile index 2908dc827f..24783bb2be 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ # Modifier --platform=$BUILDPLATFORM limits the platform to "BUILDPLATFORM" during buildx multi-platform builds # This is because npm "chromedriver" package is not compatiable with all platforms # For more info see: https://docs.docker.com/build/building/multi-platform/#cross-compilation -FROM --platform=$BUILDPLATFORM node:24-alpine@sha256:e67514e5d0f6c46656005e1b693b2ec9d52e80b641307de684d4a015ba7a4eaf AS builder +FROM --platform=$BUILDPLATFORM node:24-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1 AS builder WORKDIR /app diff --git a/package-lock.json b/package-lock.json index 0becf29c0e..fb8d687e12 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,7 +39,7 @@ "d3": "7.9.0", "d3-hexbin": "^0.2.2", "diff": "^9.0.0", - "dompurify": "^3.4.15", + "dompurify": "^3.4.16", "es6-promisify": "^7.0.0", "escodegen": "^2.1.0", "esprima": "^4.0.1", @@ -112,16 +112,16 @@ "zlibjs": "^0.3.1" }, "devDependencies": { - "@babel/eslint-parser": "^8.0.5", - "@babel/plugin-transform-runtime": "^8.0.1", - "@babel/preset-env": "^8.0.5", + "@babel/eslint-parser": "^8.0.6", + "@babel/plugin-transform-runtime": "^8.0.6", + "@babel/preset-env": "^8.0.6", "@babel/runtime": "^8.0.5", "@codemirror/commands": "^6.11.1", "@codemirror/language": "^6.12.4", "@codemirror/search": "^6.7.2", - "@codemirror/state": "^6.7.5", - "@codemirror/view": "^6.43.12", - "@puppeteer/browsers": "3.2.2", + "@codemirror/state": "^6.7.6", + "@codemirror/view": "^6.43.13", + "@puppeteer/browsers": "3.2.3", "autoprefixer": "^10.6.1", "babel-loader": "^10.1.1", "babel-plugin-polyfill-corejs3": "^1.0.0", @@ -162,7 +162,7 @@ "sitemap": "^9.0.1", "terser": "^5.51.2", "webpack": "^5.110.3", - "webpack-bundle-analyzer": "^5.3.3", + "webpack-bundle-analyzer": "^5.4.0", "webpack-dev-server": "^6.0.0", "webpack-node-externals": "^3.0.0", "worker-loader": "^3.0.8" @@ -289,6 +289,7 @@ "integrity": "sha512-dYYg153EyN2Ekbqw2zAsbd6/JR+9N2SEoC7YV2GyyqMM7x9bLDTjBD6XBhSMLH0wtIVyJj03jWNriQhaN+eoCw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/helper-validator-identifier": "^8.0.0", "js-tokens": "^10.0.0" @@ -303,6 +304,7 @@ "integrity": "sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": "^22.18.0 || >=24.11.0" } @@ -312,12 +314,13 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@babel/eslint-parser": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-8.0.5.tgz", - "integrity": "sha512-q4c+FpoJ/FKeiLnZ9Os3vWnSlZw3dBmlTUx6vuITRqbd8yn4hgUB0/OOJ+gi5lt+mOx/0IW2rXINR98JJllfag==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-8.0.6.tgz", + "integrity": "sha512-mXx93HLovamLnDDLQ4i48gm4HHtaoqJrbMAuJqrMfpCGJkJ5M4sXhRgKGTrxykg1P8tAN5myrJxsRZuMuTq+OQ==", "dev": true, "license": "MIT", "dependencies": { @@ -353,14 +356,14 @@ } }, "node_modules/@babel/generator": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-8.0.5.tgz", - "integrity": "sha512-f/TuhuMAxJqhwxEGNsJrswuG9VHmh0oNFoQoo6TbpgtFAz9wYZXcTAcWZMHfp7ljesr0RG04bp3Aos9GI59L7w==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-8.0.6.tgz", + "integrity": "sha512-/pcanjdRsonCexCuxgGD8fKnBLLzk2i9uM4kmcmGyyev2R5YDs+rafMYZ89RvaGY1mW8T7C5au0TyYaEeHBGng==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^8.0.5", - "@babel/types": "^8.0.5", + "@babel/parser": "^8.0.6", + "@babel/types": "^8.0.6", "@jridgewell/gen-mapping": "0.4.0-beta.0", "@jridgewell/trace-mapping": "^0.3.31", "@types/jsesc": "^2.5.0", @@ -395,16 +398,16 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-8.0.5.tgz", - "integrity": "sha512-Qk8ahMGooH5mz6uuhoDvfZGkUf/Mf3RTBucVVl4MKx4LKMTv872TeW8O92h15iVtlN8wAROBIpI1aV6x1z0LCQ==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-8.0.6.tgz", + "integrity": "sha512-HTrtZ4+iA0+kzdbCgvdSk1U4pEl3BvpGnlUbualCGNbrVhhQvhgBzurTUmqpWyvyHbWYWaIfdx2mOlL9LJjsew==", "dev": true, "license": "MIT", "dependencies": { "@babel/compat-data": "^8.0.5", "@babel/helper-validator-option": "^8.0.0", "browserslist": "^4.24.0", - "lru-cache": "^11.0.0", + "flru": "1.0.2", "verkit": "^0.3.2" }, "engines": { @@ -452,9 +455,9 @@ } }, "node_modules/@babel/helper-globals": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-8.0.0.tgz", - "integrity": "sha512-lLozHOM6sWWlxNo8CYqHy4MBZeTvHXNgVPBfPOGsjPKUzHC2Az9QwB6gxdQmpwHl6GlQtbGgS+lj5887guDiLw==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-8.0.6.tgz", + "integrity": "sha512-OdnA/N52LhzFpeUuVz5YGuSWjc7TPHiFmVYZbPlSgExocO2GwbxVpSni9MVs5wwW+wZ4kPuwBEBN9pIPDYz1mA==", "dev": true, "license": "MIT", "engines": { @@ -594,9 +597,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-8.0.0.tgz", - "integrity": "sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-8.0.6.tgz", + "integrity": "sha512-+6HYEBnsDRZHJtUTAEfMQd0zMDqdFHS7C+5vAsEZqBUr3vEMWOWlHJ0Jz1gS8jJIlCvLsuA6ivmeoqzH936YcA==", "dev": true, "license": "MIT", "engines": { @@ -644,6 +647,7 @@ "integrity": "sha512-wfbi91pM3py96oIiJEz7qIpyXDytgr9zQC1HEWwlGNVRAEmItuU/0a41ZUKu1sJGyhhOIpc4t5vk4PYzt8wpsg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/template": "^8.0.0", "@babel/types": "^8.0.0" @@ -653,13 +657,13 @@ } }, "node_modules/@babel/parser": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-8.0.5.tgz", - "integrity": "sha512-51RXvQNFakaS0bTpYiGkxNbUVwkPO4kONv6EVLorZABxsx+KZ6Z7uSYvi/wmKS/+X+rfj9RvOw0/ZNh+cmI0Rw==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-8.0.6.tgz", + "integrity": "sha512-LpGDIYJAzc3Y3PT9x+FxBrGYu2PlWxLmyN7SwPTzaX0LSwEmFJBsRnPBqmaXF2r1v+Zhz6lNiEJ+7yKtM5+Ugg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^8.0.5" + "@babel/types": "^8.0.6" }, "bin": { "parser": "bin/babel-parser.js" @@ -717,9 +721,9 @@ } }, "node_modules/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array/-/plugin-bugfix-safari-rest-destructuring-rhs-array-8.0.5.tgz", - "integrity": "sha512-e5eeoBASO+893sCNdFE/vQ9STIxkSRtIcQwBmLdfDOWn1nnXDY+/ngqFC5zTSUTRl0yWR3inkPRlOQD4MMHeFg==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array/-/plugin-bugfix-safari-rest-destructuring-rhs-array-8.0.6.tgz", + "integrity": "sha512-vk9CzgaQGcTTBL8F0YNr7LBEka6pXP/I5KcMj0oicGXUquWSNqxiijHGQkHF+s8m910NbGMpn5mU2sFV7AQjBA==", "dev": true, "license": "MIT", "dependencies": { @@ -784,15 +788,15 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-8.0.1.tgz", - "integrity": "sha512-kqnSMF1YHBzuiQrl68675i5Ma1oljvo+SJsNEZFZVBu5BUrVIZm9KId3ui2PdtLK2sv2zM8sJnjPDfgLxQlEqQ==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-8.0.6.tgz", + "integrity": "sha512-4K13qZ2TVi9W/NHMg3y0Fguu63cPjGNZT5TpPctIUDdiuIpxo4jwvySGrPWlD6KD00exvpx6Y6l5foFEpnzDcg==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^8.0.1", "@babel/helper-remap-async-to-generator": "^8.0.1", - "@babel/traverse": "^8.0.0" + "@babel/traverse": "^8.0.6" }, "engines": { "node": "^22.18.0 || >=24.11.0" @@ -1432,9 +1436,9 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-8.0.5.tgz", - "integrity": "sha512-eSjLoICd0l8SkUAyV7hnVrsDycTVK7DRKXi3Pr1oqAVe37vdd4sesp8t6aZ/Wa23rV2ZQbnYJWDn7pOIf9Z/Jw==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-8.0.6.tgz", + "integrity": "sha512-ky/yW+PcQfHyOhbQFNkcHOCIHXaEANYaXCucZ1MY1PdSJRjaf3AX/TMKS6nCij73YtU1bVNy7Zx5NWAJy42TQA==", "dev": true, "license": "MIT", "dependencies": { @@ -1481,9 +1485,9 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-8.0.1.tgz", - "integrity": "sha512-MPDpKBrxn+thQay3eJmUiSeHswiT7MkINb48hHkX6OzodB149PKq1kred+lpMebrDzHA+G1ekCQnlYSkyEqAOw==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-8.0.6.tgz", + "integrity": "sha512-2djup+i7z4taCN9VCJsmPNC0GT5A0FhI+S0tZwK+FRDZdaEOQUYVmfKOg/hIKhMBXjOFxEsBHvGE0Thqj71edA==", "dev": true, "license": "MIT", "dependencies": { @@ -1646,24 +1650,24 @@ } }, "node_modules/@babel/preset-env": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-8.0.5.tgz", - "integrity": "sha512-0ZiW2jOnEQ3+FV3ro3uh6B5afBT0C2yJHCKvw+s1BOKKXg7VfCvTpGBylN5UFeO2SFtkVJB2KY0tEpdnUjjguw==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-8.0.6.tgz", + "integrity": "sha512-Ekl110OgRBQtibBTXrXyuxhy2p7QxpzWT45cFOZCBFKBan3o8vN54sQ26GtqyTyORSNWKx0GOmIdLTTu/Y+prA==", "dev": true, "license": "MIT", "dependencies": { "@babel/compat-data": "^8.0.5", - "@babel/helper-compilation-targets": "^8.0.5", + "@babel/helper-compilation-targets": "^8.0.6", "@babel/helper-plugin-utils": "^8.0.1", "@babel/helper-validator-option": "^8.0.0", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^8.0.1", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^8.0.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^8.0.1", - "@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": "^8.0.5", + "@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": "^8.0.6", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^8.0.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^8.0.1", "@babel/plugin-transform-arrow-functions": "^8.0.1", - "@babel/plugin-transform-async-generator-functions": "^8.0.1", + "@babel/plugin-transform-async-generator-functions": "^8.0.6", "@babel/plugin-transform-async-to-generator": "^8.0.1", "@babel/plugin-transform-block-scoped-functions": "^8.0.1", "@babel/plugin-transform-block-scoping": "^8.0.5", @@ -1701,7 +1705,7 @@ "@babel/plugin-transform-private-methods": "^8.0.1", "@babel/plugin-transform-private-property-in-object": "^8.0.5", "@babel/plugin-transform-property-literals": "^8.0.1", - "@babel/plugin-transform-regenerator": "^8.0.5", + "@babel/plugin-transform-regenerator": "^8.0.6", "@babel/plugin-transform-regexp-modifiers": "^8.0.1", "@babel/plugin-transform-reserved-words": "^8.0.1", "@babel/plugin-transform-shorthand-properties": "^8.0.1", @@ -1808,18 +1812,18 @@ "license": "MIT" }, "node_modules/@babel/traverse": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-8.0.5.tgz", - "integrity": "sha512-XFfnuvapSc/vJOcUO7kwORSvpBIvraofKEZ2dhT0PjiF21BRCD7YbAFC8UEeDJNeLoQz82/gVqzgX5hCzkCbdg==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-8.0.6.tgz", + "integrity": "sha512-ilYV+qLStGzSKLipJlETdvdtpK3rAuwfCmCoGKv15MU4EoeIuLkespSNoNLFGOPSciEHx9TLWtN5mv0fz5w5mQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^8.0.0", - "@babel/generator": "^8.0.5", - "@babel/helper-globals": "^8.0.0", - "@babel/parser": "^8.0.5", + "@babel/code-frame": "^8.0.6", + "@babel/generator": "^8.0.6", + "@babel/helper-globals": "^8.0.6", + "@babel/parser": "^8.0.6", "@babel/template": "^8.0.0", - "@babel/types": "^8.0.5", + "@babel/types": "^8.0.6", "obug": "^2.1.1" }, "engines": { @@ -1827,13 +1831,13 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/code-frame": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-8.0.0.tgz", - "integrity": "sha512-dYYg153EyN2Ekbqw2zAsbd6/JR+9N2SEoC7YV2GyyqMM7x9bLDTjBD6XBhSMLH0wtIVyJj03jWNriQhaN+eoCw==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-8.0.6.tgz", + "integrity": "sha512-uMHhvmDmwFiLuiozaoRYTZHqMFuu3fem/X9JY78lohAuLoh8LSGGC8JqUzo2cVuBsBxkjMZNk56CE7ock8Xxkw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^8.0.0", + "@babel/helper-validator-identifier": "^8.0.6", "js-tokens": "^10.0.0" }, "engines": { @@ -1841,9 +1845,9 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/helper-validator-identifier": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-8.0.4.tgz", - "integrity": "sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-8.0.6.tgz", + "integrity": "sha512-HYx0YmuchRxRSpnjvcNffnPS8DCauKNmnumIuHG3jnQAVewRA7kfJGwF13ayEpSZs7s4R/oBH4eppuXcAQd5JQ==", "dev": true, "license": "MIT", "engines": { @@ -1858,23 +1862,23 @@ "license": "MIT" }, "node_modules/@babel/types": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-8.0.5.tgz", - "integrity": "sha512-eVdMqi3ej5aHhyQ2Si6yD2cAWeV8FJK9UrhK5aL0Sd8hu5GhT+YswhVNbVheOGVYMg8kuGuMaUpkB3stjj4z8A==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-8.0.6.tgz", + "integrity": "sha512-c+xgSWboV2pdwXP67BUWDVRHi2BO5Q3KwxyFVs7taVTY+fsK47/L51ZXQoV9rozHJDNHvJ4v4WEsI/IlxV2l2A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^8.0.0", - "@babel/helper-validator-identifier": "^8.0.4" + "@babel/helper-string-parser": "^8.0.6", + "@babel/helper-validator-identifier": "^8.0.6" }, "engines": { "node": "^22.18.0 || >=24.11.0" } }, "node_modules/@babel/types/node_modules/@babel/helper-validator-identifier": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-8.0.4.tgz", - "integrity": "sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-8.0.6.tgz", + "integrity": "sha512-HYx0YmuchRxRSpnjvcNffnPS8DCauKNmnumIuHG3jnQAVewRA7kfJGwF13ayEpSZs7s4R/oBH4eppuXcAQd5JQ==", "dev": true, "license": "MIT", "engines": { @@ -1938,9 +1942,9 @@ } }, "node_modules/@codemirror/state": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.7.5.tgz", - "integrity": "sha512-QjLbZmY1Au3JiRrDVYFLRD0BZ3SOKS9pR3yjIkd7u27YY8TFD9/Q9fhPnLV5l1mHFSo3hHU/N31vpwEJOx4owQ==", + "version": "6.7.6", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.7.6.tgz", + "integrity": "sha512-kAz+AncRtKuIknedxT1bq4XwXv4UowhbkHU1myPrtVb/jZtImWuV5BXzv5vK6i3kYACsdiZiQKFQQ5Mq7elW8w==", "dev": true, "license": "MIT", "dependencies": { @@ -1948,9 +1952,9 @@ } }, "node_modules/@codemirror/view": { - "version": "6.43.12", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.43.12.tgz", - "integrity": "sha512-Nv0vxQ19NAqvB/c2pFzjIzFlzzJl7jmdtNkwOwGbn0Ks9mFAzibvumz7cQem5cRsFA2cEw2fg+uHZGbcHupLQQ==", + "version": "6.43.13", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.43.13.tgz", + "integrity": "sha512-sihaFrUzAsYBQsL9J2t69y8nfMQGwcYmggAZsk+kjPbjYZMyuf2hU8tUNTZ+P+isb6XRr8JE22TZlJxBoVdH1A==", "dev": true, "license": "MIT", "dependencies": { @@ -2103,7 +2107,6 @@ "integrity": "sha512-sLw1ik9qrPc2NZJ93Y6eKXd2r5jpiu7ciOl2fVsvKo11GU6MmOqx7J9UJ3uUy5+xo6Zvpo/6JGD030l8OiYUOw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=22.18.0" } @@ -2185,8 +2188,7 @@ "resolved": "https://registry.npmjs.org/@cspell/dict-css/-/dict-css-4.1.2.tgz", "integrity": "sha512-+ylGoKdwZ2sVOCOnU2Eq5wDZx+RaVX3HoKyNHGGsFvhSw6IidQ6tH/mAPKBDofViHJoWCPNlklE0lTr6MDG3QA==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@cspell/dict-dart": { "version": "2.3.2", @@ -2326,16 +2328,14 @@ "resolved": "https://registry.npmjs.org/@cspell/dict-html/-/dict-html-4.0.16.tgz", "integrity": "sha512-9B6/Cpb5YVcYgsEAlKudun1yd4ONllYS/ZibKLYea2apPR+l2vQdARnPrP9kTqa7NUNfRKl7m9Fb6k9rjimnow==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@cspell/dict-html-symbol-entities": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@cspell/dict-html-symbol-entities/-/dict-html-symbol-entities-4.0.5.tgz", "integrity": "sha512-429alTD4cE0FIwpMucvSN35Ld87HCyuM8mF731KU5Rm4Je2SG6hmVx7nkBsLyrmH3sQukTcr1GaiZsiEg8svPA==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@cspell/dict-java": { "version": "5.0.12", @@ -2533,8 +2533,7 @@ "resolved": "https://registry.npmjs.org/@cspell/dict-typescript/-/dict-typescript-3.2.3.tgz", "integrity": "sha512-zXh1wYsNljQZfWWdSPYwQhpwiuW0KPW1dSd8idjMRvSD0aSvWWHoWlrMsmZeRl4qM4QCEAjua8+cjflm41cQBg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@cspell/dict-vue": { "version": "3.0.5", @@ -2692,7 +2691,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -2716,7 +2714,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" } @@ -4579,9 +4576,9 @@ "license": "MIT" }, "node_modules/@puppeteer/browsers": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-3.2.2.tgz", - "integrity": "sha512-q2BU4YfO9h/Wt7IcWPcggpOOqLk2Tbs1hDwolvKZrweRjy751OJBKMN9zO5bfD0pzU7X/tvKw/exQds4pM/LOg==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-3.2.3.tgz", + "integrity": "sha512-2Bt3m6dDAJqmZehn0wiXSYyQmuhyiHHZ7FjvrVaS1W2RoFGV6eCK71UvKYkNJjkwC1Q9nobjhvTMhLQztFVINA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4854,7 +4851,8 @@ "resolved": "https://registry.npmjs.org/@types/gensync/-/gensync-1.0.5.tgz", "integrity": "sha512-MbsRCT7mTikHwKZ0X+LVUTLRrZZRLipTuXEO9qOYO+zmjMVk81axyClMROf6uoPD9MRVu46bx8zoR0Ad9q3NAg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/html-minifier-terser": { "version": "6.1.0", @@ -5220,7 +5218,6 @@ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5277,7 +5274,6 @@ "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -6528,7 +6524,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.11.20", "caniuse-lite": "^1.0.30001810", @@ -7347,7 +7342,8 @@ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/cookie": { "version": "0.7.2", @@ -8332,7 +8328,6 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", - "peer": true, "engines": { "node": ">=12" } @@ -8848,9 +8843,9 @@ } }, "node_modules/dompurify": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.15.tgz", - "integrity": "sha512-EUBjM+B+lkDE41iE82DDSCfkoPGfXx8IxFxPMjNzm/Uk4xDet77rTN9wqlxlVg71kK7XGuUMv6wUxJUwwv+Xyw==", + "version": "3.4.16", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.16.tgz", + "integrity": "sha512-sqo+pNp3qRhCIpbgRi1y8Tgk27Bo2Ry7w0dC1NBeNTdZChWjz9Xb/KOoZbRP/R6pQZ80Qw8YhXw13hWWBbMRnQ==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -9005,6 +9000,7 @@ "integrity": "sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=14" } @@ -9273,7 +9269,6 @@ "integrity": "sha512-wqA7W2jbsC/BnV9Iv1UZpKVFkO1AdNoSmYW8NWG4HNOBbkAMvIqDZ27pI2f07dqn583NcIC44ckjAcOXDL1QbQ==", "dev": true, "license": "MIT", - "peer": true, "workspaces": [ "packages/*" ], @@ -10151,6 +10146,16 @@ "dev": true, "license": "ISC" }, + "node_modules/flru": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flru/-/flru-1.0.2.tgz", + "integrity": "sha512-kWyh8ADvHBFz6ua5xYOPnUroZTT/bwWfrCeL0Wj1dzG4/YOmOcfJ99W8dOVyyynJN35rZ9aCOtHChqQovV7yog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/follow-redirects": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", @@ -10352,6 +10357,7 @@ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=6.9.0" } @@ -10709,7 +10715,6 @@ "integrity": "sha512-ng0CbpyNp/ox5e5CBY9TkZgVdAL4wK+nBHO6rNE8cXGa5kM++Lxlp0MpFBVZbpgOR2oCp/91V+T3CZVSWWLqMA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "dateformat": "~4.6.2", "eventemitter2": "~0.4.13", @@ -12831,7 +12836,6 @@ "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "jiti": "lib/jiti-cli.mjs" } @@ -12852,8 +12856,7 @@ "version": "3.7.1", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/js-ascon": { "version": "1.3.0", @@ -12957,7 +12960,6 @@ "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.4.0.tgz", "integrity": "sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==", "license": "MIT", - "peer": true, "engines": { "node": ">= 10.16.0" } @@ -15537,7 +15539,6 @@ "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==", "deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1", "license": "MIT", - "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -15597,7 +15598,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.18", "picocolors": "^1.1.1", @@ -15893,7 +15893,6 @@ "integrity": "sha512-idLLRewuemWd7GH/BDJzGiB0dWGfT2SQs3jy6NtZtGWU9uPTTSdeC1/cdbqLwgzhfv027daGFuXX426e2Eg20A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "agent-base": "9.0.0", "debug": "^4.3.4", @@ -16136,8 +16135,7 @@ "resolved": "https://registry.npmjs.org/quickjs-wasi/-/quickjs-wasi-2.2.0.tgz", "integrity": "sha512-zQxXmQMrEoD3S+jQdYsloq4qAuaxKFHZj6hHqOYGwB2iQZH+q9e/lf5zQPXCKOk0WJuAjzRFbO4KwHIp2D05Iw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/railroad-diagrams": { "version": "1.0.0", @@ -16821,7 +16819,6 @@ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -18150,8 +18147,7 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, - "license": "0BSD", - "peer": true + "license": "0BSD" }, "node_modules/tsyringe": { "version": "4.10.0", @@ -18739,7 +18735,6 @@ "integrity": "sha512-GuizBzRvo9YPpyoNMf3ag7AzxbaW85qrRSqTha345KyJbAFPt3/cMzBM0h+RWg7SK/7DdzRLINP3LvQ0hvr4hg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "^1.0.8", "@types/json-schema": "^7.0.15", @@ -18778,9 +18773,9 @@ } }, "node_modules/webpack-bundle-analyzer": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-5.3.3.tgz", - "integrity": "sha512-kr/bzg3sORg1xAnxpg1uaIPGDDNwaRIsClOv22HzCIMX9X64FbvIBNjP2ulPdfCgZw7ekrv7JGAPc30W+0b7rA==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-5.4.0.tgz", + "integrity": "sha512-6OjsEFQIwcRT1nId/O7OyHjDvrE0JSFAef/XCwGarrf9MF5/CaD0lhDvoySbus57dYEdJ3vrRVj5F3i30c4ozw==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index ac00bf0baf..9bd3513ff6 100644 --- a/package.json +++ b/package.json @@ -39,16 +39,16 @@ "node >= 24" ], "devDependencies": { - "@babel/eslint-parser": "^8.0.5", - "@babel/plugin-transform-runtime": "^8.0.1", - "@babel/preset-env": "^8.0.5", + "@babel/eslint-parser": "^8.0.6", + "@babel/plugin-transform-runtime": "^8.0.6", + "@babel/preset-env": "^8.0.6", "@babel/runtime": "^8.0.5", "@codemirror/commands": "^6.11.1", "@codemirror/language": "^6.12.4", "@codemirror/search": "^6.7.2", - "@codemirror/state": "^6.7.5", - "@codemirror/view": "^6.43.12", - "@puppeteer/browsers": "3.2.2", + "@codemirror/state": "^6.7.6", + "@codemirror/view": "^6.43.13", + "@puppeteer/browsers": "3.2.3", "autoprefixer": "^10.6.1", "babel-loader": "^10.1.1", "babel-plugin-polyfill-corejs3": "^1.0.0", @@ -89,7 +89,7 @@ "sitemap": "^9.0.1", "terser": "^5.51.2", "webpack": "^5.110.3", - "webpack-bundle-analyzer": "^5.3.3", + "webpack-bundle-analyzer": "^5.4.0", "webpack-dev-server": "^6.0.0", "webpack-node-externals": "^3.0.0", "worker-loader": "^3.0.8" @@ -124,7 +124,7 @@ "d3": "7.9.0", "d3-hexbin": "^0.2.2", "diff": "^9.0.0", - "dompurify": "^3.4.15", + "dompurify": "^3.4.16", "es6-promisify": "^7.0.0", "escodegen": "^2.1.0", "esprima": "^4.0.1", diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 8442fc13cd..079c7fe962 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -192,6 +192,7 @@ "name": "Public Key", "ops": [ "Parse X.509 certificate", + "Parse X.509 certificate bundles", "Parse X.509 CRL", "Parse ASN.1 hex string", "PEM to Hex", @@ -622,4 +623,4 @@ "Comment" ] } -] \ No newline at end of file +] diff --git a/src/core/operations/ParseX509CertificateBundles.mjs b/src/core/operations/ParseX509CertificateBundles.mjs new file mode 100644 index 0000000000..af6d211b67 --- /dev/null +++ b/src/core/operations/ParseX509CertificateBundles.mjs @@ -0,0 +1,69 @@ +/** + * @author Pål Sollie [sollie@gmail.com] + * @copyright Crown Copyright 2026 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; +import ParseX509Certificate from "./ParseX509Certificate.mjs"; + +/** + * Parse X.509 certificate bundles operation + */ +class ParseX509CertificateBundles extends Operation { + + /** + * ParseX509CertificateBundles constructor + */ + constructor() { + super(); + + this.name = "Parse X.509 certificate bundles"; + this.module = "PublicKey"; + this.description = "Parses a PEM file containing one or more X.509 certificates and displays the validity, issuer, subject, extensions and other details of each certificate in order."; + this.infoURL = "https://wikipedia.org/wiki/X.509"; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @returns {string} + */ + run(input) { + if (!input.length) return "No input"; + if (input.length > 2_000_000) throw new OperationError("Certificate bundle exceeds 2 MB"); + + const begin = "-----BEGIN CERTIFICATE-----"; + const end = "-----END CERTIFICATE-----"; + const parser = new ParseX509Certificate(); + const output = []; + let position = 0; + + while (position < input.length) { + const start = input.indexOf(begin, position); + if (start === -1) break; + if (input.slice(position, start).trim()) throw new OperationError("Invalid certificate bundle content"); + if (output.length >= 100) throw new OperationError("Certificate bundle exceeds 100 certificates"); + + const finish = input.indexOf(end, start + begin.length); + if (finish === -1) throw new OperationError(`Certificate ${output.length + 1}: PEM footer not found`); + + try { + if (!/^[A-Za-z0-9+/=\s]+$/.test(input.slice(start + begin.length, finish))) throw new Error("Invalid PEM body"); + output.push(`Certificate ${output.length + 1}:\n${parser.run(input.slice(start, finish + end.length), ["PEM"])}`); + } catch (err) { + throw new OperationError(`Certificate ${output.length + 1}: Certificate load error (non-certificate input?)`); + } + position = finish + end.length; + } + + if (input.slice(position).trim() || !output.length) throw new OperationError("Invalid certificate bundle content"); + return output.join("\n\n"); + } + +} + +export default ParseX509CertificateBundles; diff --git a/tests/operations/tests/ParseX509CertificateBundles.mjs b/tests/operations/tests/ParseX509CertificateBundles.mjs new file mode 100644 index 0000000000..0e0221c32a --- /dev/null +++ b/tests/operations/tests/ParseX509CertificateBundles.mjs @@ -0,0 +1,100 @@ +/** + * Parse X.509 certificate bundles tests + * + * @author Pål Sollie [sollie@gmail.com] + * @copyright Crown Copyright 2026 + * @license Apache-2.0 + */ + +import TestRegister from "../../lib/TestRegister.mjs"; +import ParseX509Certificate from "../../../src/core/operations/ParseX509Certificate.mjs"; + +const RSA_CERT = `-----BEGIN CERTIFICATE----- +MIIBfTCCASegAwIBAgIUeisK5Nwss2DGg5PCs4uSxxXyyNkwDQYJKoZIhvcNAQEL +BQAwEzERMA8GA1UEAwwIUlNBIHRlc3QwHhcNMjExMTE5MTcyMDI2WhcNMzExMTE3 +MTcyMDI2WjATMREwDwYDVQQDDAhSU0EgdGVzdDBcMA0GCSqGSIb3DQEBAQUAA0sA +MEgCQQDyq9A6emHSLczn5Omu5muy+AReC53pTGCrW6Bi65OoobahT2RUSzXCYuvB +757fLLTKz+dLeo6sFkNhIzHZI+n7AgMBAAGjUzBRMB0GA1UdDgQWBBRO+jvkqq5p +pnQgwMMnRoun6e7eiTAfBgNVHSMEGDAWgBRO+jvkqq5ppnQgwMMnRoun6e7eiTAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA0EAR/5HAZM5qBhU/ezDUIFx +gmUGoFbIb5kJD41YCnaSdrgWglh4He4melSs42G/oxBBjuCJ0bUpqWnLl+lJkv1z +IA== +-----END CERTIFICATE-----`; + +const EC_CERT = `-----BEGIN CERTIFICATE----- +MIIBfzCCASWgAwIBAgIUK4H8J3Hr7NpRLPrACj8Pje4JJJ0wCgYIKoZIzj0EAwIw +FTETMBEGA1UEAwwKUC0yNTYgdGVzdDAeFw0yMTExMTkxNzE5NDVaFw0zMTExMTcx +NzE5NDVaMBUxEzARBgNVBAMMClAtMjU2IHRlc3QwWTATBgcqhkjOPQIBBggqhkjO +PQMBBwNCAAQNRzwDQQM0qgJgg9YwfPXJTOoTmYmC6yBwATwfrzXR+QnxmZM2IIJr +qwuBHa8PVU2HZ2KKtaAo8fg9Uwpq/l7po1MwUTAdBgNVHQ4EFgQU/SxodXrpkybM +gcIgkxnRKd7HMzowHwYDVR0jBBgwFoAU/SxodXrpkybMgcIgkxnRKd7HMzowDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiBU9PrOa/kXCpTTBInRf/sN +ac2iDHmbdpWzcXI+xLKNYAIhAIRR1LRSHVwOTLQ/iBXd+8LCkm5aTB27RW46LN80 +ylxt +-----END CERTIFICATE-----`; + +const parser = new ParseX509Certificate(); +const recipeConfig = [{op: "Parse X.509 certificate bundles", args: []}]; + +TestRegister.addTests([ + { + name: "Parse X.509 certificate bundles: single PEM", + input: RSA_CERT, + expectedOutput: `Certificate 1:\n${parser.run(RSA_CERT, ["PEM"])}`, + recipeConfig + }, + { + name: "Parse X.509 certificate bundles: ordered PEM file with CRLF", + input: `\r\n${RSA_CERT}\r\n\r\n${EC_CERT}\r\n`.replace(/(?