Merge branch 'master' into 2081-ref-in-release-file
This commit is contained in:
commit
d78ab4a077
36
.github/dependabot.yml
vendored
36
.github/dependabot.yml
vendored
@ -33,8 +33,6 @@ updates:
|
|||||||
versions: [ '>=5.0.0' ]
|
versions: [ '>=5.0.0' ]
|
||||||
- dependency-name: 'cbor'
|
- dependency-name: 'cbor'
|
||||||
versions: [ '>=10.0.0' ]
|
versions: [ '>=10.0.0' ]
|
||||||
- dependency-name: 'cspell'
|
|
||||||
versions: [ '>=9.0.0' ]
|
|
||||||
- dependency-name: 'eslint'
|
- dependency-name: 'eslint'
|
||||||
versions: [ '>=10.0.0' ]
|
versions: [ '>=10.0.0' ]
|
||||||
- dependency-name: 'eslint-plugin-jsdoc'
|
- dependency-name: 'eslint-plugin-jsdoc'
|
||||||
@ -45,8 +43,6 @@ updates:
|
|||||||
versions: [ '>=2.0.0' ]
|
versions: [ '>=2.0.0' ]
|
||||||
- dependency-name: 'jimp'
|
- dependency-name: 'jimp'
|
||||||
versions: [ '1.6.1' ]
|
versions: [ '1.6.1' ]
|
||||||
- dependency-name: 'otpauth'
|
|
||||||
versions: [ '>=9.4.0' ]
|
|
||||||
- dependency-name: 'webpack-dev-server'
|
- dependency-name: 'webpack-dev-server'
|
||||||
versions: [ '>=5.1.0' ]
|
versions: [ '>=5.1.0' ]
|
||||||
groups:
|
groups:
|
||||||
@ -60,15 +56,23 @@ updates:
|
|||||||
update-types:
|
update-types:
|
||||||
- 'patch'
|
- 'patch'
|
||||||
|
|
||||||
# Can't enable this until we are using Node 24 as the latest actions all require this version
|
# Versioning on Github Actions
|
||||||
# - package-ecosystem: "github-actions"
|
- package-ecosystem: "github-actions"
|
||||||
# # Workflow files stored in the default location of `.github/workflows`; no need to
|
# Workflow files stored in the default location of `.github/workflows`; no need to
|
||||||
# # specify `/.github/workflows` for `directory`
|
# specify `/.github/workflows` for `directory`
|
||||||
# directory: '/'
|
directory: '/'
|
||||||
# schedule:
|
schedule:
|
||||||
# interval: 'weekly'
|
interval: 'weekly'
|
||||||
# day: 'friday'
|
day: 'friday'
|
||||||
# time: '03:00'
|
time: '03:00'
|
||||||
# timezone: Europe/London
|
timezone: Europe/London
|
||||||
# commit-message:
|
commit-message:
|
||||||
# prefix: 'chore (deps): '
|
prefix: 'chore (deps): '
|
||||||
|
|
||||||
|
- package-ecosystem: docker
|
||||||
|
directory: /
|
||||||
|
schedule:
|
||||||
|
interval: 'weekly'
|
||||||
|
day: 'friday'
|
||||||
|
time: '03:00'
|
||||||
|
timezone: Europe/London
|
||||||
|
|||||||
14
.github/workflows/master.yml
vendored
14
.github/workflows/master.yml
vendored
@ -16,10 +16,10 @@ jobs:
|
|||||||
pages: write
|
pages: write
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
|
|
||||||
- name: Set node version
|
- name: Set node version
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||||
with:
|
with:
|
||||||
node-version: 24
|
node-version: 24
|
||||||
registry-url: "https://registry.npmjs.org"
|
registry-url: "https://registry.npmjs.org"
|
||||||
@ -44,9 +44,17 @@ jobs:
|
|||||||
- name: Generate sitemap
|
- name: Generate sitemap
|
||||||
run: npx grunt exec:sitemap
|
run: npx grunt exec:sitemap
|
||||||
|
|
||||||
|
- name: Setup Chrome
|
||||||
|
id: setup-chrome
|
||||||
|
if: success()
|
||||||
|
run: |
|
||||||
|
npx @puppeteer/browsers install chrome@148
|
||||||
|
echo chromedir=$(dirname $(find `pwd`/chrome/* -name chrome -print -quit)) >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: UI Tests
|
- name: UI Tests
|
||||||
if: success()
|
if: success()
|
||||||
run: |
|
run: |
|
||||||
|
export PATH=${{ steps.setup-chrome.outputs.chromedir }}:$PATH
|
||||||
sudo apt-get install xvfb
|
sudo apt-get install xvfb
|
||||||
xvfb-run --server-args="-screen 0 1200x800x24" npx grunt testui
|
xvfb-run --server-args="-screen 0 1200x800x24" npx grunt testui
|
||||||
|
|
||||||
@ -56,7 +64,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Deploy to GitHub Pages
|
- name: Deploy to GitHub Pages
|
||||||
if: success() && github.ref == 'refs/heads/master'
|
if: success() && github.ref == 'refs/heads/master'
|
||||||
uses: crazy-max/ghaction-github-pages@v3
|
uses: crazy-max/ghaction-github-pages@1d6ee9b181a81033a16bd707a1401afa978daab4 # v5.0.0
|
||||||
with:
|
with:
|
||||||
target_branch: gh-pages
|
target_branch: gh-pages
|
||||||
build_dir: ./build/prod
|
build_dir: ./build/prod
|
||||||
|
|||||||
22
.github/workflows/pull_requests.yml
vendored
22
.github/workflows/pull_requests.yml
vendored
@ -12,10 +12,10 @@ jobs:
|
|||||||
main:
|
main:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
|
|
||||||
- name: Set node version
|
- name: Set node version
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||||
with:
|
with:
|
||||||
node-version: 24
|
node-version: 24
|
||||||
registry-url: "https://registry.npmjs.org"
|
registry-url: "https://registry.npmjs.org"
|
||||||
@ -39,28 +39,36 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload Build Artefact
|
- name: Upload Build Artefact
|
||||||
if: success()
|
if: success()
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: zipped-build
|
name: zipped-build
|
||||||
path: build/prod/*.zip
|
path: build/prod/*.zip
|
||||||
retention-days: 5
|
retention-days: 5
|
||||||
|
|
||||||
|
- name: Setup Chrome
|
||||||
|
id: setup-chrome
|
||||||
|
if: success()
|
||||||
|
run: |
|
||||||
|
npx @puppeteer/browsers install chrome@148
|
||||||
|
echo chromedir=$(dirname $(find `pwd`/chrome/* -name chrome -print -quit)) >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: UI Tests
|
- name: UI Tests
|
||||||
if: success()
|
if: success()
|
||||||
run: |
|
run: |
|
||||||
|
export PATH=${{ steps.setup-chrome.outputs.chromedir }}:$PATH
|
||||||
sudo apt-get install xvfb
|
sudo apt-get install xvfb
|
||||||
xvfb-run --server-args="-screen 0 1200x800x24" npx grunt testui
|
xvfb-run --server-args="-screen 0 1200x800x24" npx grunt testui
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
if: success()
|
if: success()
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
|
||||||
|
|
||||||
- name: Production Image Build
|
- name: Production Image Build
|
||||||
if: success()
|
if: success()
|
||||||
id: build-image
|
id: build-image
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
|
||||||
with:
|
with:
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||||
|
|||||||
33
.github/workflows/releases.yml
vendored
33
.github/workflows/releases.yml
vendored
@ -22,10 +22,10 @@ jobs:
|
|||||||
contents: write
|
contents: write
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
|
|
||||||
- name: Set node version
|
- name: Set node version
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||||
with:
|
with:
|
||||||
node-version: 24
|
node-version: 24
|
||||||
registry-url: "https://registry.npmjs.org"
|
registry-url: "https://registry.npmjs.org"
|
||||||
@ -46,20 +46,29 @@ jobs:
|
|||||||
- name: Production Build
|
- name: Production Build
|
||||||
run: npx grunt prod
|
run: npx grunt prod
|
||||||
|
|
||||||
- name: UI Tests
|
- name: Setup Chrome
|
||||||
|
id: setup-chrome
|
||||||
|
if: success()
|
||||||
run: |
|
run: |
|
||||||
|
npx @puppeteer/browsers install chrome@148
|
||||||
|
echo chromedir=$(dirname $(find `pwd`/chrome/* -name chrome -print -quit)) >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: UI Tests
|
||||||
|
if: success()
|
||||||
|
run: |
|
||||||
|
export PATH=${{ steps.setup-chrome.outputs.chromedir }}:$PATH
|
||||||
sudo apt-get install xvfb
|
sudo apt-get install xvfb
|
||||||
xvfb-run --server-args="-screen 0 1200x800x24" npx grunt testui
|
xvfb-run --server-args="-screen 0 1200x800x24" npx grunt testui
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
|
||||||
|
|
||||||
- name: Image Metadata
|
- name: Image Metadata
|
||||||
id: image-metadata
|
id: image-metadata
|
||||||
uses: docker/metadata-action@v4
|
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
|
||||||
with:
|
with:
|
||||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
tags: |
|
tags: |
|
||||||
@ -68,24 +77,24 @@ jobs:
|
|||||||
type=semver,pattern={{version}}
|
type=semver,pattern={{version}}
|
||||||
|
|
||||||
- name: Log in to GHCR
|
- name: Log in to GHCR
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||||
with:
|
with:
|
||||||
registry: ${{ env.REGISTRY }}
|
registry: ${{ env.REGISTRY }}
|
||||||
username: ${{ env.REGISTRY_USER }}
|
username: ${{ env.REGISTRY_USER }}
|
||||||
password: ${{ env.REGISTRY_PASSWORD }}
|
password: ${{ env.REGISTRY_PASSWORD }}
|
||||||
|
|
||||||
- name: Publish to GHCR
|
- name: Publish to GHCR
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: true
|
push: true
|
||||||
tags: ${{ steps.image-metadata.outputs.tags }}
|
tags: ${{ steps.image-metadata.outputs.tags }}
|
||||||
labels: ${{ steps.image-metadata.outputs.labels }}
|
labels: ${{ steps.image-metadata.outputs.labels }}
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||||
|
|
||||||
- name: Upload Release Assets
|
- name: Upload Release Assets
|
||||||
id: upload-release-assets
|
id: upload-release-assets
|
||||||
uses: svenstaro/upload-release-action@v2
|
uses: svenstaro/upload-release-action@29e53e917877a24fad85510ded594ab3c9ca12de # v2
|
||||||
with:
|
with:
|
||||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
file: build/prod/*.zip
|
file: build/prod/*.zip
|
||||||
@ -101,10 +110,10 @@ jobs:
|
|||||||
needs: main
|
needs: main
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
|
|
||||||
- name: Set node version
|
- name: Set node version
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||||
with:
|
with:
|
||||||
node-version: 24
|
node-version: 24
|
||||||
registry-url: "https://registry.npmjs.org"
|
registry-url: "https://registry.npmjs.org"
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -13,3 +13,4 @@ src/node/index.mjs
|
|||||||
**/*.DS_Store
|
**/*.DS_Store
|
||||||
tests/browser/output/*
|
tests/browser/output/*
|
||||||
.node-version
|
.node-version
|
||||||
|
chrome
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
# Modifier --platform=$BUILDPLATFORM limits the platform to "BUILDPLATFORM" during buildx multi-platform builds
|
# 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
|
# 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
|
# For more info see: https://docs.docker.com/build/building/multi-platform/#cross-compilation
|
||||||
FROM --platform=$BUILDPLATFORM node:24-alpine AS builder
|
FROM --platform=$BUILDPLATFORM node:24-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f AS builder
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ RUN npm run build
|
|||||||
#########################################
|
#########################################
|
||||||
# Package static build files into nginx #
|
# Package static build files into nginx #
|
||||||
#########################################
|
#########################################
|
||||||
FROM nginxinc/nginx-unprivileged:stable-alpine AS cyberchef
|
FROM nginxinc/nginx-unprivileged:stable-alpine@sha256:b9f7ba14f1f7bd3d40d7753584048f92c3aef9ccf5fab14efe4451a8d4c04d63 AS cyberchef
|
||||||
|
|
||||||
LABEL maintainer="GCHQ <oss@gchq.gov.uk>"
|
LABEL maintainer="GCHQ <oss@gchq.gov.uk>"
|
||||||
|
|
||||||
|
|||||||
873
package-lock.json
generated
873
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
27
package.json
27
package.json
@ -42,17 +42,18 @@
|
|||||||
"@babel/eslint-parser": "^7.28.6",
|
"@babel/eslint-parser": "^7.28.6",
|
||||||
"@babel/plugin-syntax-import-assertions": "^7.28.6",
|
"@babel/plugin-syntax-import-assertions": "^7.28.6",
|
||||||
"@babel/plugin-transform-runtime": "^7.29.0",
|
"@babel/plugin-transform-runtime": "^7.29.0",
|
||||||
"@babel/preset-env": "^7.29.2",
|
"@babel/preset-env": "^7.29.5",
|
||||||
"@babel/runtime": "^7.29.2",
|
"@babel/runtime": "^7.29.2",
|
||||||
"@codemirror/commands": "^6.10.3",
|
"@codemirror/commands": "^6.10.3",
|
||||||
"@codemirror/language": "^6.12.3",
|
"@codemirror/language": "^6.12.3",
|
||||||
"@codemirror/search": "^6.7.0",
|
"@codemirror/search": "^6.7.0",
|
||||||
"@codemirror/state": "^6.5.4",
|
"@codemirror/state": "^6.5.4",
|
||||||
"@codemirror/view": "^6.41.1",
|
"@codemirror/view": "^6.43.0",
|
||||||
|
"@puppeteer/browsers": "3.0.3",
|
||||||
"autoprefixer": "^10.5.0",
|
"autoprefixer": "^10.5.0",
|
||||||
"babel-loader": "^10.1.1",
|
"babel-loader": "^10.1.1",
|
||||||
"base64-loader": "^1.0.0",
|
"base64-loader": "^1.0.0",
|
||||||
"chromedriver": "^146.0.6",
|
"chromedriver": "^148.0.3",
|
||||||
"cli-progress": "^3.12.0",
|
"cli-progress": "^3.12.0",
|
||||||
"colors": "^1.4.0",
|
"colors": "^1.4.0",
|
||||||
"compression-webpack-plugin": "^12.0.0",
|
"compression-webpack-plugin": "^12.0.0",
|
||||||
@ -62,7 +63,7 @@
|
|||||||
"css-loader": "^7.1.4",
|
"css-loader": "^7.1.4",
|
||||||
"eslint": "^9.39.4",
|
"eslint": "^9.39.4",
|
||||||
"eslint-plugin-jsdoc": "^50.8.0",
|
"eslint-plugin-jsdoc": "^50.8.0",
|
||||||
"globals": "^17.4.0",
|
"globals": "^17.6.0",
|
||||||
"grunt": "^1.6.2",
|
"grunt": "^1.6.2",
|
||||||
"grunt-chmod": "~1.1.1",
|
"grunt-chmod": "~1.1.1",
|
||||||
"grunt-concurrent": "^3.0.0",
|
"grunt-concurrent": "^3.0.0",
|
||||||
@ -79,7 +80,7 @@
|
|||||||
"mini-css-extract-plugin": "2.10.2",
|
"mini-css-extract-plugin": "2.10.2",
|
||||||
"modify-source-webpack-plugin": "^4.1.0",
|
"modify-source-webpack-plugin": "^4.1.0",
|
||||||
"nightwatch": "^3.15.0",
|
"nightwatch": "^3.15.0",
|
||||||
"postcss": "^8.5.10",
|
"postcss": "^8.5.14",
|
||||||
"postcss-css-variables": "^0.19.0",
|
"postcss-css-variables": "^0.19.0",
|
||||||
"postcss-import": "^16.1.1",
|
"postcss-import": "^16.1.1",
|
||||||
"postcss-loader": "^8.2.1",
|
"postcss-loader": "^8.2.1",
|
||||||
@ -87,7 +88,7 @@
|
|||||||
"sitemap": "^8.0.3",
|
"sitemap": "^8.0.3",
|
||||||
"terser": "^5.46.2",
|
"terser": "^5.46.2",
|
||||||
"webpack": "^5.106.2",
|
"webpack": "^5.106.2",
|
||||||
"webpack-bundle-analyzer": "^5.0.0",
|
"webpack-bundle-analyzer": "^5.3.0",
|
||||||
"webpack-dev-server": "^5.0.4",
|
"webpack-dev-server": "^5.0.4",
|
||||||
"webpack-node-externals": "^3.0.0",
|
"webpack-node-externals": "^3.0.0",
|
||||||
"worker-loader": "^3.0.8"
|
"worker-loader": "^3.0.8"
|
||||||
@ -96,15 +97,15 @@
|
|||||||
"@alexaltea/capstone-js": "^3.0.5",
|
"@alexaltea/capstone-js": "^3.0.5",
|
||||||
"@astronautlabs/amf": "^0.0.6",
|
"@astronautlabs/amf": "^0.0.6",
|
||||||
"@blu3r4y/lzma": "^2.3.3",
|
"@blu3r4y/lzma": "^2.3.3",
|
||||||
|
"@noble/hashes": "2.2.0",
|
||||||
"@wavesenterprise/crypto-gost-js": "^2.1.0-RC1",
|
"@wavesenterprise/crypto-gost-js": "^2.1.0-RC1",
|
||||||
"@xmldom/xmldom": "^0.8.13",
|
"@xmldom/xmldom": "^0.8.13",
|
||||||
"argon2-browser": "^1.18.0",
|
"argon2-browser": "^1.18.0",
|
||||||
"arrive": "^2.5.3",
|
"arrive": "^2.5.3",
|
||||||
"assert": "^2.1.0",
|
"assert": "^2.1.0",
|
||||||
"avsc": "^5.7.9",
|
"avsc": "^5.7.9",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^3.0.3",
|
||||||
"bignumber.js": "^9.3.1",
|
"bignumber.js": "^9.3.1",
|
||||||
"@noble/hashes": "2.2.0",
|
|
||||||
"blakejs": "^1.2.1",
|
"blakejs": "^1.2.1",
|
||||||
"bootstrap": "4.6.2",
|
"bootstrap": "4.6.2",
|
||||||
"bootstrap-colorpicker": "^3.4.0",
|
"bootstrap-colorpicker": "^3.4.0",
|
||||||
@ -122,7 +123,7 @@
|
|||||||
"d3": "7.9.0",
|
"d3": "7.9.0",
|
||||||
"d3-hexbin": "^0.2.2",
|
"d3-hexbin": "^0.2.2",
|
||||||
"diff": "^5.2.2",
|
"diff": "^5.2.2",
|
||||||
"dompurify": "^3.4.1",
|
"dompurify": "^3.4.3",
|
||||||
"es6-promisify": "^7.0.0",
|
"es6-promisify": "^7.0.0",
|
||||||
"escodegen": "^2.1.0",
|
"escodegen": "^2.1.0",
|
||||||
"esprima": "^4.0.1",
|
"esprima": "^4.0.1",
|
||||||
@ -156,7 +157,7 @@
|
|||||||
"lz4js": "^0.2.0",
|
"lz4js": "^0.2.0",
|
||||||
"markdown-it": "^14.1.1",
|
"markdown-it": "^14.1.1",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"moment-timezone": "^0.6.1",
|
"moment-timezone": "^0.6.2",
|
||||||
"ngeohash": "^0.6.3",
|
"ngeohash": "^0.6.3",
|
||||||
"node-forge": "^1.4.0",
|
"node-forge": "^1.4.0",
|
||||||
"node-md6": "^0.1.0",
|
"node-md6": "^0.1.0",
|
||||||
@ -168,7 +169,7 @@
|
|||||||
"path": "^0.12.7",
|
"path": "^0.12.7",
|
||||||
"popper.js": "^1.16.1",
|
"popper.js": "^1.16.1",
|
||||||
"process": "^0.11.10",
|
"process": "^0.11.10",
|
||||||
"protobufjs": "^7.5.5",
|
"protobufjs": "^7.5.8",
|
||||||
"punycode.js": "^2.3.1",
|
"punycode.js": "^2.3.1",
|
||||||
"qr-image": "^3.2.0",
|
"qr-image": "^3.2.0",
|
||||||
"reflect-metadata": "^0.2.2",
|
"reflect-metadata": "^0.2.2",
|
||||||
@ -177,7 +178,7 @@
|
|||||||
"snackbarjs": "^1.1.0",
|
"snackbarjs": "^1.1.0",
|
||||||
"sortablejs": "^1.15.7",
|
"sortablejs": "^1.15.7",
|
||||||
"split.js": "^1.6.5",
|
"split.js": "^1.6.5",
|
||||||
"sql-formatter": "^15.7.3",
|
"sql-formatter": "^15.7.4",
|
||||||
"ssdeep.js": "0.0.3",
|
"ssdeep.js": "0.0.3",
|
||||||
"stream-browserify": "^3.0.0",
|
"stream-browserify": "^3.0.0",
|
||||||
"tesseract.js": "^6.0.1",
|
"tesseract.js": "^6.0.1",
|
||||||
@ -185,7 +186,7 @@
|
|||||||
"unorm": "^1.6.0",
|
"unorm": "^1.6.0",
|
||||||
"url": "^0.11.4",
|
"url": "^0.11.4",
|
||||||
"utf8": "^3.0.0",
|
"utf8": "^3.0.0",
|
||||||
"uuid": "^13.0.0",
|
"uuid": "^14.0.0",
|
||||||
"vkbeautify": "^0.99.3",
|
"vkbeautify": "^0.99.3",
|
||||||
"xpath": "0.0.34",
|
"xpath": "0.0.34",
|
||||||
"xregexp": "^5.1.2",
|
"xregexp": "^5.1.2",
|
||||||
|
|||||||
@ -348,6 +348,7 @@
|
|||||||
"Pseudo-Random Number Generator",
|
"Pseudo-Random Number Generator",
|
||||||
"Sleep",
|
"Sleep",
|
||||||
"File Tree",
|
"File Tree",
|
||||||
|
"Wrap",
|
||||||
"Take nth bytes",
|
"Take nth bytes",
|
||||||
"Drop nth bytes"
|
"Drop nth bytes"
|
||||||
]
|
]
|
||||||
|
|||||||
@ -43,7 +43,7 @@ class Bcrypt extends Operation {
|
|||||||
const rounds = args[0];
|
const rounds = args[0];
|
||||||
const salt = await bcrypt.genSalt(rounds);
|
const salt = await bcrypt.genSalt(rounds);
|
||||||
|
|
||||||
return await bcrypt.hash(input, salt, null, p => {
|
return await bcrypt.hash(input, salt, undefined, p => {
|
||||||
// Progress callback
|
// Progress callback
|
||||||
if (isWorkerEnvironment())
|
if (isWorkerEnvironment())
|
||||||
self.sendStatusMessage(`Progress: ${(p * 100).toFixed(0)}%`);
|
self.sendStatusMessage(`Progress: ${(p * 100).toFixed(0)}%`);
|
||||||
|
|||||||
@ -43,7 +43,7 @@ class BcryptCompare extends Operation {
|
|||||||
async run(input, args) {
|
async run(input, args) {
|
||||||
const hash = args[0];
|
const hash = args[0];
|
||||||
|
|
||||||
const match = await bcrypt.compare(input, hash, null, p => {
|
const match = await bcrypt.compare(input, hash, undefined, p => {
|
||||||
// Progress callback
|
// Progress callback
|
||||||
if (isWorkerEnvironment())
|
if (isWorkerEnvironment())
|
||||||
self.sendStatusMessage(`Progress: ${(p * 100).toFixed(0)}%`);
|
self.sendStatusMessage(`Progress: ${(p * 100).toFixed(0)}%`);
|
||||||
|
|||||||
@ -92,7 +92,7 @@ class ParseEthernetFrame extends Operation {
|
|||||||
const packetData = input.slice(offset);
|
const packetData = input.slice(offset);
|
||||||
|
|
||||||
if (outputFormat === "Packet data") {
|
if (outputFormat === "Packet data") {
|
||||||
return Utils.byteArrayToChars(packetData);
|
return Utils.escapeHtml(Utils.byteArrayToChars(packetData));
|
||||||
} else if (outputFormat === "Packet data (hex)") {
|
} else if (outputFormat === "Packet data (hex)") {
|
||||||
return toHex(packetData);
|
return toHex(packetData);
|
||||||
} else if (outputFormat === "Text output") {
|
} else if (outputFormat === "Text output") {
|
||||||
|
|||||||
@ -138,7 +138,7 @@ class ParseIPv4Header extends Operation {
|
|||||||
} else if (outputFormat === "Data (hex)") {
|
} else if (outputFormat === "Data (hex)") {
|
||||||
return toHex(data);
|
return toHex(data);
|
||||||
} else if (outputFormat === "Data (raw)") {
|
} else if (outputFormat === "Data (raw)") {
|
||||||
return Utils.byteArrayToChars(data);
|
return Utils.escapeHtml(Utils.byteArrayToChars(data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,20 @@ import Utils from "../Utils.mjs";
|
|||||||
const d3 = d3temp.default ? d3temp.default : d3temp;
|
const d3 = d3temp.default ? d3temp.default : d3temp;
|
||||||
const nodom = nodomtemp.default ? nodomtemp.default: nodomtemp;
|
const nodom = nodomtemp.default ? nodomtemp.default: nodomtemp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes D3's internal bound data from a nodom tree before serialization.
|
||||||
|
* nodom serializes enumerable expando properties such as __data__ as attributes,
|
||||||
|
* so leaving them on attacker-controlled values can create executable markup.
|
||||||
|
*
|
||||||
|
* @param {Object} node
|
||||||
|
*/
|
||||||
|
function clearD3BoundData(node) {
|
||||||
|
delete node.__data__;
|
||||||
|
|
||||||
|
if (!node.childNodes) return;
|
||||||
|
node.childNodes.forEach(clearD3BoundData);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Series chart operation
|
* Series chart operation
|
||||||
*/
|
*/
|
||||||
@ -222,6 +236,8 @@ class SeriesChart extends Operation {
|
|||||||
.text(serie.name);
|
.text(serie.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
clearD3BoundData(svg.node());
|
||||||
|
|
||||||
return svg._groups[0][0].outerHTML;
|
return svg._groups[0][0].outerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
47
src/core/operations/Wrap.mjs
Normal file
47
src/core/operations/Wrap.mjs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* @author 0xff1ce [github.com/0xff1ce]
|
||||||
|
* @copyright Crown Copyright 2024
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation.mjs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap operation
|
||||||
|
*/
|
||||||
|
class Wrap extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Wrap";
|
||||||
|
this.module = "Default";
|
||||||
|
this.description = "Wraps the input text at a specified number of characters per line.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Line Width",
|
||||||
|
"type": "number",
|
||||||
|
"value": 64,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
if (!input) return ""; // Handle empty input
|
||||||
|
const lineWidth = args[0];
|
||||||
|
const regex = new RegExp(`.{1,${lineWidth}}`, "g");
|
||||||
|
return input.match(regex).join("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Wrap;
|
||||||
@ -64,7 +64,7 @@ module.exports = {
|
|||||||
testOp(browser, "BSON serialise", '{"a":"test"}', "\u0011\u0000\u0000\u0000\u0002a\u0000\u0005\u0000\u0000\u0000test\u0000\u0000");
|
testOp(browser, "BSON serialise", '{"a":"test"}', "\u0011\u0000\u0000\u0000\u0002a\u0000\u0005\u0000\u0000\u0000test\u0000\u0000");
|
||||||
// testOp(browser, "Bacon Cipher Decode", "test input", "test_output");
|
// testOp(browser, "Bacon Cipher Decode", "test input", "test_output");
|
||||||
// testOp(browser, "Bacon Cipher Encode", "test input", "test_output");
|
// testOp(browser, "Bacon Cipher Encode", "test input", "test_output");
|
||||||
testOp(browser, "Bcrypt", "test input", /^\$2a\$06\$.{53}$/, [6]);
|
testOp(browser, "Bcrypt", "test input", /^\$2b\$06\$.{53}$/, [6]);
|
||||||
testOp(browser, "Bcrypt compare", "test input", "Match: test input", ["$2a$05$FCfBSVX7OeRkK.9kQVFCiOYu9XtwtIbePqUiroD1lkASW9q5QClzG"]);
|
testOp(browser, "Bcrypt compare", "test input", "Match: test input", ["$2a$05$FCfBSVX7OeRkK.9kQVFCiOYu9XtwtIbePqUiroD1lkASW9q5QClzG"]);
|
||||||
testOp(browser, "Bcrypt parse", "$2a$05$kXWtAIGB/R8VEzInoM5ocOTBtyc0m2YTIwFiBU/0XoW032f9QrkWW", /Rounds: 5/);
|
testOp(browser, "Bcrypt parse", "$2a$05$kXWtAIGB/R8VEzInoM5ocOTBtyc0m2YTIwFiBU/0XoW032f9QrkWW", /Rounds: 5/);
|
||||||
testOp(browser, "Bifid Cipher Decode", "qblb tfovy", "test input", ["pass"]);
|
testOp(browser, "Bifid Cipher Decode", "qblb tfovy", "test input", ["pass"]);
|
||||||
|
|||||||
@ -136,8 +136,8 @@ Tiger-128`;
|
|||||||
it("Bcrypt", async () => {
|
it("Bcrypt", async () => {
|
||||||
const result = await chef.bcrypt("Put a Sock In It");
|
const result = await chef.bcrypt("Put a Sock In It");
|
||||||
const strResult = result.toString();
|
const strResult = result.toString();
|
||||||
assert.equal(strResult.length, 60);
|
assert.match(strResult, /^\$2b\$10\$[./A-Za-z0-9]{53}$/);
|
||||||
assert.equal(strResult.slice(0, 7), "$2a$10$");
|
assert.equal(strResult.split("$").length, 4);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
it("bcryptCompare", async() => {
|
it("bcryptCompare", async() => {
|
||||||
|
|||||||
@ -126,6 +126,7 @@ import "./tests/NormaliseUnicode.mjs";
|
|||||||
import "./tests/NTLM.mjs";
|
import "./tests/NTLM.mjs";
|
||||||
import "./tests/OTP.mjs";
|
import "./tests/OTP.mjs";
|
||||||
import "./tests/ParseEthernetFrame.mjs";
|
import "./tests/ParseEthernetFrame.mjs";
|
||||||
|
import "./tests/ParseIPv4Header.mjs";
|
||||||
import "./tests/ParseIPRange.mjs";
|
import "./tests/ParseIPRange.mjs";
|
||||||
import "./tests/ParseObjectIDTimestamp.mjs";
|
import "./tests/ParseObjectIDTimestamp.mjs";
|
||||||
import "./tests/ParseQRCode.mjs";
|
import "./tests/ParseQRCode.mjs";
|
||||||
@ -181,6 +182,7 @@ import "./tests/TranslateDateTimeFormat.mjs";
|
|||||||
import "./tests/Typex.mjs";
|
import "./tests/Typex.mjs";
|
||||||
import "./tests/UnescapeString.mjs";
|
import "./tests/UnescapeString.mjs";
|
||||||
import "./tests/Unicode.mjs";
|
import "./tests/Unicode.mjs";
|
||||||
|
import "./tests/Wrap.mjs";
|
||||||
import "./tests/URLEncodeDecode.mjs";
|
import "./tests/URLEncodeDecode.mjs";
|
||||||
import "./tests/RSA.mjs";
|
import "./tests/RSA.mjs";
|
||||||
import "./tests/CBOREncode.mjs";
|
import "./tests/CBOREncode.mjs";
|
||||||
|
|||||||
@ -41,6 +41,17 @@ TestRegister.addTests([
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Series chart escapes x-axis values in serialized SVG",
|
||||||
|
input: `s,x"><script>globalThis.seriesChartInjected=1</script><g a=",1`,
|
||||||
|
unexpectedMatch: /<script>|__data__=/,
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Series chart",
|
||||||
|
"args": ["Line feed", "Comma", "", 1, "red"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "Heatmap chart",
|
name: "Heatmap chart",
|
||||||
input: "100 100\n200 200\n300 300\n400 400\n500 500",
|
input: "100 100\n200 200\n300 300\n400 400\n500 500",
|
||||||
|
|||||||
@ -41,5 +41,16 @@ TestRegister.addTests([
|
|||||||
"args": ["Hex", "Text output"]
|
"args": ["Hex", "Text output"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Parse Ethernet frame escapes packet data HTML",
|
||||||
|
input: "000000000000ffffffffffff08003c696d67207372633d78206f6e6572726f723d616c6572742831293e3c7363726970743e616c6572742832293c2f7363726970743e",
|
||||||
|
expectedOutput: "<img src=x onerror=alert(1)><script>alert(2)</script>",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Parse Ethernet frame",
|
||||||
|
"args": ["Hex", "Packet data"]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|||||||
23
tests/operations/tests/ParseIPv4Header.mjs
Normal file
23
tests/operations/tests/ParseIPv4Header.mjs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Parse IPv4 header tests.
|
||||||
|
*
|
||||||
|
* @author C85297 [95289555+C85297@users.noreply.github.com]
|
||||||
|
* @copyright Crown Copyright 2026
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import TestRegister from "../../lib/TestRegister.mjs";
|
||||||
|
|
||||||
|
TestRegister.addTests([
|
||||||
|
{
|
||||||
|
name: "Parse IPv4 header: Correctly formatted HTML output",
|
||||||
|
input: "45 00 00 3c 1c 46 40 00 40 06 b1 e6 c0 a8 00 01 c0 a8 00 02 3c 73 63 72 69 70 74 3e 61 6c 65 72 74 28 31 33 33 37 29 3c 2f 73 63 72 69 70 74 3e",
|
||||||
|
expectedOutput: "<script>alert(1337)</script>",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Parse IPv4 header",
|
||||||
|
args: ["Hex", "Data (raw)"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]);
|
||||||
44
tests/operations/tests/Wrap.mjs
Normal file
44
tests/operations/tests/Wrap.mjs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* @author 0xff1ce [github.com/0xff1ce]
|
||||||
|
* @copyright Crown Copyright 2024
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import TestRegister from "../../lib/TestRegister.mjs";
|
||||||
|
|
||||||
|
TestRegister.addTests([
|
||||||
|
// Add tests specific to the Wrap operation
|
||||||
|
{
|
||||||
|
name: "Wrap text at 64 characters",
|
||||||
|
input: "A".repeat(128), // Generate an input string of 128 'A' characters
|
||||||
|
expectedOutput: "A".repeat(64) + "\n" + "A".repeat(64), // Expected output with a line break after 64 characters
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Wrap",
|
||||||
|
"args": [64]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Wrap text at 32 characters",
|
||||||
|
input: "B".repeat(96), // Generate an input string of 96 'B' characters
|
||||||
|
expectedOutput: "B".repeat(32) + "\n" + "B".repeat(32) + "\n" + "B".repeat(32), // Expected output with line breaks after every 32 characters
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Wrap",
|
||||||
|
"args": [32]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Wrap text at 10 characters",
|
||||||
|
input: "1234567890".repeat(10), // Generate an input string by repeating '1234567890'
|
||||||
|
expectedOutput: Array(10).fill("1234567890").join("\n"), // Expected output with line breaks every 10 characters
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Wrap",
|
||||||
|
"args": [10]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
]);
|
||||||
Loading…
x
Reference in New Issue
Block a user