From 18d681397ebe1378da3a2dba7a72c594f7ac258b Mon Sep 17 00:00:00 2001 From: Nat Dean-Lewis <94526761+natdeanlewissoftwire@users.noreply.github.com> Date: Wed, 17 Jun 2026 09:44:54 +0100 Subject: [PATCH 01/10] CLDC-4473: Add pipeline steps for SBOM tracking and upload (#3351) * feat: add sbom pipeline step using dependency-track skill * Potential fix for pull request finding 'CodeQL / Workflow does not contain permissions' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * Potential fix for pull request finding 'CodeQL / Workflow does not contain permissions' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .claude/settings.json | 5 +++ .github/workflows/production_pipeline.yml | 11 +++++ .github/workflows/staging_pipeline.yml | 9 ++++ .github/workflows/upload-sbom.yml | 52 +++++++++++++++++++++++ 4 files changed, 77 insertions(+) create mode 100644 .claude/settings.json create mode 100644 .github/workflows/upload-sbom.yml diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 000000000..f292eeaab --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,5 @@ +{ + "enabledPlugins": { + "dependency-track@skillwire": true + } +} diff --git a/.github/workflows/production_pipeline.yml b/.github/workflows/production_pipeline.yml index 45a31167f..6fc1c3b96 100644 --- a/.github/workflows/production_pipeline.yml +++ b/.github/workflows/production_pipeline.yml @@ -20,3 +20,14 @@ jobs: release_tag: ${{ needs.test.outputs.releasetag }} permissions: id-token: write + + sbom: + name: Upload SBOM + needs: [aws_deploy] + permissions: + contents: read + uses: ./.github/workflows/upload-sbom.yml + with: + projectversion: prod + secrets: + DTRACK_API_KEY: ${{ secrets.DTRACK_API_KEY }} diff --git a/.github/workflows/staging_pipeline.yml b/.github/workflows/staging_pipeline.yml index a2e777db0..9187142d3 100644 --- a/.github/workflows/staging_pipeline.yml +++ b/.github/workflows/staging_pipeline.yml @@ -32,6 +32,15 @@ jobs: permissions: id-token: write + sbom: + name: Upload SBOM + needs: [aws_deploy] + uses: ./.github/workflows/upload-sbom.yml + with: + projectversion: staging + secrets: + DTRACK_API_KEY: ${{ secrets.DTRACK_API_KEY }} + performance: needs: [aws_deploy] runs-on: ubuntu-latest diff --git a/.github/workflows/upload-sbom.yml b/.github/workflows/upload-sbom.yml new file mode 100644 index 000000000..f1c02a0ec --- /dev/null +++ b/.github/workflows/upload-sbom.yml @@ -0,0 +1,52 @@ +name: Upload SBOM + +# Generates a CycloneDX SBOM with Syft (auto-detects both the Ruby gems in +# Gemfile.lock and the Node packages in yarn.lock) and uploads it to +# Dependency-Track. Called from the staging and production pipelines after a +# successful deploy. + +on: + workflow_call: + inputs: + projectversion: + required: true + type: string + secrets: + DTRACK_API_KEY: + required: true + +permissions: + contents: read + +jobs: + sbom: + name: Generate and upload SBOM + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - run: | + echo "SYFT_VERSION=v1.45.0" >> "$GITHUB_ENV" + echo "SYFT_SCRIPT_SHA=9673f867e50398b5d25ec97ff051a451c46d262c" >> "$GITHUB_ENV" + + - uses: actions/cache@v4 + with: + path: /usr/local/bin/syft + key: syft-${{ env.SYFT_VERSION }} + + - name: Install Syft + run: | + [ -f /usr/local/bin/syft ] || \ + curl -sSfL "https://raw.githubusercontent.com/anchore/syft/${SYFT_SCRIPT_SHA}/install.sh" | sh -s -- -b /usr/local/bin "$SYFT_VERSION" + + - run: syft . -o cyclonedx-xml=bom.xml + + - uses: DependencyTrack/gh-upload-sbom@v3 + with: + serverhostname: api-deps.softwire.com + apikey: ${{ secrets.DTRACK_API_KEY }} + autocreate: true + projectname: CORE + projectversion: ${{ inputs.projectversion }} + parentname: Support + bomfilename: bom.xml From 7725de440cf71aa914e33e1aa6989779e0a369ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jun 2026 10:10:39 +0100 Subject: [PATCH 02/10] Bump @babel/core from 7.25.2 to 7.29.6 (#3355) Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.25.2 to 7.29.6. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.29.6/packages/babel-core) --- updated-dependencies: - dependency-name: "@babel/core" dependency-version: 7.29.6 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 315 ++++++++++++++------------------------------------- 2 files changed, 87 insertions(+), 230 deletions(-) diff --git a/package.json b/package.json index 564ffc371..fd9870c6b 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "node": "^24.0.0" }, "dependencies": { - "@babel/core": "^7.17.7", + "@babel/core": "^7.29.6", "@babel/plugin-transform-runtime": "^7.17.0", "@babel/preset-env": "^7.16.11", "@hotwired/stimulus": "^3.0.0", diff --git a/yarn.lock b/yarn.lock index cabcb7043..0072e89e0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,32 +2,7 @@ # yarn lockfile v1 -"@ampproject/remapping@^2.2.0": - version "2.3.0" - resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz" - integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== - dependencies: - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.24" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz" - integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== - dependencies: - "@babel/highlight" "^7.24.7" - picocolors "^1.0.0" - -"@babel/code-frame@^7.26.2": - version "7.26.2" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz" - integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ== - dependencies: - "@babel/helper-validator-identifier" "^7.25.9" - js-tokens "^4.0.0" - picocolors "^1.0.0" - -"@babel/code-frame@^7.29.7": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.29.0", "@babel/code-frame@^7.29.7": version "7.29.7" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.7.tgz#f2fbbfea87c44a21590ec515b778b2c26d8866e7" integrity sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw== @@ -41,38 +16,33 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz" integrity sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ== -"@babel/core@^7.17.7": - version "7.25.2" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz" - integrity sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.24.7" - "@babel/generator" "^7.25.0" - "@babel/helper-compilation-targets" "^7.25.2" - "@babel/helper-module-transforms" "^7.25.2" - "@babel/helpers" "^7.25.0" - "@babel/parser" "^7.25.0" - "@babel/template" "^7.25.0" - "@babel/traverse" "^7.25.2" - "@babel/types" "^7.25.2" +"@babel/compat-data@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.7.tgz#6f0237f0f36d2e51c0570a636faed9d2d0efe629" + integrity sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg== + +"@babel/core@^7.29.6": + version "7.29.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.29.6.tgz#2f2c2ca1728ae73c9b68ece91d1ae6dee18ff83a" + integrity sha512-QdxmAo/ikZqqRGA8s43ww8lcql6naWRvEz0FFrl6MIlc7Gi6TroXnSdWa5U/kq6fzcpqpHesicQxFZIieZbyIA== + dependencies: + "@babel/code-frame" "^7.29.0" + "@babel/generator" "^7.29.6" + "@babel/helper-compilation-targets" "^7.28.6" + "@babel/helper-module-transforms" "^7.28.6" + "@babel/helpers" "^7.29.2" + "@babel/parser" "^7.29.3" + "@babel/template" "^7.28.6" + "@babel/traverse" "^7.29.0" + "@babel/types" "^7.29.0" + "@jridgewell/remapping" "^2.3.5" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.25.0": - version "7.25.0" - resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz" - integrity sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw== - dependencies: - "@babel/types" "^7.25.0" - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.25" - jsesc "^2.5.1" - -"@babel/generator@^7.29.7": +"@babel/generator@^7.29.6", "@babel/generator@^7.29.7": version "7.29.7" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.7.tgz#cca0b8827e6bcf3ba176788e7f3b180ad6db2fa3" integrity sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ== @@ -98,14 +68,14 @@ "@babel/traverse" "^7.24.7" "@babel/types" "^7.24.7" -"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.24.7", "@babel/helper-compilation-targets@^7.24.8", "@babel/helper-compilation-targets@^7.25.2": - version "7.25.2" - resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz" - integrity sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw== +"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.24.7", "@babel/helper-compilation-targets@^7.24.8", "@babel/helper-compilation-targets@^7.25.2", "@babel/helper-compilation-targets@^7.28.6": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz#7a1def704302401c47f64fa85589e974ae217042" + integrity sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g== dependencies: - "@babel/compat-data" "^7.25.2" - "@babel/helper-validator-option" "^7.24.8" - browserslist "^4.23.1" + "@babel/compat-data" "^7.29.7" + "@babel/helper-validator-option" "^7.29.7" + browserslist "^4.24.0" lru-cache "^5.1.1" semver "^6.3.1" @@ -171,17 +141,7 @@ "@babel/traverse" "^7.29.7" "@babel/types" "^7.29.7" -"@babel/helper-module-transforms@^7.24.7", "@babel/helper-module-transforms@^7.24.8", "@babel/helper-module-transforms@^7.25.2": - version "7.25.2" - resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz" - integrity sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ== - dependencies: - "@babel/helper-module-imports" "^7.24.7" - "@babel/helper-simple-access" "^7.24.7" - "@babel/helper-validator-identifier" "^7.24.7" - "@babel/traverse" "^7.25.2" - -"@babel/helper-module-transforms@^7.29.7": +"@babel/helper-module-transforms@^7.24.7", "@babel/helper-module-transforms@^7.24.8", "@babel/helper-module-transforms@^7.28.6", "@babel/helper-module-transforms@^7.29.7": version "7.29.7" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz#b062747a5997ba138637201328bbff77960574ae" integrity sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg== @@ -241,31 +201,11 @@ "@babel/traverse" "^7.24.7" "@babel/types" "^7.24.7" -"@babel/helper-string-parser@^7.24.8": - version "7.24.8" - resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz" - integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== - -"@babel/helper-string-parser@^7.25.9": - version "7.25.9" - resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz" - integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== - "@babel/helper-string-parser@^7.29.7": version "7.29.7" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz#7f0871d99824d23137d60f86fcf6130fd5a1b51f" integrity sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw== -"@babel/helper-validator-identifier@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz" - integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== - -"@babel/helper-validator-identifier@^7.25.9": - version "7.25.9" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz" - integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== - "@babel/helper-validator-identifier@^7.29.7": version "7.29.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz#bd87084ced0c796ec46bda492de6e83d29e89fc2" @@ -276,6 +216,11 @@ resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz" integrity sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q== +"@babel/helper-validator-option@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz#cf315be940213b354eb4abcc0bd01ebe3f73bc2a" + integrity sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw== + "@babel/helper-wrap-function@^7.25.0": version "7.25.0" resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz" @@ -285,39 +230,15 @@ "@babel/traverse" "^7.25.0" "@babel/types" "^7.25.0" -"@babel/helpers@^7.25.0": - version "7.26.10" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz" - integrity sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g== - dependencies: - "@babel/template" "^7.26.9" - "@babel/types" "^7.26.10" - -"@babel/highlight@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz" - integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== - dependencies: - "@babel/helper-validator-identifier" "^7.24.7" - chalk "^2.4.2" - js-tokens "^4.0.0" - picocolors "^1.0.0" - -"@babel/parser@^7.25.0", "@babel/parser@^7.25.3": - version "7.25.3" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz" - integrity sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw== - dependencies: - "@babel/types" "^7.25.2" - -"@babel/parser@^7.26.9": - version "7.26.10" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz" - integrity sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA== +"@babel/helpers@^7.29.2": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.29.7.tgz#45abfde7548997e34376c3e69feb475cffb4a607" + integrity sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg== dependencies: - "@babel/types" "^7.26.10" + "@babel/template" "^7.29.7" + "@babel/types" "^7.29.7" -"@babel/parser@^7.29.7": +"@babel/parser@^7.29.3", "@babel/parser@^7.29.7": version "7.29.7" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.7.tgz#837b87387cbf5ec5530cb634b3c622f68edb9334" integrity sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg== @@ -1010,25 +931,7 @@ dependencies: regenerator-runtime "^0.14.0" -"@babel/template@^7.24.7", "@babel/template@^7.25.0": - version "7.25.0" - resolved "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz" - integrity sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q== - dependencies: - "@babel/code-frame" "^7.24.7" - "@babel/parser" "^7.25.0" - "@babel/types" "^7.25.0" - -"@babel/template@^7.26.9": - version "7.26.9" - resolved "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz" - integrity sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA== - dependencies: - "@babel/code-frame" "^7.26.2" - "@babel/parser" "^7.26.9" - "@babel/types" "^7.26.9" - -"@babel/template@^7.29.7": +"@babel/template@^7.24.7", "@babel/template@^7.25.0", "@babel/template@^7.28.6", "@babel/template@^7.29.7": version "7.29.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.29.7.tgz#4d9d4004f645cdd304de958c725162784ecac700" integrity sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg== @@ -1037,20 +940,7 @@ "@babel/parser" "^7.29.7" "@babel/types" "^7.29.7" -"@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.25.0", "@babel/traverse@^7.25.1", "@babel/traverse@^7.25.2", "@babel/traverse@^7.25.3": - version "7.25.3" - resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz" - integrity sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ== - dependencies: - "@babel/code-frame" "^7.24.7" - "@babel/generator" "^7.25.0" - "@babel/parser" "^7.25.3" - "@babel/template" "^7.25.0" - "@babel/types" "^7.25.2" - debug "^4.3.1" - globals "^11.1.0" - -"@babel/traverse@^7.29.7": +"@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.25.0", "@babel/traverse@^7.25.1", "@babel/traverse@^7.25.3", "@babel/traverse@^7.29.0", "@babel/traverse@^7.29.7": version "7.29.7" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.7.tgz#c47b07a41b95da0907d026b5dd894d98de7d2f2d" integrity sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw== @@ -1063,24 +953,7 @@ "@babel/types" "^7.29.7" debug "^4.3.1" -"@babel/types@^7.24.7", "@babel/types@^7.24.8", "@babel/types@^7.25.0", "@babel/types@^7.25.2", "@babel/types@^7.4.4": - version "7.25.2" - resolved "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz" - integrity sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q== - dependencies: - "@babel/helper-string-parser" "^7.24.8" - "@babel/helper-validator-identifier" "^7.24.7" - to-fast-properties "^2.0.0" - -"@babel/types@^7.26.10", "@babel/types@^7.26.9": - version "7.26.10" - resolved "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz" - integrity sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ== - dependencies: - "@babel/helper-string-parser" "^7.25.9" - "@babel/helper-validator-identifier" "^7.25.9" - -"@babel/types@^7.29.7": +"@babel/types@^7.24.7", "@babel/types@^7.24.8", "@babel/types@^7.25.0", "@babel/types@^7.29.0", "@babel/types@^7.29.7", "@babel/types@^7.4.4": version "7.29.7" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.7.tgz#8005e31d82712ee7adaef6e23c63b71a62770a92" integrity sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA== @@ -1209,6 +1082,14 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.24" +"@jridgewell/remapping@^2.3.5": + version "2.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1" + integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + "@jridgewell/resolve-uri@^3.1.0": version "3.1.2" resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz" @@ -1604,13 +1485,6 @@ ansi-regex@^6.0.1: resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz" integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" @@ -1827,6 +1701,11 @@ balanced-match@^2.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz" integrity sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA== +baseline-browser-mapping@^2.10.12: + version "2.10.37" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.37.tgz#3e636475b6b293244e2b23e2c71a2ab9d9e6ba7d" + integrity sha512-girxaJ7WZssDOFhzCGZTDKoTa1gk6A1TbflaYTpykLJ4UU9Fz9kx1aREM8JCuoVHbL8X8T/mJg7w2oYSq72Oig== + baseline-browser-mapping@^2.9.0: version "2.9.19" resolved "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz" @@ -1862,7 +1741,7 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" -browserslist@^4.23.1, browserslist@^4.23.3, browserslist@^4.28.1: +browserslist@^4.23.3, browserslist@^4.28.1: version "4.28.1" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz" integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== @@ -1873,6 +1752,17 @@ browserslist@^4.23.1, browserslist@^4.23.3, browserslist@^4.28.1: node-releases "^2.0.27" update-browserslist-db "^1.2.0" +browserslist@^4.24.0: + version "4.28.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.2.tgz#f50b65362ef48974ca9f50b3680566d786b811d2" + integrity sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg== + dependencies: + baseline-browser-mapping "^2.10.12" + caniuse-lite "^1.0.30001782" + electron-to-chromium "^1.5.328" + node-releases "^2.0.36" + update-browserslist-db "^1.2.3" + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" @@ -1906,14 +1796,10 @@ caniuse-lite@^1.0.30001759: resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz" integrity sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg== -chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" +caniuse-lite@^1.0.30001782: + version "1.0.30001799" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz#5c909138c27f1a61219d3e092071c1cc7d32dc55" + integrity sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw== chalk@^4.0.0: version "4.1.2" @@ -1952,13 +1838,6 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - color-convert@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" @@ -1966,11 +1845,6 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - color-name@~1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" @@ -2202,6 +2076,11 @@ electron-to-chromium@^1.5.263: resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz" integrity sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A== +electron-to-chromium@^1.5.328: + version "1.5.375" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.375.tgz#54a9a616dc2b3765e7263d98d14c2135408954d9" + integrity sha512-ZWP5eB4BVPW/ZYo9252hQZHZ5XavtsTgpbhcmMmRwymavC5AsLWQWBPaKMeNd2LW0KGby5HPXvj7+sr4ta5j/Q== + element-closest@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/element-closest/-/element-closest-2.0.2.tgz" @@ -2368,11 +2247,6 @@ escalade@^3.2.0: resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz" integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" @@ -2979,11 +2853,6 @@ has-bigints@^1.0.1, has-bigints@^1.0.2: resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - has-flag@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" @@ -3379,11 +3248,6 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - jsesc@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" @@ -3669,6 +3533,11 @@ node-releases@^2.0.27: resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz" integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== +node-releases@^2.0.36: + version "2.0.47" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.47.tgz#521bb2786da8eb140b748841c0b3b3a75334ffc4" + integrity sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og== + normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" @@ -3859,7 +3728,7 @@ path-type@^4.0.0: resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -picocolors@^1.0.0, picocolors@^1.0.1: +picocolors@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz" integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== @@ -4597,13 +4466,6 @@ stylelint@^16.8.2: table "^6.8.2" write-file-atomic "^5.0.1" -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - supports-color@^7.0.0, supports-color@^7.1.0: version "7.2.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" @@ -4678,11 +4540,6 @@ text-table@^0.2.0: resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" @@ -4804,7 +4661,7 @@ unicode-property-aliases-ecmascript@^2.0.0: resolved "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz" integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== -update-browserslist-db@^1.2.0: +update-browserslist-db@^1.2.0, update-browserslist-db@^1.2.3: version "1.2.3" resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz" integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== From d805c39dea8b17fcfe0ffd39c2d10850d39e98ce Mon Sep 17 00:00:00 2001 From: Nat Dean-Lewis Date: Wed, 17 Jun 2026 10:31:39 +0100 Subject: [PATCH 03/10] CLDC-4473: upload sbom directly --- .github/workflows/upload-sbom.yml | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/.github/workflows/upload-sbom.yml b/.github/workflows/upload-sbom.yml index f1c02a0ec..da41affce 100644 --- a/.github/workflows/upload-sbom.yml +++ b/.github/workflows/upload-sbom.yml @@ -41,12 +41,15 @@ jobs: - run: syft . -o cyclonedx-xml=bom.xml - - uses: DependencyTrack/gh-upload-sbom@v3 - with: - serverhostname: api-deps.softwire.com - apikey: ${{ secrets.DTRACK_API_KEY }} - autocreate: true - projectname: CORE - projectversion: ${{ inputs.projectversion }} - parentname: Support - bomfilename: bom.xml + - name: Upload SBOM to Dependency-Track + env: + DTRACK_API_KEY: ${{ secrets.DTRACK_API_KEY }} + SBOM_VERSION: ${{ inputs.projectversion }} + run: | + curl -sSf -X POST "https://api-deps.softwire.com/api/v1/bom" \ + -H "X-Api-Key: $DTRACK_API_KEY" \ + -F "autoCreate=true" \ + -F "projectName=CORE" \ + -F "projectVersion=$SBOM_VERSION" \ + -F "parentName=Support" \ + -F "bom=@bom.xml" From 316943cfc0014085ba56744ca2b88c0c5ead09a6 Mon Sep 17 00:00:00 2001 From: Samuel Young Date: Thu, 18 Jun 2026 15:31:10 +0100 Subject: [PATCH 04/10] CLDC-4331: Make downloads traceable (#3313) * CLDC-4331: Add model for download records * CLDC-4331: Add a row to database on all download paths * fixup! CLDC-4331: Add model for download records improve comment * fixup! CLDC-4331: Add model for download records remove organisation type * CLDC-4331: Record kind of schemes download * fixup! CLDC-4331: Add model for download records fix scheme id mention location in name * fixup! fixup! CLDC-4331: Add model for download records * empty commit * CLDC-4331: run migration post-merge * CLDC-4331: update migration timestamp --------- Co-authored-by: Nat Dean-Lewis Co-authored-by: Nat Dean-Lewis <94526761+natdeanlewissoftwire@users.noreply.github.com> --- app/controllers/lettings_logs_controller.rb | 1 + app/controllers/organisations_controller.rb | 4 +++ app/controllers/sales_logs_controller.rb | 1 + app/controllers/schemes_controller.rb | 1 + app/controllers/users_controller.rb | 1 + app/models/download_record.rb | 25 +++++++++++++++++++ .../20260618101455_create_download_record.rb | 13 ++++++++++ db/schema.rb | 14 +++++++++++ 8 files changed, 60 insertions(+) create mode 100644 app/models/download_record.rb create mode 100644 db/migrate/20260618101455_create_download_record.rb diff --git a/app/controllers/lettings_logs_controller.rb b/app/controllers/lettings_logs_controller.rb index cd2a6ca5a..6f8efe28e 100644 --- a/app/controllers/lettings_logs_controller.rb +++ b/app/controllers/lettings_logs_controller.rb @@ -96,6 +96,7 @@ class LettingsLogsController < LogsController end def email_csv + DownloadRecord.build_from_user(download_type: :lettings_log, download_filters: session_filters.to_s, user: current_user).save! all_orgs = params["organisation_select"] == "all" EmailCsvJob.perform_later(current_user, search_term, session_filters, all_orgs, nil, codes_only_export?, "lettings", session_filters["years"].first.to_i) redirect_to csv_confirmation_lettings_logs_path diff --git a/app/controllers/organisations_controller.rb b/app/controllers/organisations_controller.rb index d4e4f34fc..a99c78dcf 100644 --- a/app/controllers/organisations_controller.rb +++ b/app/controllers/organisations_controller.rb @@ -40,6 +40,7 @@ class OrganisationsController < ApplicationController end def email_schemes_csv + DownloadRecord.build_from_user(download_type: :scheme_location, download_filters: session_filters.merge({ download_type: params[:download_type] }).to_s, user: current_user).save! SchemeEmailCsvJob.perform_later(current_user, search_term, session_filters, false, @organisation, params[:download_type]) redirect_to schemes_csv_confirmation_organisation_path end @@ -72,6 +73,7 @@ class OrganisationsController < ApplicationController end end format.csv do + DownloadRecord.build_from_user(download_type: :user, download_filters: session_filters.to_s, user: current_user).save! send_data byte_order_mark + unpaginated_filtered_users.to_csv, filename: "users-#{@organisation.name}-#{Time.zone.now}.csv" end end @@ -205,6 +207,7 @@ class OrganisationsController < ApplicationController end def email_lettings_csv + DownloadRecord.build_from_user(download_type: :lettings_log, download_filters: session_filters.to_s, user: current_user).save! EmailCsvJob.perform_later(current_user, search_term, session_filters, false, @organisation, codes_only_export?, "lettings", session_filters["years"].first.to_i) redirect_to lettings_logs_csv_confirmation_organisation_path end @@ -243,6 +246,7 @@ class OrganisationsController < ApplicationController end def email_sales_csv + DownloadRecord.build_from_user(download_type: :sales_log, download_filters: session_filters.to_s, user: current_user).save! EmailCsvJob.perform_later(current_user, search_term, session_filters, false, @organisation, codes_only_export?, "sales", session_filters["years"].first.to_i) redirect_to sales_logs_csv_confirmation_organisation_path end diff --git a/app/controllers/sales_logs_controller.rb b/app/controllers/sales_logs_controller.rb index 3c389ccf1..4e53e4f13 100644 --- a/app/controllers/sales_logs_controller.rb +++ b/app/controllers/sales_logs_controller.rb @@ -70,6 +70,7 @@ class SalesLogsController < LogsController end def email_csv + DownloadRecord.build_from_user(download_type: :sales_log, download_filters: session_filters.to_s, user: current_user).save! all_orgs = params["organisation_select"] == "all" EmailCsvJob.perform_later(current_user, search_term, session_filters, all_orgs, nil, codes_only_export?, "sales", session_filters["years"].first.to_i) redirect_to csv_confirmation_sales_logs_path diff --git a/app/controllers/schemes_controller.rb b/app/controllers/schemes_controller.rb index 4b018ee34..b5e796f72 100644 --- a/app/controllers/schemes_controller.rb +++ b/app/controllers/schemes_controller.rb @@ -236,6 +236,7 @@ class SchemesController < ApplicationController end def email_csv + DownloadRecord.build_from_user(download_type: :scheme_location, download_filters: session_filters.merge({ download_type: params[:download_type] }).to_s, user: current_user).save! all_orgs = params["organisation_select"] == "all" SchemeEmailCsvJob.perform_later(current_user, search_term, session_filters, all_orgs, nil, params[:download_type]) redirect_to csv_confirmation_schemes_path diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 677925679..c8ad4cb12 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -24,6 +24,7 @@ class UsersController < ApplicationController format.html format.csv do if current_user.support? + DownloadRecord.build_from_user(download_type: :user, download_filters: session_filters.to_s, user: current_user).save! send_data byte_order_mark + filtered_users.to_csv, filename: "users-#{Time.zone.now}.csv" else head :unauthorized diff --git a/app/models/download_record.rb b/app/models/download_record.rb new file mode 100644 index 000000000..09c8ee851 --- /dev/null +++ b/app/models/download_record.rb @@ -0,0 +1,25 @@ +# Used to allow for easier auditing of what users downloaded what info +# Caches some info about the user at the time of download +class DownloadRecord < ApplicationRecord + belongs_to :user + belongs_to :user_organisation, class_name: "Organisation" + + DOWNLOAD_TYPE = { + user: 0, + lettings_log: 1, + sales_log: 2, + scheme_location: 3, + }.freeze + + enum download_type: DOWNLOAD_TYPE + enum user_role: User::ROLES + + def self.build_from_user(user:, **attrs) + new( + user:, + user_organisation: user.organisation, + user_role: user.role, + **attrs, + ) + end +end diff --git a/db/migrate/20260618101455_create_download_record.rb b/db/migrate/20260618101455_create_download_record.rb new file mode 100644 index 000000000..4fbaffa06 --- /dev/null +++ b/db/migrate/20260618101455_create_download_record.rb @@ -0,0 +1,13 @@ +class CreateDownloadRecord < ActiveRecord::Migration[7.2] + def change + create_table :download_records do |t| + t.integer :download_type, null: false + t.string :download_filters, null: false + t.references :user, null: false, foreign_key: true + t.references :user_organisation, null: false, foreign_key: { to_table: :organisations } + t.integer :user_role, null: false + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 4af47a53f..07d725526 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -106,6 +106,18 @@ ActiveRecord::Schema[7.2].define(version: 2026_04_20_151627) do t.index ["organisation_id"], name: "index_data_protection_confirmations_on_organisation_id" end + create_table "download_records", force: :cascade do |t| + t.integer "download_type", null: false + t.string "download_filters", null: false + t.bigint "user_id", null: false + t.bigint "user_organisation_id", null: false + t.integer "user_role", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["user_id"], name: "index_download_records_on_user_id" + t.index ["user_organisation_id"], name: "index_download_records_on_user_organisation_id" + end + create_table "exports", force: :cascade do |t| t.datetime "created_at", default: -> { "CURRENT_TIMESTAMP" } t.datetime "started_at", null: false @@ -944,6 +956,8 @@ ActiveRecord::Schema[7.2].define(version: 2026_04_20_151627) do t.index ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id" end + add_foreign_key "download_records", "organisations", column: "user_organisation_id" + add_foreign_key "download_records", "users" add_foreign_key "lettings_logs", "locations" add_foreign_key "lettings_logs", "organisations", column: "owning_organisation_id", on_delete: :cascade add_foreign_key "lettings_logs", "schemes" From 3386e96bbcc5b37ce481f1c44e89be0a067814cc Mon Sep 17 00:00:00 2001 From: Nat Dean-Lewis Date: Mon, 22 Jun 2026 11:13:48 +0100 Subject: [PATCH 05/10] CLDC-4331: update schema --- db/schema.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 07d725526..5f73c8068 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.2].define(version: 2026_04_20_151627) do +ActiveRecord::Schema[7.2].define(version: 2026_06_18_101455) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -837,9 +837,6 @@ ActiveRecord::Schema[7.2].define(version: 2026_04_20_151627) do t.string "sexrab5" t.string "sexrab6" t.integer "buildheightclass" - t.integer "mortlen_known" - t.integer "hasservicechargeschanged" - t.decimal "newservicecharges", precision: 10, scale: 2 t.integer "gender_same_as_sex1" t.integer "gender_same_as_sex2" t.integer "gender_same_as_sex3" @@ -852,6 +849,9 @@ ActiveRecord::Schema[7.2].define(version: 2026_04_20_151627) do t.string "gender_description4" t.string "gender_description5" t.string "gender_description6" + t.integer "mortlen_known" + t.integer "hasservicechargeschanged" + t.decimal "newservicecharges", precision: 10, scale: 2 t.index ["assigned_to_id"], name: "index_sales_logs_on_assigned_to_id" t.index ["bulk_upload_id"], name: "index_sales_logs_on_bulk_upload_id" t.index ["created_by_id"], name: "index_sales_logs_on_created_by_id" From 2977ef7aaee1d2e31c703d315fd3bfb607bcd169 Mon Sep 17 00:00:00 2001 From: Nat Dean-Lewis <94526761+natdeanlewissoftwire@users.noreply.github.com> Date: Tue, 23 Jun 2026 09:23:17 +0100 Subject: [PATCH 06/10] CLDC-NONE: update excon (#3356) * CLDC-NONE: update excon * CLDC-NONE: update nokogiri --- Gemfile | 2 +- Gemfile.lock | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index 0e5be060d..1e5cdfc3e 100644 --- a/Gemfile +++ b/Gemfile @@ -119,7 +119,7 @@ end gem "cssbundling-rails" gem "tzinfo-data", platforms: %i[mingw mswin x64_mingw jruby] -gem "excon", "~> 0.111.0" +gem "excon", ">= 1.5.0" # faraday is a transitive dependency, but we need to force the version to 2.14.1 to avoid a vulnerability. gem "faraday", ">= 2.14.1" diff --git a/Gemfile.lock b/Gemfile.lock index da3fe1c1f..cc5db7e08 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -202,7 +202,8 @@ GEM et-orbi (1.4.0) tzinfo event_stream_parser (1.0.0) - excon (0.111.0) + excon (1.5.0) + logger factory_bot (6.5.0) activesupport (>= 5.0.0) factory_bot_rails (6.4.4) @@ -305,13 +306,13 @@ GEM net-smtp (0.5.1) net-protocol nio4r (2.7.5) - nokogiri (1.19.3-arm64-darwin) + nokogiri (1.19.4-arm64-darwin) racc (~> 1.4) - nokogiri (1.19.3-x86_64-darwin) + nokogiri (1.19.4-x86_64-darwin) racc (~> 1.4) - nokogiri (1.19.3-x86_64-linux-gnu) + nokogiri (1.19.4-x86_64-linux-gnu) racc (~> 1.4) - nokogiri (1.19.3-x86_64-linux-musl) + nokogiri (1.19.4-x86_64-linux-musl) racc (~> 1.4) notifications-ruby-client (6.4.0) jwt (>= 1.5, < 4) @@ -600,7 +601,7 @@ DEPENDENCIES devise_two_factor_authentication dotenv-rails erb_lint - excon (~> 0.111.0) + excon (>= 1.5.0) factory_bot_rails faker faraday (>= 2.14.1) From 868ac594f40b087b45425bfd7e83a0aa9907d019 Mon Sep 17 00:00:00 2001 From: Nat Dean-Lewis Date: Tue, 23 Jun 2026 09:36:35 +0100 Subject: [PATCH 07/10] CLDC-NONE: update concurrent-ruby and faraday --- Gemfile | 4 ++-- Gemfile.lock | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 1e5cdfc3e..21382e178 100644 --- a/Gemfile +++ b/Gemfile @@ -121,5 +121,5 @@ gem "tzinfo-data", platforms: %i[mingw mswin x64_mingw jruby] gem "excon", ">= 1.5.0" -# faraday is a transitive dependency, but we need to force the version to 2.14.1 to avoid a vulnerability. -gem "faraday", ">= 2.14.1" +# faraday is a transitive dependency, but we need to force the version to 2.14.3 to avoid a vulnerability. +gem "faraday", ">= 2.14.3" diff --git a/Gemfile.lock b/Gemfile.lock index cc5db7e08..50a5882fb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -154,7 +154,7 @@ GEM coderay (1.1.3) coercible (1.0.0) descendants_tracker (~> 0.0.1) - concurrent-ruby (1.3.6) + concurrent-ruby (1.3.7) connection_pool (2.5.5) crack (1.0.0) bigdecimal @@ -211,7 +211,7 @@ GEM railties (>= 5.0.0) faker (3.2.3) i18n (>= 1.8.11, < 2) - faraday (2.14.2) + faraday (2.14.3) faraday-net_http (>= 2.0, < 3.5) json logger @@ -604,7 +604,7 @@ DEPENDENCIES excon (>= 1.5.0) factory_bot_rails faker - faraday (>= 2.14.1) + faraday (>= 2.14.3) govuk-components (~> 6.2) govuk_design_system_formbuilder (~> 5.7) govuk_markdown From c2a8fde6740cbbfd74f29cf054033bbf7bdc4bfb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jun 2026 08:46:16 +0000 Subject: [PATCH 08/10] Bump faraday from 2.14.2 to 2.14.3 in /docs (#3358) Bumps [faraday](https://github.com/lostisland/faraday) from 2.14.2 to 2.14.3. - [Release notes](https://github.com/lostisland/faraday/releases) - [Changelog](https://github.com/lostisland/faraday/blob/main/CHANGELOG.md) - [Commits](https://github.com/lostisland/faraday/compare/v2.14.2...v2.14.3) --- updated-dependencies: - dependency-name: faraday dependency-version: 2.14.3 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Nat Dean-Lewis <94526761+natdeanlewissoftwire@users.noreply.github.com> --- docs/Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 0bce82170..f7a89e79c 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -37,7 +37,7 @@ GEM ffi (>= 1.15.0) eventmachine (1.2.7) execjs (2.8.1) - faraday (2.14.2) + faraday (2.14.3) faraday-net_http (>= 2.0, < 3.5) json logger @@ -211,7 +211,7 @@ GEM gemoji (~> 3.0) html-pipeline (~> 2.2) jekyll (>= 3.0, < 5.0) - json (2.19.8) + json (2.19.9) kramdown (2.3.2) rexml kramdown-parser-gfm (1.1.0) From ce0a925df473504d221f91ffc7579574bc444d47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jun 2026 08:46:22 +0000 Subject: [PATCH 09/10] Bump concurrent-ruby from 1.3.6 to 1.3.7 in /docs (#3359) Bumps [concurrent-ruby](https://github.com/ruby-concurrency/concurrent-ruby) from 1.3.6 to 1.3.7. - [Release notes](https://github.com/ruby-concurrency/concurrent-ruby/releases) - [Changelog](https://github.com/ruby-concurrency/concurrent-ruby/blob/master/CHANGELOG.md) - [Commits](https://github.com/ruby-concurrency/concurrent-ruby/compare/v1.3.6...v1.3.7) --- updated-dependencies: - dependency-name: concurrent-ruby dependency-version: 1.3.7 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Nat Dean-Lewis <94526761+natdeanlewissoftwire@users.noreply.github.com> --- docs/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index f7a89e79c..2ec3f9dbd 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -24,7 +24,7 @@ GEM coffee-script-source (1.11.1) colorator (1.1.0) commonmarker (0.23.10) - concurrent-ruby (1.3.6) + concurrent-ruby (1.3.7) connection_pool (3.0.2) csv (3.3.5) dnsruby (1.61.9) From bcc78833bd135b8bd4597095168a8317fe6db99b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jun 2026 08:46:38 +0000 Subject: [PATCH 10/10] Bump nokogiri from 1.19.3 to 1.19.4 in /docs (#3357) Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.19.3 to 1.19.4. - [Release notes](https://github.com/sparklemotion/nokogiri/releases) - [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md) - [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.19.3...v1.19.4) --- updated-dependencies: - dependency-name: nokogiri dependency-version: 1.19.4 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Nat Dean-Lewis <94526761+natdeanlewissoftwire@users.noreply.github.com> --- docs/Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 2ec3f9dbd..6db7d2511 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -229,11 +229,11 @@ GEM minitest (5.27.0) net-http (0.9.1) uri (>= 0.11.1) - nokogiri (1.19.3-arm64-darwin) + nokogiri (1.19.4-arm64-darwin) racc (~> 1.4) - nokogiri (1.19.3-x86_64-darwin) + nokogiri (1.19.4-x86_64-darwin) racc (~> 1.4) - nokogiri (1.19.3-x86_64-linux-gnu) + nokogiri (1.19.4-x86_64-linux-gnu) racc (~> 1.4) octokit (4.25.1) faraday (>= 1, < 3)