diff --git a/.envrc b/.envrc index 068b8b84ce..71d4504f60 100644 --- a/.envrc +++ b/.envrc @@ -5,6 +5,11 @@ # shellcheck shell=sh # https://direnv.net/man/direnv-stdlib.1.html PATH_add bin + +export VIRTUAL_ENV=venv +layout python +use nvm + # shellcheck disable=SC2155 export PROJECT_DIR="$(pwd)" diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ed54725f1a..1f80a11d78 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -59,6 +59,7 @@ updates: ignore: - dependency-name: "io.kubernetes:client-java:*-legacy" - dependency-name: "io.securecodebox:defectdojo-client:3.0.0" + - dependency-name: "org.springframework:spring-web" groups: gradle-security-updates: applies-to: security-updates @@ -69,52 +70,70 @@ updates: patterns: - "*" - # Docker Updates - - package-ecosystem: "docker" + # GitHub Actions Updates + - package-ecosystem: "github-actions" directories: - - "/" - - "**/*" + - "/.github/workflows" schedule: interval: "weekly" groups: - docker-security-updates: + github-actions-security-updates: applies-to: security-updates patterns: - "*" - docker-version-updates: + github-actions-version-updates: applies-to: version-updates patterns: - "*" - # GitHub Actions Updates - - package-ecosystem: "github-actions" + # Helm Chart Updates + - package-ecosystem: "helm" directories: - - "/.github/workflows" + - "/operator" + - "/hooks/persistence-elastic" schedule: interval: "weekly" groups: - github-actions-security-updates: + helm-security-updates: applies-to: security-updates patterns: - "*" - github-actions-version-updates: + helm-version-updates: applies-to: version-updates patterns: - "*" - # Helm Chart Updates - - package-ecosystem: "helm" + # Go dependancies Updae + - package-ecosystem: "gomod" directories: + - "/auto-discovery/kubernetes" + - "/auto-discovery/cloud-aws" - "/operator" - - "/hooks/persistence-elastic" + - "/lurker" schedule: interval: "weekly" groups: - helm-security-updates: + go-security-updates: applies-to: security-updates patterns: - "*" - helm-version-updates: + go-version-updates: + applies-to: version-updates + patterns: + - "*" + + - package-ecosystem: "pip" + directories: + - "/auto-discovery/kubernetes/pull-secret-extractor/" + - "/scanners/git-repo-scanner/scanner" + schedule: + interval: "weekly" + groups: + pip-security-updates: + applies-to: security-updates + patterns: + - "*" + pip-version-updates: applies-to: version-updates patterns: - "*" diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index fcef6cd7ec..e1c56e68ea 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -10,30 +10,37 @@ on: - v[0-9]+.x pull_request: +permissions: + contents: read + # The CI runs on ubuntu-24.04; More info about the installed software is found here: # https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md env: # ---- Language Versions ---- - GO_VERSION: "1.24.5" + # renovate: datasource=github-releases depName=python/cpython PYTHON_VERSION: "3.13.5" - KIND_NODE_IMAGE: "kindest/node:v1.33.1@sha256:050072256b9a903bd914c0b2866828150cb229cea0efe5892e2b644d5dd3b34f" - KUBECTL_VERSION: "v1.33.2" - KIND_BINARY_VERSION: "v0.29.0" - HELM_VERSION: "v3.18.4" - HELM_PLUGIN_UNITTEST: "0.8.2" - TASK_VERSION: "v3.44.0" + # renovate: datasource=github-releases depName=kubernetes/kubernetes + KUBECTL_VERSION: "v1.35.0" + # renovate: datasource=github-releases depName=kubernetes-sigs/kind + KIND_BINARY_VERSION: "v0.31.0" + # renovate: datasource=github-releases depName=helm/helm + HELM_VERSION: "v4.1.0" + # renovate: datasource=github-releases depName=helm-unittest/helm-unittest + HELM_PLUGIN_UNITTEST_VERSION: "1.0.3" + # renovate: datasource=github-releases depName=go-task/task + TASK_VERSION: "v3.48.0" jobs: test-nodejs-scanner-test-helpers: name: "Unit Test | Node.js Scanner Test Helpers" runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install bun - uses: oven-sh/setup-bun@v2 + uses: oven-sh/setup-bun@3d267786b128fe76c2f16a390aa2448b815359f3 # v2.1.2 - name: Install dependencies working-directory: tests/integration @@ -46,7 +53,7 @@ jobs: name: "Setup Kind & Kubectl & Helm & Task" runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Kind run: | @@ -63,7 +70,7 @@ jobs: curl -Lo ./helm.tar.gz https://get.helm.sh/helm-${{ env.HELM_VERSION }}-linux-amd64.tar.gz tar -xzf ./helm.tar.gz chmod +x ./linux-amd64/helm - + - name: Install Task run: | curl -Lo ./task.tar.gz https://github.com/go-task/task/releases/download/${{ env.TASK_VERSION }}/task_linux_amd64.tar.gz @@ -71,25 +78,25 @@ jobs: chmod +x ./task - name: Archive Kind - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: kind path: ./kind - name: Archive Kubectl - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: kubectl path: ./kubectl - name: Archive Helm - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: helm path: ./linux-amd64/helm - + - name: Archive Task - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: task path: ./task @@ -104,9 +111,9 @@ jobs: needs: - k8s-setup steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Download Helm - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: helm path: ./helm @@ -121,10 +128,10 @@ jobs: - name: Install Helm Unit Test Plugin run: | - helm plugin install https://github.com/helm-unittest/helm-unittest.git --version ${{ env.HELM_PLUGIN_UNITTEST }} + helm plugin install https://github.com/helm-unittest/helm-unittest.git --version ${{ env.HELM_PLUGIN_UNITTEST_VERSION }} --verify=false - name: Download Task - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: task path: ./task @@ -143,24 +150,24 @@ jobs: matrix: unit: ["persistence-defectdojo"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Set up JDK 17 - uses: actions/setup-java@v4 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 with: distribution: "temurin" # required Java distribution java-version: "17" # The JDK version to make available on the path. java-package: jdk # (jre, jdk, or jdk+fx) - defaults to jdk architecture: x64 # (x64 or x86) - defaults to x64 - name: Cache SonarCloud packages - uses: actions/cache@v4 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: ~/.sonar/cache key: ${{ runner.os }}-sonar restore-keys: ${{ runner.os }}-sonar - name: Cache Gradle packages - uses: actions/cache@v4 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: ~/.gradle/caches key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} @@ -184,12 +191,12 @@ jobs: component: ["operator", "lurker"] steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Go Setup - uses: actions/setup-go@v5 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: - go-version: ${{ env.GO_VERSION }} + go-version-file: "operator/go.mod" - name: Lint Go Code working-directory: ./${{ matrix.component }} @@ -210,7 +217,7 @@ jobs: run: make docker-export-${{ matrix.component }} - name: Upload Image As Artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: ${{ matrix.component }}-image path: ./operator/${{ matrix.component }}.tar @@ -223,12 +230,12 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Go Setup - uses: actions/setup-go@v5 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: - go-version: ${{ env.GO_VERSION }} + go-version-file: "auto-discovery/kubernetes/go.mod" - name: Lint Go Code working-directory: ./auto-discovery/kubernetes @@ -249,7 +256,7 @@ jobs: run: make docker-export - name: Upload Image As Artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: auto-discovery-image path: ./auto-discovery/kubernetes/auto-discovery-kubernetes.tar @@ -263,31 +270,43 @@ jobs: - k8s-setup steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Setup Python Version - uses: actions/setup-python@v5 + - name: Go Setup + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: - python-version: "${{ env.PYTHON_VERSION }}" + go-version-file: "auto-discovery/kubernetes/go.mod" - - uses: actions/setup-node@v4 + - name: Lint Go Code + working-directory: ./auto-discovery/kubernetes + run: | + go fmt ./... + go vet ./... + + - name: Download Task + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: - node-version-file: ".nvmrc" + name: task + path: ./task + + - name: Make Task globally available + run: | + chmod +x ./task/task && sudo mv ./task/task /usr/local/bin/task - name: Download Kind - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: kind path: ./kind - name: Download Kubectl - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: kubectl path: ./kubectl - name: Download Helm - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: helm path: ./helm @@ -306,18 +325,18 @@ jobs: - name: Unit Tests working-directory: ./auto-discovery/kubernetes/pull-secret-extractor - run: make unit-test + run: task unit-test - name: Build Container Image working-directory: ./auto-discovery/kubernetes/pull-secret-extractor - run: make docker-build + run: task docker-build - name: Export Container Image working-directory: ./auto-discovery/kubernetes/pull-secret-extractor - run: make docker-export + run: task docker-export - name: Upload Image As Artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: auto-discovery-pull-secret-extractor path: ./auto-discovery/kubernetes/pull-secret-extractor/auto-discovery-secret-extractor.tar @@ -326,7 +345,7 @@ jobs: - name: "Start kind cluster" run: | kind version - kind create cluster --wait 3m --image "$KIND_NODE_IMAGE" + kind create cluster --wait 3m - name: "Inspect kind cluster" run: | @@ -336,7 +355,7 @@ jobs: - name: "Run integration tests" working-directory: ./auto-discovery/kubernetes/pull-secret-extractor run: | - make integration-test + task integration-test # ---- Build Stage | AutoDiscovery | Cloud | AWS ---- auto-discovery-cloud-aws: @@ -344,12 +363,12 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Go Setup - uses: actions/setup-go@v5 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: - go-version: ${{ env.GO_VERSION }} + go-version-file: "auto-discovery/cloud-aws/go.mod" - name: Lint Go Code working-directory: ./auto-discovery/cloud-aws @@ -370,7 +389,7 @@ jobs: run: make docker-export - name: Upload Image As Artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: auto-discovery-cloud-aws-image path: ./auto-discovery/cloud-aws/auto-discovery-cloud-aws.tar @@ -388,7 +407,7 @@ jobs: - hook-sdk steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Build Image working-directory: ./${{ matrix.sdk }}/nodejs @@ -399,7 +418,7 @@ jobs: run: make docker-export-sdk - name: Upload Artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: ${{ matrix.sdk }}-image path: ./${{ matrix.sdk }}/nodejs/${{ matrix.sdk }}.tar @@ -418,8 +437,6 @@ jobs: fail-fast: false matrix: unit: - - amass - - cmseek - ffuf - git-repo-scanner - gitleaks @@ -432,6 +449,7 @@ jobs: - semgrep - ssh-audit - sslyze + - subfinder - trivy - trivy-sbom - whatweb @@ -439,13 +457,13 @@ jobs: - zap-automation-framework steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install bun - uses: oven-sh/setup-bun@v2 + uses: oven-sh/setup-bun@3d267786b128fe76c2f16a390aa2448b815359f3 # v2.1.2 - name: Download Task - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: task path: ./task @@ -455,19 +473,19 @@ jobs: chmod +x ./task/task && sudo mv ./task/task /usr/local/bin/task - name: Download Kind - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: kind path: ./kind - name: Download Kubectl - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: kubectl path: ./kubectl - name: Download Helm - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: helm path: ./helm @@ -478,18 +496,24 @@ jobs: chmod +x ./kubectl/kubectl && sudo mv ./kubectl/kubectl /usr/local/bin/kubectl chmod +x ./helm/helm && sudo mv ./helm/helm /usr/local/bin/helm + - name: Go Setup + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 + with: + go-version-file: "scanners/git-repo-scanner/scanner/go.mod" + - name: Verify tools run: | kind version kubectl version || true helm version + go version - name: Unit Tests working-directory: ./scanners/${{ matrix.unit }}/ run: task test:unit - name: Download Parser SDK Image - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: parser-sdk-image path: /tmp @@ -500,7 +524,7 @@ jobs: docker images | grep sdk - name: Download Operator Image - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: operator-image path: ./operator @@ -511,7 +535,7 @@ jobs: docker images | grep operator - name: Download Lurker Image - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: lurker-image path: ./operator @@ -592,13 +616,13 @@ jobs: # - persistence-static-report (WIP) steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install bun - uses: oven-sh/setup-bun@v2 + uses: oven-sh/setup-bun@3d267786b128fe76c2f16a390aa2448b815359f3 # v2.1.2 - name: Download Task - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: task path: ./task @@ -608,19 +632,19 @@ jobs: chmod +x ./task/task && sudo mv ./task/task /usr/local/bin/task - name: Download Kind - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: kind path: ./kind - name: Download Kubectl - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: kubectl path: ./kubectl - name: Download Helm - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: helm path: ./helm @@ -642,7 +666,7 @@ jobs: run: task test:unit - name: Download Parser SDK Image - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: hook-sdk-image path: /tmp @@ -653,7 +677,7 @@ jobs: docker images | grep sdk - name: Download Operator Image - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: operator-image path: ./operator @@ -664,7 +688,7 @@ jobs: docker images | grep operator - name: Download Lurker Image - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: lurker-image path: ./operator @@ -726,12 +750,12 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: - go-version: ${{ env.GO_VERSION }} + go-version-file: "scbctl/go.mod" - name: Run tests working-directory: scbctl diff --git a/.github/workflows/documentation-roulette.yaml b/.github/workflows/documentation-roulette.yaml index 0bc09da5d2..b695a82ecc 100644 --- a/.github/workflows/documentation-roulette.yaml +++ b/.github/workflows/documentation-roulette.yaml @@ -9,6 +9,10 @@ on: schedule: - cron: "0 12 15 * *" # At 12:00 UTC on day-of-month 15 +permissions: + contents: read + issues: write + jobs: docu-roulette: permissions: @@ -17,7 +21,7 @@ jobs: if: github.repository == 'secureCodeBox/secureCodeBox' steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 # Request team members with the GitHub API using their gh cli - name: Fetch core-team members @@ -38,7 +42,7 @@ jobs: echo "MEMBER=${MEMBERS[$index]}" >> $GITHUB_ENV # Create issue and insert chosen member ({{ env.MEMBER}} in template) - - uses: JasonEtco/create-an-issue@v2 + - uses: JasonEtco/create-an-issue@1b14a70e4d8dc185e5cc76d3bec9eab20257b2c5 # v2.9.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/.github/workflows/helm-charts-release-ghcr.yaml b/.github/workflows/helm-charts-release-ghcr.yaml index 5896cd4db4..369d64a1da 100644 --- a/.github/workflows/helm-charts-release-ghcr.yaml +++ b/.github/workflows/helm-charts-release-ghcr.yaml @@ -7,6 +7,11 @@ on: types: [published] name: "Publish Helm Charts to GHCR" + +permissions: + contents: read + packages: write + env: CONTAINER_REGISTRY: ghcr.io/securecodebox HELM_VERSION: "v3.12.2" @@ -14,11 +19,8 @@ jobs: GHCR-Helm-Release: name: "Publish Helm Charts to GHCR" runs-on: ubuntu-24.04 - permissions: - contents: read - packages: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Parse Release Version run: | @@ -46,7 +48,7 @@ jobs: cd "${dir}" || exit echo "Processing Helm Chart in $dir" NAME=$(yq eval '.name' - < Chart.yaml) - + helm package --version "${{ env.version }}" . helm push "${NAME}-${{ env.version }}.tgz" oci://$CONTAINER_REGISTRY/helm/ diff --git a/.github/workflows/helm-charts-release.yaml b/.github/workflows/helm-charts-release.yaml index 20aa6640ca..07d6e51f85 100644 --- a/.github/workflows/helm-charts-release.yaml +++ b/.github/workflows/helm-charts-release.yaml @@ -9,12 +9,16 @@ on: release: types: [published] name: "Publish Helm Charts" + +permissions: + contents: read + jobs: helm: name: Package and Publish runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: "Install yq" run: | sudo snap install yq diff --git a/.github/workflows/helm-docs.yaml b/.github/workflows/helm-docs.yaml index 98963d41e4..ef31ac48c5 100644 --- a/.github/workflows/helm-docs.yaml +++ b/.github/workflows/helm-docs.yaml @@ -5,24 +5,27 @@ # The CI runs on ubuntu-24.04; More info about the installed software is found here: # https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md - name: "Update Helm Docs" on: push: branches: - main + +permissions: + contents: write + jobs: helm-docs: runs-on: ubuntu-24.04 if: github.repository == 'secureCodeBox/secureCodeBox' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.head_ref }} token: ${{ secrets.SCB_BOT_USER_TOKEN }} - name: Import GPG key - uses: crazy-max/ghaction-import-gpg@v6 + uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6.3.0 with: gpg_private_key: ${{ secrets.GPG_COMMITS_PRIVATE_KEY }} passphrase: ${{ secrets.GPG_COMMITS_PASSPHRASE }} diff --git a/.github/workflows/label-commenter.yml b/.github/workflows/label-commenter.yml index f92609a5cc..ed95133232 100644 --- a/.github/workflows/label-commenter.yml +++ b/.github/workflows/label-commenter.yml @@ -19,11 +19,8 @@ jobs: comment: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Label Commenter - uses: peaceiris/actions-label-commenter@v1.10.0 + uses: peaceiris/actions-label-commenter@f0dbbef043eb1b150b566db36b0bdc8b7f505579 # v1.10.0 with: github_token: ${{ secrets.SCB_BOT_USER_TOKEN }} - - - \ No newline at end of file diff --git a/.github/workflows/license-check.yaml b/.github/workflows/license-check.yaml index 4ed1e1ad44..eff256f09b 100644 --- a/.github/workflows/license-check.yaml +++ b/.github/workflows/license-check.yaml @@ -10,15 +10,18 @@ on: - v[0-9]+.x pull_request: +permissions: + contents: read + jobs: license-check: runs-on: ubuntu-24.04 if: github.repository == 'secureCodeBox/secureCodeBox' steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: REUSE Compliance Check - uses: fsfe/reuse-action@v5 + uses: fsfe/reuse-action@676e2d560c9a403aa252096d99fcab3e1132b0f5 # v6.0.0 with: args: --include-submodules lint diff --git a/.github/workflows/mega-linter.yml b/.github/workflows/mega-linter.yml index c38b90efa3..5c75d103c6 100644 --- a/.github/workflows/mega-linter.yml +++ b/.github/workflows/mega-linter.yml @@ -16,6 +16,9 @@ on: pull_request: branches: [master, main] +permissions: + contents: read + env: # Comment env block if you do not want to apply fixes # Apply linter fixes configuration APPLY_FIXES: none # When active, APPLY_FIXES must also be defined as environment variable (in github/workflows/mega-linter.yml or other CI tool) @@ -33,7 +36,7 @@ jobs: steps: # Git Checkout - name: Checkout Code - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} fetch-depth: 0 @@ -43,7 +46,7 @@ jobs: id: ml # You can override MegaLinter flavor used to have faster performances # More info at https://megalinter.github.io/flavors/ - uses: oxsecurity/megalinter@v8 + uses: oxsecurity/megalinter@42bb470545e359597e7f12156947c436e4e3fb9a # v9.3.0 env: # All available variables are described in documentation # https://megalinter.github.io/configuration/ @@ -54,7 +57,7 @@ jobs: # Upload MegaLinter artifacts - name: Archive production artifacts if: ${{ success() }} || ${{ failure() }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: MegaLinter reports path: | diff --git a/.github/workflows/move-bot-pr-to-review.yaml b/.github/workflows/move-bot-pr-to-review.yaml index b2365c5680..10d9b2395a 100644 --- a/.github/workflows/move-bot-pr-to-review.yaml +++ b/.github/workflows/move-bot-pr-to-review.yaml @@ -9,17 +9,21 @@ on: branches: - main +permissions: + contents: read + pull-requests: write + jobs: - move-bot-pr-to-review: + move-bot-pr-to-review: runs-on: ubuntu-24.04 - # only run if the branch starts with 'dependabot/' or 'dependencies/upgrading' + # only run if the branch starts with 'dependabot/' or 'dependencies/upgrading' if: startsWith(github.head_ref, 'dependabot/') || startsWith(github.head_ref, 'dependencies/upgrading') steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Add bot PR to project run: | - # Get the ID for the field Status + # Get the ID for the field Status # gh project list --owner secureCodeBox secureCodeBoxV4ProjectID="PVT_kwDOAg-Nic05GQ" @@ -32,15 +36,15 @@ jobs: } } }" | jq -r '.data.addProjectV2ItemById.item.id') >> $GITHUB_ENV - env: - GH_TOKEN: ${{ secrets.SCB_BOT_USER_TOKEN }} + env: + GH_TOKEN: ${{ secrets.SCB_BOT_USER_TOKEN }} PR_ID: ${{ github.event.pull_request.node_id }} - name: Move PR to column To Review # only move SCB-Bot, since dependabot is not part of core team and therefore has no access to secrets if: startsWith(github.head_ref, 'dependencies/upgrading') run: | - # Get the ID for the field Status + # Get the ID for the field Status # gh project field-list 6 --owner secureCodeBox StatusFieldID="PVTSSF_lADOAg-Nic05Gc4AAZuO" @@ -52,6 +56,6 @@ jobs: prNodeID=${{env.prNodeID}} # Move PR to "To Review" status gh project item-edit --id ${{ env.prNodeID }} --field-id $StatusFieldID --project-id $secureCodeBoxV4ProjectID --single-select-option-id $ToReviewID - + env: - GH_TOKEN: ${{ secrets.SCB_BOT_USER_TOKEN }} \ No newline at end of file + GH_TOKEN: ${{ secrets.SCB_BOT_USER_TOKEN }} diff --git a/.github/workflows/oss-scorecard.yaml b/.github/workflows/oss-scorecard.yaml new file mode 100644 index 0000000000..8cc03fa42c --- /dev/null +++ b/.github/workflows/oss-scorecard.yaml @@ -0,0 +1,38 @@ +# SPDX-FileCopyrightText: the secureCodeBox authors +# +# SPDX-License-Identifier: Apache-2.0 + +name: Scorecards supply-chain security +on: + push: + branches: + - main + +permissions: read-all + +jobs: + analysis: + name: Scorecards analysis + runs-on: ubuntu-latest + permissions: + security-events: write + id-token: write + + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 + with: + results_file: results.sarif + results_format: sarif + publish_results: true + + # Upload the results to GitHub's code scanning dashboard. + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@6bc82e05fd0ea64601dd4b465378bbcf57de0314 # v4.32.1 + with: + sarif_file: results.sarif diff --git a/.github/workflows/release-build.yaml b/.github/workflows/release-build.yaml index 7842ad77be..76f848c277 100644 --- a/.github/workflows/release-build.yaml +++ b/.github/workflows/release-build.yaml @@ -8,7 +8,10 @@ name: "Release Build" on: release: - types: [released, prereleased] + types: [published] + +permissions: + contents: read env: # ---- Docker Namespace ---- @@ -28,11 +31,11 @@ jobs: component: ["operator", "lurker"] steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Docker Meta id: docker_meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 with: images: ${{ env.DOCKER_NAMESPACE }}/${{ matrix.component }} tags: | @@ -40,18 +43,18 @@ jobs: type=semver,pattern={{version}} - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - name: Login to DockerHub - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} - name: Build and Push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: ./${{ matrix.component }} file: ./${{ matrix.component }}/Dockerfile @@ -61,7 +64,7 @@ jobs: labels: ${{ steps.docker_meta.outputs.labels }} - name: Update Docker Hub Description - uses: peter-evans/dockerhub-description@v4 + uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} @@ -75,11 +78,11 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Docker Meta id: docker_meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 with: images: ${{ env.DOCKER_NAMESPACE }}/auto-discovery-kubernetes tags: | @@ -87,18 +90,18 @@ jobs: type=semver,pattern={{version}} - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - name: Login to DockerHub - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} - name: Build and Push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: ./auto-discovery/kubernetes/ file: ./auto-discovery/kubernetes/Dockerfile @@ -108,7 +111,7 @@ jobs: labels: ${{ steps.docker_meta.outputs.labels }} - name: Update Docker Hub Description - uses: peter-evans/dockerhub-description@v4 + uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} @@ -122,11 +125,11 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Docker Meta id: docker_meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 with: images: ${{ env.DOCKER_NAMESPACE }}/auto-discovery-pull-secret-extractor tags: | @@ -134,18 +137,18 @@ jobs: type=semver,pattern={{version}} - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - name: Login to DockerHub - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} - name: Build and Push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: ./auto-discovery/kubernetes/pull-secret-extractor file: ./auto-discovery/kubernetes/pull-secret-extractor/Dockerfile @@ -155,7 +158,7 @@ jobs: labels: ${{ steps.docker_meta.outputs.labels }} - name: Update Docker Hub Description - uses: peter-evans/dockerhub-description@v4 + uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} @@ -175,11 +178,11 @@ jobs: - hook-sdk steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Docker Meta id: docker_meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 with: images: ${{ env.DOCKER_NAMESPACE }}/${{ matrix.sdk }}-nodejs tags: | @@ -187,18 +190,18 @@ jobs: type=semver,pattern={{version}} - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - name: Login to DockerHub - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} - name: Build and Push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: ./${{ matrix.sdk }}/nodejs file: ./${{ matrix.sdk }}/nodejs/Dockerfile @@ -228,11 +231,11 @@ jobs: - update-field-hook steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Docker Meta id: docker_meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 with: images: ${{ env.DOCKER_NAMESPACE }}/hook-${{ matrix.hook }} tags: | @@ -240,12 +243,12 @@ jobs: type=semver,pattern={{version}} - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - name: Login to DockerHub - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} @@ -255,7 +258,7 @@ jobs: echo "baseImageTag=sha-$(git rev-parse --short HEAD)" >> $GITHUB_ENV - name: Build and Push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: ./hooks/${{ matrix.hook }}/hook file: ./hooks/${{ matrix.hook }}/hook/Dockerfile @@ -268,7 +271,7 @@ jobs: labels: ${{ steps.docker_meta.outputs.labels }} - name: Update Docker Hub Description - uses: peter-evans/dockerhub-description@v4 + uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} @@ -282,11 +285,11 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Docker Meta id: docker_meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 with: images: ${{ env.DOCKER_NAMESPACE }}/persistence-elastic-dashboard-importer tags: | @@ -294,16 +297,16 @@ jobs: type=semver,pattern={{version}} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - name: Login to DockerHub - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} - name: Build and Push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: ./hooks/persistence-elastic/dashboard-importer/ file: ./hooks/persistence-elastic/dashboard-importer/Dockerfile @@ -322,8 +325,6 @@ jobs: strategy: matrix: parser: - - amass - - cmseek - ffuf - git-repo-scanner - gitleaks @@ -336,6 +337,7 @@ jobs: - semgrep - ssh-audit - sslyze + - subfinder - test-scan - trivy - trivy-sbom @@ -345,11 +347,11 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Docker Meta id: docker_meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 with: images: ${{ env.DOCKER_NAMESPACE }}/parser-${{ matrix.parser }} tags: | @@ -357,12 +359,12 @@ jobs: type=semver,pattern={{version}} - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - name: Login to DockerHub - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} @@ -372,7 +374,7 @@ jobs: echo "baseImageTag=sha-$(git rev-parse --short HEAD)" >> $GITHUB_ENV - name: Build and Push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: ./scanners/${{ matrix.parser }}/parser file: ./scanners/${{ matrix.parser }}/parser/Dockerfile @@ -385,7 +387,7 @@ jobs: labels: ${{ steps.docker_meta.outputs.labels }} - name: Update Docker Hub Description - uses: peter-evans/dockerhub-description@v4 + uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} @@ -408,8 +410,6 @@ jobs: strategy: matrix: scanner: - - amass - - cmseek - ffuf - kube-hunter - ncrack @@ -422,10 +422,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set ENV Var with Scanner Version - uses: mikefarah/yq@v4.46.1 + uses: mikefarah/yq@2be0094729a1006f61e8339ce9934bfb3cbb549f # v4.52.2 # Notice: The current version of the scanner is provided via the Chart.yaml to ensure # there is only one place to edit the version of a scanner with: @@ -433,13 +433,13 @@ jobs: # extract the supported cpu architectures from the Chart.yaml - name: Set ENV Var with Supported Platforms - uses: mikefarah/yq@v4.46.1 + uses: mikefarah/yq@2be0094729a1006f61e8339ce9934bfb3cbb549f # v4.52.2 with: cmd: echo supportedPlatforms=$(yq e .annotations.supported-platforms scanners/${{ matrix.scanner }}/Chart.yaml) >> $GITHUB_ENV - name: Docker Meta id: docker_meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 with: images: ${{ env.DOCKER_NAMESPACE }}/scanner-${{ matrix.scanner }} tags: | @@ -447,16 +447,16 @@ jobs: ${{ env.scannerVersion }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - name: Login to DockerHub - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} - name: Build and Push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: ./scanners/${{ matrix.scanner }}/scanner file: ./scanners/${{ matrix.scanner }}/scanner/Dockerfile @@ -468,7 +468,7 @@ jobs: labels: ${{ steps.docker_meta.outputs.labels }} - name: Update Docker Hub Description - uses: peter-evans/dockerhub-description@v4 + uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} @@ -492,11 +492,11 @@ jobs: - test-scan steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Docker Meta id: docker_meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 with: images: ${{ env.DOCKER_NAMESPACE }}/scanner-${{ matrix.scanner }} tags: | @@ -504,10 +504,10 @@ jobs: type=semver,pattern={{version}} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - name: Login to DockerHub - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} @@ -517,7 +517,7 @@ jobs: echo "baseImageTag=sha-$(git rev-parse --short HEAD)" >> $GITHUB_ENV - name: Build and Push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: ./scanners/${{ matrix.scanner }}/scanner file: ./scanners/${{ matrix.scanner }}/scanner/Dockerfile @@ -529,7 +529,7 @@ jobs: labels: ${{ steps.docker_meta.outputs.labels }} - name: Update Docker Hub Description - uses: peter-evans/dockerhub-description@v4 + uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} @@ -552,10 +552,10 @@ jobs: - old-wordpress steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set ENV Var with Demo-Target Version - uses: mikefarah/yq@v4.46.1 + uses: mikefarah/yq@2be0094729a1006f61e8339ce9934bfb3cbb549f # v4.52.2 # Notice: The current version of the demo-target is provided via the Chart.yaml to ensure # there is only one place to edit the version of a scanner with: @@ -563,7 +563,7 @@ jobs: - name: Docker Meta id: docker_meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 with: images: ${{ env.DOCKER_NAMESPACE }}/demo-target-${{ matrix.target }} tags: | @@ -572,16 +572,16 @@ jobs: ${{ env.targetVersion }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - name: Login to DockerHub - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} - name: Build and Push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: ./demo-targets/${{ matrix.target }}/container file: ./demo-targets/${{ matrix.target }}/container/Dockerfile @@ -591,7 +591,7 @@ jobs: labels: ${{ steps.docker_meta.outputs.labels }} - name: Update Docker Hub Description - uses: peter-evans/dockerhub-description@v4 + uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} diff --git a/.github/workflows/scb-bot.yaml b/.github/workflows/scb-bot.yaml index 5faa6af0bc..cd1da7adee 100644 --- a/.github/workflows/scb-bot.yaml +++ b/.github/workflows/scb-bot.yaml @@ -18,6 +18,11 @@ name: Check outdated scanners on: schedule: - cron: "15 9 * * *" # Daily at 9:15 (avoids the beginning of the hour congestion) + +permissions: + contents: write + pull-requests: write + jobs: version-compare: runs-on: ubuntu-24.04 @@ -27,8 +32,6 @@ jobs: fail-fast: false matrix: scanner: - - amass - - cmseek - ffuf - gitleaks - kube-hunter @@ -37,6 +40,7 @@ jobs: - semgrep - ssh-audit - sslyze + - subfinder - trivy - trivy-sbom - whatweb @@ -44,10 +48,10 @@ jobs: - zap-automation-framework # missing scanners are : nmap, nikto steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Import GPG key - uses: crazy-max/ghaction-import-gpg@v6 + uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6.3.0 with: gpg_private_key: ${{ secrets.GPG_COMMITS_PRIVATE_KEY }} passphrase: ${{ secrets.GPG_COMMITS_PASSPHRASE }} @@ -57,14 +61,14 @@ jobs: # Fetching scanner version from local chart .appVersion attribute # this would look like 1.1.1 or v1.1.1 depending on the corresponding Docker image tag - name: Fetch local scanner version - uses: mikefarah/yq@v4.46.1 + uses: mikefarah/yq@2be0094729a1006f61e8339ce9934bfb3cbb549f # v4.52.2 with: cmd: echo local=$(yq e .appVersion scanners/${{ matrix.scanner }}/Chart.yaml) >> $GITHUB_ENV # Fetching scanner version API from local chart .annotations.versionApi attribute - # This would look like https://api.github.com/repos/OWASP/Amass/releases/latest + # This would look like https://api.github.com/repos/projectdiscovery/nuclei/releases/latest - name: Fetch scanner's version API - uses: mikefarah/yq@v4.46.1 + uses: mikefarah/yq@2be0094729a1006f61e8339ce9934bfb3cbb549f # v4.52.2 with: cmd: echo versionApi=$(yq e .annotations.versionApi scanners/${{ matrix.scanner }}/Chart.yaml) >> $GITHUB_ENV @@ -77,7 +81,7 @@ jobs: set -o pipefail local=${{env.local}} - release=$(curl -sL ${{env.versionApi}} | jq -er ".tag_name" ) + release=$(curl -sL ${{env.versionApi}} | jq -er ".tag_name" ) upgrade=$release # Check the exit status of the curl and jq command @@ -94,11 +98,11 @@ jobs: if [[ ${local:0:1} != ${release:0:1} ]] ; then # Check if the first character of local is "v" # In this case docker/local format is "v1.0.0" and github format is "1.0.1" - # We want the upgrade to be "v1.0.1" + # We want the upgrade to be "v1.0.1" if [[ ${local:0:1} == "v" ]] ; then # set upgrade to "v" followed by the value of release. upgrade=v${release}; - # Check if the first character of release is "v" + # Check if the first character of release is "v" # in this case docker/local format is "1.0.0" and github format is "v1.0.1" # We want the upgrade to be "1.0.1" elif [[ ${release:0:1} == "v" ]] ; then @@ -131,7 +135,7 @@ jobs: # Reformats the versionApi to have an HTML view of the release changelog # sed command is divided into three parts s/api.//g; , s/\/repos//g; and s/latest//g # "api." and "/repos" and "latest" are replaced with nothing (a.k.a removed) - # example: https://api.github.com/repos/OWASP/Amass/releases/latest --> https://github.com/OWASP/Amass/releases/ + # example: https://api.github.com/repos/projectdiscovery/nuclei/releases/latest --> https://github.com/projectdiscovery/nuclei/releases/ # the next command then appends the link with the new release version as it is in Github. run: | changelog=$(echo ${{env.versionApi}} | sed -e 's/api.//g;s/\/repos//g;s/latest//g') @@ -139,7 +143,7 @@ jobs: - name: Upgrade Scanner Helm Chart if: ${{ env.release != env.local && env.prExists == 0 && env.release != null}} - uses: mikefarah/yq@v4.46.1 + uses: mikefarah/yq@2be0094729a1006f61e8339ce9934bfb3cbb549f # v4.52.2 with: # appVersion value in chart is replaced with release value. Empty lines are deleted in the process cmd: yq e --inplace '.appVersion = "${{env.release}}"' ./scanners/${{ matrix.scanner }}/Chart.yaml @@ -185,7 +189,7 @@ jobs: - name: Create Pull Request if: ${{ env.release != env.local && env.prExists == 0 && env.release != null }} - uses: peter-evans/create-pull-request@v7 + uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0 with: token: ${{ secrets.SCB_BOT_USER_TOKEN }} committer: secureCodeBoxBot diff --git a/.gitignore b/.gitignore index 5fb27ddee0..9c40c75c5d 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,7 @@ report # Documentation ## Documentation build files +documentation/build/ documentation/.docusaurus documentation/.cache-loader ## Documentation generated files @@ -73,4 +74,5 @@ documentation/.author_meta **/node_modules/ # we still use package-lock.json from node as we still use node for our acutal production containers -bun.lock \ No newline at end of file +bun.lock + diff --git a/.python-version b/.python-version index 71380f2427..f982feb41b 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.9.10 \ No newline at end of file +3.14.0 diff --git a/.reuse/dep5 b/.reuse/dep5 deleted file mode 100644 index 64acaf960b..0000000000 --- a/.reuse/dep5 +++ /dev/null @@ -1,15 +0,0 @@ -Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: secureCodeBox -Upstream-Contact: Robert Felber -Source: https://github.com/secureCodeBox/secureCodeBox - -Files: .github/ISSUE_TEMPLATE/*.md -Copyright: the secureCodeBox authors -License: Apache-2.0 - -# Workaround because some of the test files hav content which confuses reuse -# and it will skip the file resulting in no copyright/license ifo which will -# fail our check. -Files: **/tests/__snapshot__/*.yaml.snap -Copyright: the secureCodeBox authors -License: Apache-2.0 diff --git a/.templates/new-scanner/parser/parser.test.js b/.templates/new-scanner/parser/parser.test.js index f747350079..5daf88095c 100644 --- a/.templates/new-scanner/parser/parser.test.js +++ b/.templates/new-scanner/parser/parser.test.js @@ -11,11 +11,11 @@ test("should properly parse new-scanner json file", async () => { const fileContent = JSON.parse( await readFile(import.meta.dirname + "/__testFiles__/example.com.json", { encoding: "utf8", - }) + }), ); const findings = await parse(fileContent); // validate findings - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(); }); @@ -23,10 +23,10 @@ test("should properly parse empty json file", async () => { const fileContent = JSON.parse( await readFile(import.meta.dirname + "/__testFiles__/empty.json", { encoding: "utf8", - }) + }), ); const findings = await parse(fileContent); // validate findings - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(); }); diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 0105bd80dc..a8a78389ed 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -58,4 +58,8 @@ Committing with `git commit -s` will add the sign-off at the end of the commit m - Eline Henriksen - Michael Kruggel - Ochi Daiki -- Kai Schäfer \ No newline at end of file +- Kai Schäfer +- Joel Saß +- Patrick Weiss +- Conleth Kennedy +- Matus Szepe diff --git a/README.md b/README.md index 3e0dfd4cc4..545c6abda2 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ SPDX-License-Identifier: Apache-2.0 Artifact HUB Mastodon Follower Build - Known Vulnerabilities + OpenSSF Scorecard

diff --git a/REUSE.toml b/REUSE.toml new file mode 100644 index 0000000000..f2f92f8080 --- /dev/null +++ b/REUSE.toml @@ -0,0 +1,16 @@ +version = 1 +SPDX-PackageName = "secureCodeBox" +SPDX-PackageSupplier = "OWASP (https://owasp.org/)" +SPDX-PackageDownloadLocation = "https://github.com/secureCodeBox/secureCodeBox" + +[[annotations]] +path = ".github/ISSUE_TEMPLATE/**.md" +precedence = "aggregate" +SPDX-FileCopyrightText = "the secureCodeBox authors" +SPDX-License-Identifier = "Apache-2.0" + +[[annotations]] +path = "**/tests/__snapshot__/**.yaml.snap" +precedence = "aggregate" +SPDX-FileCopyrightText = "the secureCodeBox authors" +SPDX-License-Identifier = "Apache-2.0" diff --git a/SECURITY.md b/SECURITY.md index f30ec54ff9..20ffb4cf4f 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -7,35 +7,42 @@ SPDX-License-Identifier: Apache-2.0 # Security Policy ## Supported Versions + Our _release cycle_ for new features (minor [semver](https://semver.org/) update) -is roughly every two weeks (we will usually make a new release after each review). +is roughly every four weeks (we will usually make a new release after each sprint review). | Version | Security Fixes* | Supported** | | ------- | ------------------ | ------------------ | -| 4.x.x | :white_check_mark: | :white_check_mark: | -| 3.15.x | :white_check_mark: | :white_check_mark: | -| <= 2.9.x | :x: | :x: | -| < 2.0 | :x: | :x: | +| 5.x.x | :white_check_mark: | :white_check_mark: | +| 4.16.x | Critical issues only | :x: | +| <= 3.15.x | :x: | :x: | ### Major Release (Semver) + _Upcoming major updates_ will come with a time window in which both _major versions_ (starting with v2.x.x) -will receive security updates and bugfixes. The concrete support intervall will be probably a couple of months -and will be published when the next major version will be released. +will receive security updates and bugfixes. The concrete support interval will probably be a couple of months +and will be published when the next major version is released. ### Minor Release/Feature Releases (Semver) + We currently plan to provide support for the _latest minor [semver](https://semver.org/)_ release only. ### Patch Release/Bugfix/Security Fix + We try to make bugfixes and high severity fixes available as patch release for the current minor release as early as possible. ## Extended (Enterprise) Support -If you are interested in extended support for older versions with security updates of our project + +If you are interested in extended support for older versions with security updates of our project please get in touch with the project team via Slack or email . ## Reporting a Vulnerability -You have found a vulnerability in the project that shouldn't be disclosed as public issue before it's fixed? -Please get in touch with the project team via Slack or email . -You can expect a fast reaction within the next days. -We will keep you updated about the next steps and inform you if the vulnerability is accepted and when its fixed or if its ordeclined somehow. +You have found a vulnerability in the project that shouldn't be disclosed as a public issue before it's fixed? +Please report it using GitHub Security Advisories at https://github.com/secureCodeBox/secureCodeBox/security/advisories. + +If you are unable to use GitHub advisories, please email the project leaders at their OWASP email addresses that can be found under https://github.com/OWASP/www-project-securecodebox/blob/master/leaders.md. + +You can expect a fast reaction within the next few days. +We will keep you updated about the next steps and inform you if the vulnerability is accepted and when it's fixed or if it's declined somehow. diff --git a/auto-discovery/cloud-aws/Dockerfile b/auto-discovery/cloud-aws/Dockerfile index 2ba2650677..3c5b86e862 100644 --- a/auto-discovery/cloud-aws/Dockerfile +++ b/auto-discovery/cloud-aws/Dockerfile @@ -3,7 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 # Build the service binary -FROM golang:1.24.2 AS builder +FROM --platform=$BUILDPLATFORM golang:1.25.7 AS builder WORKDIR /workspace # Copy the Go Modules manifests @@ -18,7 +18,8 @@ COPY cmd/ cmd/ COPY pkg/ pkg/ # Build -RUN CGO_ENABLED=0 go build -a -o service cmd/service/main.go +ARG TARGETOS TARGETARCH +RUN GOOS="$TARGETOS" GOARCH="$TARGETARCH" CGO_ENABLED=0 go build -a -o service cmd/service/main.go # Use distroless as minimal base image to package the service binary # Refer to https://github.com/GoogleContainerTools/distroless for more details diff --git a/auto-discovery/cloud-aws/cmd/service/main.go b/auto-discovery/cloud-aws/cmd/service/main.go index d8f52c4dea..d3f62743be 100644 --- a/auto-discovery/cloud-aws/cmd/service/main.go +++ b/auto-discovery/cloud-aws/cmd/service/main.go @@ -11,6 +11,7 @@ import ( "github.com/secureCodeBox/secureCodeBox/auto-discovery/cloud-aws/pkg/aws" "github.com/secureCodeBox/secureCodeBox/auto-discovery/cloud-aws/pkg/config" "github.com/secureCodeBox/secureCodeBox/auto-discovery/cloud-aws/pkg/kubernetes" + "k8s.io/klog/v2" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/log/zap" ) @@ -22,13 +23,14 @@ func main() { "Omit this flag to use the default configuration values. "+ "Environment variables override some configuration values from this file.") opts := zap.Options{ - Development: true, + Development: false, } opts.BindFlags(flag.CommandLine) flag.Parse() log := zap.New(zap.UseFlagOptions(&opts)) ctrl.SetLogger(log) + klog.SetLogger(log) // Read config from file first, some values may be overridden by env variables cfg := config.GetConfig(configFile) diff --git a/auto-discovery/cloud-aws/cmd/service/suite_test.go b/auto-discovery/cloud-aws/cmd/service/suite_test.go index 37fe29aea4..ab9e4db01a 100644 --- a/auto-discovery/cloud-aws/cmd/service/suite_test.go +++ b/auto-discovery/cloud-aws/cmd/service/suite_test.go @@ -19,7 +19,6 @@ import ( "github.com/secureCodeBox/secureCodeBox/auto-discovery/cloud-aws/pkg/aws" "github.com/secureCodeBox/secureCodeBox/auto-discovery/cloud-aws/pkg/config" "github.com/secureCodeBox/secureCodeBox/auto-discovery/cloud-aws/pkg/kubernetes" - configv1 "github.com/secureCodeBox/secureCodeBox/auto-discovery/kubernetes/api/v1" executionv1 "github.com/secureCodeBox/secureCodeBox/operator/apis/execution/v1" batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" @@ -86,7 +85,7 @@ var _ = BeforeSuite(func() { }, Kubernetes: config.KubernetesConfig{ Namespace: namespace, - ScanConfigs: []configv1.ScanConfig{ + ScanConfigs: []config.ScanConfig{ { Name: "test-scan", RepeatInterval: metav1.Duration{Duration: time.Hour}, diff --git a/auto-discovery/cloud-aws/go.mod b/auto-discovery/cloud-aws/go.mod index 5c0d126366..7e3a155a65 100644 --- a/auto-discovery/cloud-aws/go.mod +++ b/auto-discovery/cloud-aws/go.mod @@ -4,106 +4,105 @@ module github.com/secureCodeBox/secureCodeBox/auto-discovery/cloud-aws -go 1.24.2 +go 1.25.0 require ( - github.com/aws/aws-sdk-go v1.55.6 - github.com/go-logr/logr v1.4.2 + github.com/aws/aws-sdk-go v1.55.8 + github.com/go-logr/logr v1.4.3 github.com/novln/docker-parser v1.0.0 - github.com/onsi/ginkgo/v2 v2.23.4 - github.com/onsi/gomega v1.37.0 - github.com/secureCodeBox/secureCodeBox/auto-discovery/kubernetes v0.0.0-20231009114358-c5a65b0a38da - github.com/secureCodeBox/secureCodeBox/operator v0.0.0-20230926134536-ff777849ca12 - k8s.io/api v0.28.2 - k8s.io/client-go v0.28.2 - sigs.k8s.io/controller-runtime v0.16.2 - sigs.k8s.io/yaml v1.3.0 + github.com/onsi/ginkgo/v2 v2.28.1 + github.com/onsi/gomega v1.39.1 + github.com/secureCodeBox/secureCodeBox/auto-discovery/kubernetes v0.0.0-20250811150403-217d256e71c1 + github.com/secureCodeBox/secureCodeBox/operator v0.0.0-20250409151104-b2c7b64c9589 + k8s.io/api v0.35.0 + k8s.io/client-go v0.35.0 + k8s.io/klog/v2 v2.130.1 + sigs.k8s.io/controller-runtime v0.23.1 + sigs.k8s.io/yaml v1.6.0 ) require ( + github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver v1.5.0 // indirect + github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/Masterminds/sprig v2.22.0+incompatible // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/evanphx/json-patch v5.7.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.7.0 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/evanphx/json-patch/v5 v5.9.11 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/go-errors/errors v1.5.1 // indirect - github.com/go-logr/zapr v1.2.4 // indirect - github.com/go-openapi/jsonpointer v0.20.0 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.4 // indirect + github.com/go-logr/zapr v1.3.0 // indirect + github.com/go-openapi/jsonpointer v0.21.1 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/swag v0.23.1 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/google/btree v1.1.2 // indirect - github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/btree v1.1.3 // indirect + github.com/google/gnostic-models v0.7.0 // indirect github.com/google/go-cmp v0.7.0 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect - github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/google/uuid v1.3.1 // indirect + github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect - github.com/huandu/xstrings v1.3.2 // indirect + github.com/huandu/xstrings v1.5.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.16.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect - github.com/spf13/cobra v1.7.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_golang v1.23.2 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.66.1 // indirect + github.com/prometheus/procfs v0.16.1 // indirect + github.com/spf13/cobra v1.10.0 // indirect + github.com/spf13/pflag v1.0.9 // indirect + github.com/x448/float16 v0.8.4 // indirect github.com/xlab/treeprint v1.2.0 // indirect - go.starlark.net v0.0.0-20230925163745-10651d5192ab // indirect - go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/net v0.38.0 // indirect - golang.org/x/oauth2 v0.12.0 // indirect - golang.org/x/sync v0.12.0 // indirect - golang.org/x/sys v0.32.0 // indirect - golang.org/x/term v0.30.0 // indirect - golang.org/x/text v0.23.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.31.0 // indirect - gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/appengine v1.6.8 // indirect - google.golang.org/protobuf v1.36.5 // indirect + go.uber.org/zap v1.27.0 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/crypto v0.47.0 // indirect + golang.org/x/mod v0.32.0 // indirect + golang.org/x/net v0.49.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/term v0.39.0 // indirect + golang.org/x/text v0.33.0 // indirect + golang.org/x/time v0.11.0 // indirect + golang.org/x/tools v0.41.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.28.2 // indirect - k8s.io/component-base v0.28.2 // indirect - k8s.io/klog/v2 v2.100.1 // indirect - k8s.io/kube-openapi v0.0.0-20230918164632-68afd615200d // indirect - k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/kustomize/api v0.14.0 // indirect - sigs.k8s.io/kustomize/kyaml v0.14.3 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect + k8s.io/apiextensions-apiserver v0.35.0 // indirect + k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect + sigs.k8s.io/kustomize/api v0.20.1 // indirect + sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 // indirect ) require ( github.com/jmespath/go-jmespath v0.4.0 // indirect - k8s.io/apimachinery v0.28.2 - k8s.io/cli-runtime v0.28.2 + k8s.io/apimachinery v0.35.0 + k8s.io/cli-runtime v0.35.0 ) diff --git a/auto-discovery/cloud-aws/go.sum b/auto-discovery/cloud-aws/go.sum index bc64e248bd..a0675c8919 100644 --- a/auto-discovery/cloud-aws/go.sum +++ b/auto-discovery/cloud-aws/go.sum @@ -1,77 +1,77 @@ +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/aws/aws-sdk-go v1.55.6 h1:cSg4pvZ3m8dgYcgqB97MrcdjUmZ1BeMYKUxMMB89IPk= -github.com/aws/aws-sdk-go v1.55.6/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/aws/aws-sdk-go v1.55.8 h1:JRmEUbU52aJQZ2AjX4q4Wu7t4uZjOu71uyNmaWlUkJQ= +github.com/aws/aws-sdk-go v1.55.8/go.mod h1:ZkViS9AqA6otK+JBBNH2++sx1sgxrPKcSzPPvQkUtXk= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= +github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc= -github.com/evanphx/json-patch/v5 v5.7.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= +github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs= +github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= +github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= +github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk= +github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE= +github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc= github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= -github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= -github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= +github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic= +github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= +github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= +github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= -github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= -github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= +github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -82,33 +82,38 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE= +github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= +github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= +github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE= +github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= @@ -119,192 +124,135 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus= -github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8= -github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y= -github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= +github.com/onsi/ginkgo/v2 v2.28.1 h1:S4hj+HbZp40fNKuLUQOYLDgZLwNUVn19N3Atb98NCyI= +github.com/onsi/ginkgo/v2 v2.28.1/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE= +github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= +github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= -github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= +github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= +github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/secureCodeBox/secureCodeBox/auto-discovery/kubernetes v0.0.0-20231009114358-c5a65b0a38da h1:jMZHIeCu7cowf0phcI+1g11NWjt13ObbJKvE6Req/l0= -github.com/secureCodeBox/secureCodeBox/auto-discovery/kubernetes v0.0.0-20231009114358-c5a65b0a38da/go.mod h1:f3479yw9Dx8q7mPXxY5PA66jZtxkL6xCdHyT6P2XIdI= -github.com/secureCodeBox/secureCodeBox/operator v0.0.0-20230926134536-ff777849ca12 h1:lJvPbgFtwUi388WZ4XhA05EE0fk1L6PvvbpOrMi557g= -github.com/secureCodeBox/secureCodeBox/operator v0.0.0-20230926134536-ff777849ca12/go.mod h1:EQIJ+f9YITmYp1ZJQbPDg70yayr0oMC3X3nQoGkFg4s= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/secureCodeBox/secureCodeBox/auto-discovery/kubernetes v0.0.0-20250811150403-217d256e71c1 h1:RR7V/tWCsJPwVVrUssYsM9mvG7BdqzspN3fiZVbMI8E= +github.com/secureCodeBox/secureCodeBox/auto-discovery/kubernetes v0.0.0-20250811150403-217d256e71c1/go.mod h1:1yO4sAVFa6nBekvAs/yXvPqknKqdbYPhdFhS22tu8YM= +github.com/secureCodeBox/secureCodeBox/operator v0.0.0-20250409151104-b2c7b64c9589 h1:bA5TfYaqlHXqrDGAZJuIPVpC+BqUU4wKSJzrOH6V6oU= +github.com/secureCodeBox/secureCodeBox/operator v0.0.0-20250409151104-b2c7b64c9589/go.mod h1:C2aY0MPPrtn+VkOpWXJKpd+2xmFogMy4sjBH406XrDA= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/spf13/cobra v1.10.0 h1:a5/WeUlSDCvV5a45ljW2ZFtV0bTDpkfSAj3uqB6Sc+0= +github.com/spf13/cobra v1.10.0/go.mod h1:9dhySC7dnTtEiqzmqfkLj47BslqLCUPMXjG2lj/NgoE= +github.com/spf13/pflag v1.0.8/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.starlark.net v0.0.0-20230925163745-10651d5192ab h1:7QkXlIVjYdSsKKSGnM0jQdw/2w9W5qcFDGTc00zKqgI= -go.starlark.net v0.0.0-20230925163745-10651d5192ab/go.mod h1:LcLNIzVOMp4oV+uusnpk+VU+SzXaJakUuBjoCSWH5dM= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= -go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= -go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= -golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= -golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= -golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= -golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU= -golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= -gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= +golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= +golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= +golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= +golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= +golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= +golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= +gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= +gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= -k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= -k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= -k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= -k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= -k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= -k8s.io/cli-runtime v0.28.2 h1:64meB2fDj10/ThIMEJLO29a1oujSm0GQmKzh1RtA/uk= -k8s.io/cli-runtime v0.28.2/go.mod h1:bTpGOvpdsPtDKoyfG4EG041WIyFZLV9qq4rPlkyYfDA= -k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= -k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= -k8s.io/component-base v0.28.2 h1:Yc1yU+6AQSlpJZyvehm/NkJBII72rzlEsd6MkBQ+G0E= -k8s.io/component-base v0.28.2/go.mod h1:4IuQPQviQCg3du4si8GpMrhAIegxpsgPngPRR/zWpzc= -k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= -k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20230918164632-68afd615200d h1:/CFeJBjBrZvHX09rObS2+2iEEDevMWYc1v3aIYAjIYI= -k8s.io/kube-openapi v0.0.0-20230918164632-68afd615200d/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.16.2 h1:mwXAVuEk3EQf478PQwQ48zGOXvW27UJc8NHktQVuIPU= -sigs.k8s.io/controller-runtime v0.16.2/go.mod h1:vpMu3LpI5sYWtujJOa2uPK61nB5rbwlN7BAB8aSLvGU= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kustomize/api v0.14.0 h1:6+QLmXXA8X4eDM7ejeaNUyruA1DDB3PVIjbpVhDOJRA= -sigs.k8s.io/kustomize/api v0.14.0/go.mod h1:vmOXlC8BcmcUJQjiceUbcyQ75JBP6eg8sgoyzc+eLpQ= -sigs.k8s.io/kustomize/kyaml v0.14.3 h1:WpabVAKZe2YEp/irTSHwD6bfjwZnTtSDewd2BVJGMZs= -sigs.k8s.io/kustomize/kyaml v0.14.3/go.mod h1:npvh9epWysfQ689Rtt/U+dpOJDTBn8kUnF1O6VzvmZA= -sigs.k8s.io/structured-merge-diff/v4 v4.3.0 h1:UZbZAZfX0wV2zr7YZorDz6GXROfDFj6LvqCRm4VUVKk= -sigs.k8s.io/structured-merge-diff/v4 v4.3.0/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +k8s.io/api v0.35.0 h1:iBAU5LTyBI9vw3L5glmat1njFK34srdLmktWwLTprlY= +k8s.io/api v0.35.0/go.mod h1:AQ0SNTzm4ZAczM03QH42c7l3bih1TbAXYo0DkF8ktnA= +k8s.io/apiextensions-apiserver v0.35.0 h1:3xHk2rTOdWXXJM+RDQZJvdx0yEOgC0FgQ1PlJatA5T4= +k8s.io/apiextensions-apiserver v0.35.0/go.mod h1:E1Ahk9SADaLQ4qtzYFkwUqusXTcaV2uw3l14aqpL2LU= +k8s.io/apimachinery v0.35.0 h1:Z2L3IHvPVv/MJ7xRxHEtk6GoJElaAqDCCU0S6ncYok8= +k8s.io/apimachinery v0.35.0/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= +k8s.io/cli-runtime v0.35.0 h1:PEJtYS/Zr4p20PfZSLCbY6YvaoLrfByd6THQzPworUE= +k8s.io/cli-runtime v0.35.0/go.mod h1:VBRvHzosVAoVdP3XwUQn1Oqkvaa8facnokNkD7jOTMY= +k8s.io/client-go v0.35.0 h1:IAW0ifFbfQQwQmga0UdoH0yvdqrbwMdq9vIFEhRpxBE= +k8s.io/client-go v0.35.0/go.mod h1:q2E5AAyqcbeLGPdoRB+Nxe3KYTfPce1Dnu1myQdqz9o= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE= +sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I= +sigs.k8s.io/kustomize/api v0.20.1/go.mod h1:t6hUFxO+Ph0VxIk1sKp1WS0dOjbPCtLJ4p8aADLwqjM= +sigs.k8s.io/kustomize/kyaml v0.20.1 h1:PCMnA2mrVbRP3NIB6v9kYCAc38uvFLVs8j/CD567A78= +sigs.k8s.io/kustomize/kyaml v0.20.1/go.mod h1:0EmkQHRUsJxY8Ug9Niig1pUMSCGHxQ5RklbpV/Ri6po= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 h1:2WOzJpHUBVrrkDjU4KBT8n5LDcj824eX0I5UKcgeRUs= +sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/auto-discovery/cloud-aws/pkg/config/config.go b/auto-discovery/cloud-aws/pkg/config/config.go index 3a088477f4..bbc94d4088 100644 --- a/auto-discovery/cloud-aws/pkg/config/config.go +++ b/auto-discovery/cloud-aws/pkg/config/config.go @@ -7,7 +7,7 @@ package config import ( "os" - configv1 "github.com/secureCodeBox/secureCodeBox/auto-discovery/kubernetes/api/v1" + autoDiscoveryConfig "github.com/secureCodeBox/secureCodeBox/auto-discovery/kubernetes/pkg/config" "sigs.k8s.io/yaml" ) @@ -22,10 +22,13 @@ type AwsConfig struct { } type KubernetesConfig struct { - Namespace string `json:"namespace"` - ScanConfigs []configv1.ScanConfig `json:"scanConfigs"` + Namespace string `json:"namespace"` + ScanConfigs []autoDiscoveryConfig.ScanConfig `json:"scanConfigs"` } +// Re-export ScanConfig for convenience +type ScanConfig = autoDiscoveryConfig.ScanConfig + func GetConfig(configFile string) AutoDiscoveryConfig { filecontent, err := os.ReadFile(configFile) if err != nil { diff --git a/auto-discovery/cloud-aws/pkg/kubernetes/kubernetes.go b/auto-discovery/cloud-aws/pkg/kubernetes/kubernetes.go index e26373dbd2..6efb2aceca 100644 --- a/auto-discovery/cloud-aws/pkg/kubernetes/kubernetes.go +++ b/auto-discovery/cloud-aws/pkg/kubernetes/kubernetes.go @@ -11,7 +11,6 @@ import ( "github.com/go-logr/logr" "github.com/secureCodeBox/secureCodeBox/auto-discovery/cloud-aws/pkg/config" - configv1 "github.com/secureCodeBox/secureCodeBox/auto-discovery/kubernetes/api/v1" "github.com/secureCodeBox/secureCodeBox/auto-discovery/kubernetes/pkg/util" executionv1 "github.com/secureCodeBox/secureCodeBox/operator/apis/execution/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -63,7 +62,7 @@ type CloudScanReconciler struct { // AutoDiscovery, but not all values offered there make sense here. type ContainerAutoDiscoveryTemplateArgs struct { Config config.AutoDiscoveryConfig - ScanConfig configv1.ScanConfig + ScanConfig config.ScanConfig Target ContainerInfo Image ImageDetails ImageID string @@ -203,7 +202,7 @@ func (r *CloudScanReconciler) deleteScheduledScan(ctx context.Context, name stri } // Generate a ScheduledScan based on the config and template values for a request the Reconciler received -func getScheduledScanForRequest(req Request, cfg *config.AutoDiscoveryConfig, scanConfig configv1.ScanConfig) *executionv1.ScheduledScan { +func getScheduledScanForRequest(req Request, cfg *config.AutoDiscoveryConfig, scanConfig config.ScanConfig) *executionv1.ScheduledScan { templateArgs := ContainerAutoDiscoveryTemplateArgs{ Config: *cfg, ScanConfig: scanConfig, @@ -252,12 +251,12 @@ func getScanName(req Request, name string) string { } // Templating helper function taken from the kubernetes AutoDiscovery -func getScanAnnotations(scanConfig configv1.ScanConfig, templateArgs ContainerAutoDiscoveryTemplateArgs) map[string]string { +func getScanAnnotations(scanConfig config.ScanConfig, templateArgs ContainerAutoDiscoveryTemplateArgs) map[string]string { return util.ParseMapTemplate(templateArgs, scanConfig.Annotations) } // Templating helper function taken from the kubernetes AutoDiscovery -func getScanLabels(scanConfig configv1.ScanConfig, templateArgs ContainerAutoDiscoveryTemplateArgs) map[string]string { +func getScanLabels(scanConfig config.ScanConfig, templateArgs ContainerAutoDiscoveryTemplateArgs) map[string]string { generatedLabels := util.ParseMapTemplate(templateArgs, scanConfig.Labels) generatedLabels["app.kubernetes.io/managed-by"] = "securecodebox-autodiscovery" diff --git a/auto-discovery/kubernetes/Dockerfile b/auto-discovery/kubernetes/Dockerfile index 68f2c12ea0..b2373d5ed0 100644 --- a/auto-discovery/kubernetes/Dockerfile +++ b/auto-discovery/kubernetes/Dockerfile @@ -3,7 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 # Build the manager binary -FROM golang:1.24.2 AS builder +FROM --platform=$BUILDPLATFORM golang:1.25.7 AS builder WORKDIR /workspace # Copy the Go Modules manifests @@ -19,7 +19,8 @@ COPY controllers/ controllers/ COPY pkg/ pkg/ # Build -RUN CGO_ENABLED=0 go build -a -o manager main.go +ARG TARGETOS TARGETARCH +RUN GOOS="$TARGETOS" GOARCH="$TARGETARCH" CGO_ENABLED=0 go build -a -o manager main.go # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details diff --git a/auto-discovery/kubernetes/controllers/container_scan_controller.go b/auto-discovery/kubernetes/controllers/container_scan_controller.go index 736a5f4841..771d6ad48d 100644 --- a/auto-discovery/kubernetes/controllers/container_scan_controller.go +++ b/auto-discovery/kubernetes/controllers/container_scan_controller.go @@ -335,8 +335,7 @@ func getSecretExtractionInitContainer(imageID string, scanConfig config.ScanConf return corev1.Container{ Name: "secret-extraction-to-env", Image: "docker.io/securecodebox/auto-discovery-pull-secret-extractor", - Command: []string{"python"}, - Args: []string{"secret_extraction.py", imageID, temporarySecretName}, + Args: []string{"-imageID", imageID, "-secret", temporarySecretName}, VolumeMounts: volumeMounts, Env: []corev1.EnvVar{ { @@ -355,6 +354,14 @@ func getSecretExtractionInitContainer(imageID string, scanConfig config.ScanConf }, }, }, + { + Name: "POD_UID", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + FieldPath: "metadata.uid", + }, + }, + }, }, } } diff --git a/auto-discovery/kubernetes/go.mod b/auto-discovery/kubernetes/go.mod index 0b652aadce..16b9e15a39 100644 --- a/auto-discovery/kubernetes/go.mod +++ b/auto-discovery/kubernetes/go.mod @@ -4,40 +4,39 @@ module github.com/secureCodeBox/secureCodeBox/auto-discovery/kubernetes -go 1.24.2 +go 1.25.0 require ( github.com/Masterminds/sprig v2.22.0+incompatible github.com/go-logr/logr v1.4.3 github.com/onsi/ginkgo v1.16.5 - github.com/onsi/gomega v1.37.0 + github.com/onsi/gomega v1.39.1 github.com/secureCodeBox/secureCodeBox/operator v0.0.0-20250409151104-b2c7b64c9589 - k8s.io/api v0.33.2 - k8s.io/apimachinery v0.33.2 - k8s.io/client-go v0.33.2 - k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e - sigs.k8s.io/controller-runtime v0.21.0 - sigs.k8s.io/yaml v1.5.0 + k8s.io/api v0.35.0 + k8s.io/apimachinery v0.35.0 + k8s.io/client-go v0.35.0 + k8s.io/klog/v2 v2.130.1 + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 + sigs.k8s.io/controller-runtime v0.23.1 + sigs.k8s.io/yaml v1.6.0 ) require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver v1.5.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/blang/semver/v4 v4.0.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/fxamacker/cbor/v2 v2.8.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.21.1 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.1 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/google/btree v1.1.3 // indirect - github.com/google/gnostic-models v0.6.9 // indirect + github.com/google/gnostic-models v0.7.0 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect @@ -48,38 +47,37 @@ require ( github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/nxadm/tail v1.4.8 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.22.0 // indirect - github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.63.0 // indirect - github.com/prometheus/procfs v0.16.0 // indirect - github.com/spf13/pflag v1.0.6 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_golang v1.23.2 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.66.1 // indirect + github.com/prometheus/procfs v0.16.1 // indirect + github.com/spf13/pflag v1.0.9 // indirect github.com/x448/float16 v0.8.4 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/crypto v0.37.0 // indirect - golang.org/x/net v0.39.0 // indirect - golang.org/x/oauth2 v0.29.0 // indirect - golang.org/x/sync v0.13.0 // indirect - golang.org/x/sys v0.32.0 // indirect - golang.org/x/term v0.31.0 // indirect - golang.org/x/text v0.24.0 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/crypto v0.47.0 // indirect + golang.org/x/net v0.49.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/term v0.39.0 // indirect + golang.org/x/text v0.33.0 // indirect golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.32.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/protobuf v1.36.6 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.33.0 // indirect - k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/apiextensions-apiserver v0.35.0 // indirect + k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 // indirect ) diff --git a/auto-discovery/kubernetes/go.sum b/auto-discovery/kubernetes/go.sum index 6811bb82a8..090c2a7a4d 100644 --- a/auto-discovery/kubernetes/go.sum +++ b/auto-discovery/kubernetes/go.sum @@ -2,12 +2,12 @@ github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJ github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -24,8 +24,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU= -github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= @@ -40,8 +40,6 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8Wd github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -51,19 +49,18 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= -github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= +github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= +github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -75,8 +72,6 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -94,8 +89,9 @@ github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -105,40 +101,39 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.23.3 h1:edHxnszytJ4lD9D5Jjc4tiDkPBZ3siDeJJkUZJJVkp0= -github.com/onsi/ginkgo/v2 v2.23.3/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM= +github.com/onsi/ginkgo/v2 v2.28.0 h1:Rrf+lVLmtlBIKv6KrIGJCjyY8N36vDVcutbGJkyqjJc= +github.com/onsi/ginkgo/v2 v2.28.0/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y= -github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= +github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= +github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= -github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= -github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= -github.com/prometheus/procfs v0.16.0 h1:xh6oHhKwnOJKMYiYBDWmkHqQPyiY40sny36Cmx2bbsM= -github.com/prometheus/procfs v0.16.0/go.mod h1:8veyXUu3nGP7oaCxhX6yeaM5u4stL2FeMXnCqhDthZg= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= +github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= +github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/secureCodeBox/secureCodeBox/operator v0.0.0-20250409151104-b2c7b64c9589 h1:bA5TfYaqlHXqrDGAZJuIPVpC+BqUU4wKSJzrOH6V6oU= github.com/secureCodeBox/secureCodeBox/operator v0.0.0-20250409151104-b2c7b64c9589/go.mod h1:C2aY0MPPrtn+VkOpWXJKpd+2xmFogMy4sjBH406XrDA= -github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= -github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -146,33 +141,32 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= -go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= -go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= -golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= +golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= +golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= -golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= -golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98= -golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -182,23 +176,21 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= -golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= -golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= +golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= -golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU= -golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s= +golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= +golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -211,13 +203,13 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= @@ -228,29 +220,27 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.33.2 h1:YgwIS5jKfA+BZg//OQhkJNIfie/kmRsO0BmNaVSimvY= -k8s.io/api v0.33.2/go.mod h1:fhrbphQJSM2cXzCWgqU29xLDuks4mu7ti9vveEnpSXs= -k8s.io/apiextensions-apiserver v0.33.0 h1:d2qpYL7Mngbsc1taA4IjJPRJ9ilnsXIrndH+r9IimOs= -k8s.io/apiextensions-apiserver v0.33.0/go.mod h1:VeJ8u9dEEN+tbETo+lFkwaaZPg6uFKLGj5vyNEwwSzc= -k8s.io/apimachinery v0.33.2 h1:IHFVhqg59mb8PJWTLi8m1mAoepkUNYmptHsV+Z1m5jY= -k8s.io/apimachinery v0.33.2/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= -k8s.io/client-go v0.33.2 h1:z8CIcc0P581x/J1ZYf4CNzRKxRvQAwoAolYPbtQes+E= -k8s.io/client-go v0.33.2/go.mod h1:9mCgT4wROvL948w6f6ArJNb7yQd7QsvqavDeZHvNmHo= +k8s.io/api v0.35.0 h1:iBAU5LTyBI9vw3L5glmat1njFK34srdLmktWwLTprlY= +k8s.io/api v0.35.0/go.mod h1:AQ0SNTzm4ZAczM03QH42c7l3bih1TbAXYo0DkF8ktnA= +k8s.io/apiextensions-apiserver v0.35.0 h1:3xHk2rTOdWXXJM+RDQZJvdx0yEOgC0FgQ1PlJatA5T4= +k8s.io/apiextensions-apiserver v0.35.0/go.mod h1:E1Ahk9SADaLQ4qtzYFkwUqusXTcaV2uw3l14aqpL2LU= +k8s.io/apimachinery v0.35.0 h1:Z2L3IHvPVv/MJ7xRxHEtk6GoJElaAqDCCU0S6ncYok8= +k8s.io/apimachinery v0.35.0/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= +k8s.io/client-go v0.35.0 h1:IAW0ifFbfQQwQmga0UdoH0yvdqrbwMdq9vIFEhRpxBE= +k8s.io/client-go v0.35.0/go.mod h1:q2E5AAyqcbeLGPdoRB+Nxe3KYTfPce1Dnu1myQdqz9o= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= -k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro= -k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= -sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= -sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE= +sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= -sigs.k8s.io/yaml v1.5.0 h1:M10b2U7aEUY6hRtU870n2VTPgR5RZiL/I6Lcc2F4NUQ= -sigs.k8s.io/yaml v1.5.0/go.mod h1:wZs27Rbxoai4C0f8/9urLZtZtF3avA3gKvGyPdDqTO4= +sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 h1:2WOzJpHUBVrrkDjU4KBT8n5LDcj824eX0I5UKcgeRUs= +sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/auto-discovery/kubernetes/main.go b/auto-discovery/kubernetes/main.go index 9ca6b5ee3f..84e9e601bd 100644 --- a/auto-discovery/kubernetes/main.go +++ b/auto-discovery/kubernetes/main.go @@ -16,6 +16,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" + "k8s.io/klog/v2" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/metrics/server" @@ -45,12 +46,14 @@ func main() { "Omit this flag to use the default configuration values. "+ "Command-line flags override configuration from this file.") opts := zap.Options{ - Development: true, + Development: false, } opts.BindFlags(flag.CommandLine) flag.Parse() - ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + logger := zap.New(zap.UseFlagOptions(&opts)) + ctrl.SetLogger(logger) + klog.SetLogger(logger) ctrlConfig, err := util.LoadAutoDiscoveryConfig(configFile) if err != nil { diff --git a/auto-discovery/kubernetes/pull-secret-extractor/.dockerignore b/auto-discovery/kubernetes/pull-secret-extractor/.dockerignore index ee0eeed1b3..c8ebc7c57a 100644 --- a/auto-discovery/kubernetes/pull-secret-extractor/.dockerignore +++ b/auto-discovery/kubernetes/pull-secret-extractor/.dockerignore @@ -2,5 +2,4 @@ // // SPDX-License-Identifier: Apache-2.0 -integration-test/* -venv/* \ No newline at end of file +venv/* diff --git a/auto-discovery/kubernetes/pull-secret-extractor/Dockerfile b/auto-discovery/kubernetes/pull-secret-extractor/Dockerfile index 54efd3e020..3d92c15bb7 100644 --- a/auto-discovery/kubernetes/pull-secret-extractor/Dockerfile +++ b/auto-discovery/kubernetes/pull-secret-extractor/Dockerfile @@ -2,9 +2,29 @@ # # SPDX-License-Identifier: Apache-2.0 -FROM python:3.11-alpine +# Build the pull-secret-extractor binary +FROM --platform=$BUILDPLATFORM golang:1.25.7 AS builder -COPY requirements.txt . -RUN pip install -r requirements.txt -COPY docker_image.py secret_extraction.py ./ -CMD ["python", secret_extraction.py] +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +COPY main.go main.go +COPY internal/ internal/ + +# Build +ARG TARGETOS TARGETARCH +RUN GOOS="$TARGETOS" GOARCH="$TARGETARCH" CGO_ENABLED=0 go build -a -o secret_extraction main.go + +# Use distroless as minimal base image to package the manager binary +# Refer to https://github.com/GoogleContainerTools/distroless for more details +FROM gcr.io/distroless/static:nonroot +WORKDIR / +COPY --from=builder /workspace/secret_extraction . + +ENTRYPOINT ["/secret_extraction"] diff --git a/auto-discovery/kubernetes/pull-secret-extractor/Makefile b/auto-discovery/kubernetes/pull-secret-extractor/Makefile deleted file mode 100644 index 2f2b2b0dbb..0000000000 --- a/auto-discovery/kubernetes/pull-secret-extractor/Makefile +++ /dev/null @@ -1,76 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -include ../../../prerequisites.mk - -IMG_NS ?= securecodebox - -# Image URL to use all building/pushing image targets -IMG ?= auto-discovery-secret-extractor - -# Tag used for the image -IMG_TAG ?= sha-$$(git rev-parse --short HEAD) - - -##@ General - -# The help target prints out all targets with their descriptions organized -# beneath their categories. The categories are represented by '##@' and the -# target descriptions by '##'. The awk commands is responsible for reading the -# entire set of makefiles included in this invocation, looking for lines of the -# file as xyz: ## something, and then pretty-format the target and help. Then, -# if there's a line with ##@ something, that gets pretty-printed as a category. -# More info on the usage of ANSI control characters for terminal formatting: -# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters -# More info on the awk command: -# http://linuxcommand.org/lc3_adv_awk.php - -.PHONY: help -help: ## Display this help. - @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) - - -##@ Development - -.PHONY: test -test: unit-test integration-test - -.PHONY: unit-test -unit-test: - $(PYTHON) -m unittest discover - -.PHONY: integration-test -integration-test: docker-build docker-export kind-import - @echo ".: 🩺 Starting integration test in kind namespace 'integration-tests'." - kubectl delete namespace integration-test --wait || true - kubectl create namespace integration-test - - ./integration-test/test-pod.sh ${IMG_NS}/${IMG}:${IMG_TAG} - kubectl wait --for=condition=ready --timeout=60s -n integration-test pod/init-container-test - - kubectl get secret --namespace integration-test test-secret - -##@ Build - - -.PHONY: docker-build -docker-build: ## Build docker image with the manager. - @echo ".: ⚙️ Build Container Images" - docker build -t ${IMG_NS}/${IMG}:${IMG_TAG} . - -.PHONY: docker-push -docker-push: ## Push docker image with the manager. - docker push ${IMG_NS}/${IMG}:${IMG_TAG} - -.PHONY: docker-export -docker-export: - @echo ".: 💾 Export Container Images" - docker save $(IMG_NS)/$(IMG):$(IMG_TAG) > $(IMG).tar - -##@ Deployment - -.PHONY: kind-import -kind-import: - @echo ".: 💾 Importing the image archive to local kind cluster." - kind load image-archive ./$(IMG).tar \ No newline at end of file diff --git a/auto-discovery/kubernetes/pull-secret-extractor/Taskfile.yaml b/auto-discovery/kubernetes/pull-secret-extractor/Taskfile.yaml new file mode 100644 index 0000000000..32e0f12a7d --- /dev/null +++ b/auto-discovery/kubernetes/pull-secret-extractor/Taskfile.yaml @@ -0,0 +1,78 @@ +# SPDX-FileCopyrightText: the secureCodeBox authors +# +# SPDX-License-Identifier: Apache-2.0 + +version: "3.44.0" + +vars: + IMG_NS: '{{default "securecodebox" .IMG_NS}}' + IMG: '{{default "auto-discovery-secret-extractor" .IMG}}' + IMG_TAG: + sh: echo "${IMG_TAG:-sha-$(git rev-parse --short HEAD)}" + FULL_IMAGE: "{{.IMG_NS}}/{{.IMG}}/{{.IMG_TAG}}" + +tasks: + unit-test: + desc: Run unit tests + cmds: + - go test ./... + + integration-test: + desc: Run integration tests in kind cluster + deps: + - kind-import + cmds: + - defer: task clean + - 'echo "🩺 Starting integration test in kind namespace integration-tests."' + - cmd: kubectl delete namespace integration-test --wait + ignore_error: true + - kubectl create namespace integration-test + - ./test/integration/test-pod.sh {{.IMG_NS}}/{{.IMG}}:{{.IMG_TAG}} + - kubectl wait --for=condition=ready --timeout=60s -n integration-test pod/init-container-test + - kubectl get secret --namespace integration-test test-secret + + test: + desc: Run all tests (unit and integration) + deps: + - unit-test + - integration-test + + docker-build: + desc: Build docker image with the manager + cmds: + - 'echo "⚙️ Build Container Images"' + - docker build -t {{.IMG_NS}}/{{.IMG}}:{{.IMG_TAG}} . + + docker-export: + desc: Export container image to tar archive + deps: + - docker-build + cmds: + - 'echo "💾 Export Container Images"' + - docker save {{.IMG_NS}}/{{.IMG}}:{{.IMG_TAG}} > {{.IMG}}.tar + + kind-import: + desc: Import container image to local kind cluster + deps: + - docker-export + preconditions: + - sh: test -f {{.IMG}}.tar + msg: "Image archive {{.IMG}}.tar not found. Run 'task docker-export' first." + cmds: + - 'echo "💾 Importing the image archive to local kind cluster."' + - kind load image-archive ./{{.IMG}}.tar + + clean: + desc: Clean up generated files + cmds: + - rm -f {{.IMG}}.tar + + vars: + desc: Display current variable values (useful for debugging) + cmds: + - | + echo "Current variable values:" + echo " IMG_NS: {{.IMG_NS}}" + echo " IMG: {{.IMG}}" + echo " IMG_TAG: {{.IMG_TAG}}" + echo " FULL_IMAGE: {{.IMG_NS}}/{{.IMG}}:{{.IMG_TAG}}" diff --git a/auto-discovery/kubernetes/pull-secret-extractor/docker_image.py b/auto-discovery/kubernetes/pull-secret-extractor/docker_image.py deleted file mode 100644 index d8a8039ff0..0000000000 --- a/auto-discovery/kubernetes/pull-secret-extractor/docker_image.py +++ /dev/null @@ -1,33 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -legacyDefaultDomain = "index.docker.io" -defaultDomain = "docker.io" -officialRepoName = "library" -defaultTag = "latest" - - -def get_domain_from_docker_image(name: str) -> str: - """ - Extracts domain and image from a given docker image. Has the same defaulting behavior when it comes to docker.io image as containerd - Code adapted from https://github.com/containerd/containerd/blob/20de989afcd2fd4edc20e9b85312e49a8bbe152b/reference/docker/normalize.go#L102-L119 - :param name: docker image - :return: tuple container domain and image - """ - try: - i = name.index('/') - except ValueError: - i = -1 - - name_slice = name[:i] - if i == -1 or ':' not in name_slice and '.' not in name_slice and name_slice != 'localhost' and name_slice.lower() == name_slice: - domain = defaultDomain - else: - domain = name[:i] - - if domain == legacyDefaultDomain: - domain = defaultDomain - - return domain - diff --git a/auto-discovery/kubernetes/pull-secret-extractor/go.mod b/auto-discovery/kubernetes/pull-secret-extractor/go.mod new file mode 100644 index 0000000000..8151c1bdc7 --- /dev/null +++ b/auto-discovery/kubernetes/pull-secret-extractor/go.mod @@ -0,0 +1,56 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +module github.com/secureCodeBox/auto-discovery/kubernetes/pull-secret-extractor + +go 1.24.5 + +require ( + k8s.io/api v0.34.0 + k8s.io/apimachinery v0.34.0 + sigs.k8s.io/controller-runtime v0.22.1 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/evanphx/json-patch/v5 v5.9.11 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/spf13/pflag v1.0.6 // indirect + github.com/x448/float16 v0.8.4 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/net v0.38.0 // indirect + golang.org/x/oauth2 v0.27.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/term v0.30.0 // indirect + golang.org/x/text v0.23.0 // indirect + golang.org/x/time v0.9.0 // indirect + google.golang.org/protobuf v1.36.5 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/client-go v0.34.0 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect + k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect + sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect +) diff --git a/auto-discovery/kubernetes/pull-secret-extractor/go.sum b/auto-discovery/kubernetes/pull-secret-extractor/go.sum new file mode 100644 index 0000000000..7f305f9954 --- /dev/null +++ b/auto-discovery/kubernetes/pull-secret-extractor/go.sum @@ -0,0 +1,180 @@ +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= +github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= +github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= +github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= +github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= +github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= +github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= +github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= +golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= +golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/api v0.34.0 h1:L+JtP2wDbEYPUeNGbeSa/5GwFtIA662EmT2YSLOkAVE= +k8s.io/api v0.34.0/go.mod h1:YzgkIzOOlhl9uwWCZNqpw6RJy9L2FK4dlJeayUoydug= +k8s.io/apiextensions-apiserver v0.34.0 h1:B3hiB32jV7BcyKcMU5fDaDxk882YrJ1KU+ZSkA9Qxoc= +k8s.io/apiextensions-apiserver v0.34.0/go.mod h1:hLI4GxE1BDBy9adJKxUxCEHBGZtGfIg98Q+JmTD7+g0= +k8s.io/apimachinery v0.34.0 h1:eR1WO5fo0HyoQZt1wdISpFDffnWOvFLOOeJ7MgIv4z0= +k8s.io/apimachinery v0.34.0/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.0 h1:YoWv5r7bsBfb0Hs2jh8SOvFbKzzxyNo0nSb0zC19KZo= +k8s.io/client-go v0.34.0/go.mod h1:ozgMnEKXkRjeMvBZdV1AijMHLTh3pbACPvK7zFR+QQY= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA= +k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.22.1 h1:Ah1T7I+0A7ize291nJZdS1CabF/lB4E++WizgV24Eqg= +sigs.k8s.io/controller-runtime v0.22.1/go.mod h1:FwiwRjkRPbiN+zp2QRp7wlTCzbUXxZ/D4OzuQUDwBHY= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/auto-discovery/kubernetes/pull-secret-extractor/requirements.txt.license b/auto-discovery/kubernetes/pull-secret-extractor/go.sum.license similarity index 100% rename from auto-discovery/kubernetes/pull-secret-extractor/requirements.txt.license rename to auto-discovery/kubernetes/pull-secret-extractor/go.sum.license diff --git a/auto-discovery/kubernetes/pull-secret-extractor/internal/docker_image/docker_image.go b/auto-discovery/kubernetes/pull-secret-extractor/internal/docker_image/docker_image.go new file mode 100644 index 0000000000..7993644919 --- /dev/null +++ b/auto-discovery/kubernetes/pull-secret-extractor/internal/docker_image/docker_image.go @@ -0,0 +1,46 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +package docker_image + +import ( + "strings" +) + +const ( + legacyDefaultDomain = "index.docker.io" + defaultDomain = "docker.io" + officialRepoName = "library" + defaultTag = "latest" +) + +// GetDomainFromDockerImage extracts domain from a given docker image. +// Has the same defaulting behavior when it comes to docker.io image as containerd. +// Code adapted from https://github.com/containerd/containerd/blob/20de989afcd2fd4edc20e9b85312e49a8bbe152b/reference/docker/normalize.go#L102-L119 +func GetDomainFromDockerImage(name string) string { + i := strings.Index(name, "/") + + var domain string + + if i == -1 { + domain = defaultDomain + } else { + nameSlice := name[:i] + + if !strings.Contains(nameSlice, ":") && + !strings.Contains(nameSlice, ".") && + nameSlice != "localhost" && + strings.ToLower(nameSlice) == nameSlice { + domain = defaultDomain + } else { + domain = nameSlice + } + } + + if domain == legacyDefaultDomain { + domain = defaultDomain + } + + return domain +} diff --git a/auto-discovery/kubernetes/pull-secret-extractor/internal/docker_image/docker_image_test.go b/auto-discovery/kubernetes/pull-secret-extractor/internal/docker_image/docker_image_test.go new file mode 100644 index 0000000000..fbe1668e8c --- /dev/null +++ b/auto-discovery/kubernetes/pull-secret-extractor/internal/docker_image/docker_image_test.go @@ -0,0 +1,45 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +package docker_image + +import "testing" + +func TestGetDomainFromDockerImage(t *testing.T) { + testCases := []struct { + name string + image string + expected string + }{ + { + name: "image with no domain", + image: "foo/bar", + expected: "docker.io", + }, + { + name: "image with docker.io domain", + image: "docker.io/foo/bar", + expected: "docker.io", + }, + { + name: "image with non-docker.io domain", + image: "test.xyz/foo/bar", + expected: "test.xyz", + }, + { + name: "single word image", + image: "ubuntu", + expected: "docker.io", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + result := GetDomainFromDockerImage(tc.image) + if result != tc.expected { + t.Errorf("GetDomainFromDockerImage(%q) = %q; want %q", tc.image, result, tc.expected) + } + }) + } +} diff --git a/auto-discovery/kubernetes/pull-secret-extractor/internal/secret_extraction/secret_extraction.go b/auto-discovery/kubernetes/pull-secret-extractor/internal/secret_extraction/secret_extraction.go new file mode 100644 index 0000000000..83b7e3eaee --- /dev/null +++ b/auto-discovery/kubernetes/pull-secret-extractor/internal/secret_extraction/secret_extraction.go @@ -0,0 +1,243 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +package secret_extraction + +import ( + "context" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "os" + "path/filepath" + "strings" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/config" +) + +// Constants for config +const ( + dockerConfigFileName = ".dockerconfigjson" + defaultSecretsPath = "/secrets" +) + +// Env variable names +const ( + envPodName = "POD_NAME" + envNameSpace = "NAMESPACE" +) + +type DockerConfigJSON struct { + Auths map[string]AuthEntry `json:"auths"` +} + +type AuthEntry struct { + Auth string `json:"auth,omitempty"` + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty"` +} + +type Credentials struct { + Username string + Password string +} + +func CreateTemporarySecret(ctx context.Context, k8sClient client.Client, temporarySecretName, domain, namespace, podName, podUID, secretsPath string) error { + if temporarySecretName == "" { + return fmt.Errorf("temporary secret name cannot be empty") + } + + if domain == "" { + return fmt.Errorf("domain cannot be empty") + } + + configs, err := readDockerConfigs(secretsPath) + if err != nil { + return fmt.Errorf("failed to read Docker configs: %w", err) + } + + authEntry := findAuthForDomain(domain, configs) + if authEntry == nil { + return fmt.Errorf("no authentication found for domain: %s", domain) + } + + creds, err := extractCredentials(authEntry) + if err != nil { + return fmt.Errorf("failed to extract credentials for domain %s: %w", domain, err) + } + + secret, err := buildSecret(ctx, k8sClient, temporarySecretName, namespace, podName, podUID, creds) + if err != nil { + return fmt.Errorf("failed to build secret: %w", err) + } + + if err := k8sClient.Create(ctx, secret); err != nil { + return fmt.Errorf("failed to create temporary secret: %w", err) + } + + return nil +} + +func readDockerConfigs(basePath string) ([]DockerConfigJSON, error) { + var configs []DockerConfigJSON + + err := filepath.Walk(basePath, func(path string, info os.FileInfo, err error) error { + if err != nil { + fmt.Printf("Warning: error accessing path %s: %v\n", path, err) + return nil + } + + if info.IsDir() || filepath.Base(path) != dockerConfigFileName { + return nil + } + + config, err := readSingleConfig(path) + if err != nil { + fmt.Printf("Warning: failed to read config from %s: %v\n", path, err) + return nil + } + + configs = append(configs, *config) + return nil + }) + + if err != nil { + return nil, fmt.Errorf("failed to walk directory %s: %w", basePath, err) + } + + return configs, nil +} + +func readSingleConfig(path string) (*DockerConfigJSON, error) { + file, err := os.Open(path) + if err != nil { + return nil, fmt.Errorf("failed to open file: %w", err) + } + defer file.Close() + + data, err := io.ReadAll(file) + if err != nil { + return nil, fmt.Errorf("failed to read file: %w", err) + } + + var config DockerConfigJSON + if err := json.Unmarshal(data, &config); err != nil { + return nil, fmt.Errorf("failed to parse JSON: %w", err) + } + + return &config, nil +} + +func findAuthForDomain(domain string, configs []DockerConfigJSON) *AuthEntry { + for _, config := range configs { + if auth, exists := config.Auths[domain]; exists { + return &auth + } + } + return nil +} + +func extractCredentials(auth *AuthEntry) (*Credentials, error) { + if auth == nil { + return nil, fmt.Errorf("auth entry is nil") + } + + if auth.Auth != "" { + decoded, err := base64.StdEncoding.DecodeString(auth.Auth) + if err != nil { + return nil, fmt.Errorf("failed to decode auth field: %w", err) + } + + parts := strings.SplitN(string(decoded), ":", 2) + if len(parts) != 2 { + return nil, fmt.Errorf("invalid auth format, expected username:password") + } + + return &Credentials{ + Username: parts[0], + Password: parts[1], + }, nil + } + + if auth.Username != "" && auth.Password != "" { + return &Credentials{ + Username: auth.Username, + Password: auth.Password, + }, nil + } + + return nil, fmt.Errorf("auth entry does not contain valid credentials") +} + +func buildSecret(ctx context.Context, k8sClient client.Client, secretName, namespace, podName, podUID string, creds *Credentials) (*v1.Secret, error) { + return &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName, + Namespace: namespace, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "v1", + Kind: "Pod", + Name: podName, + UID: types.UID(podUID), + }, + }, + }, + StringData: map[string]string{ + "username": creds.Username, + "password": creds.Password, + }, + Type: v1.SecretTypeOpaque, + }, nil +} + +func createK8sClient() (client.Client, error) { + cfg, err := config.GetConfig() + if err != nil { + return nil, fmt.Errorf("failed to get Kubernetes config: %w", err) + } + + scheme := runtime.NewScheme() + if err := v1.AddToScheme(scheme); err != nil { + return nil, fmt.Errorf("failed to add core v1 to scheme: %w", err) + } + + k8sClient, err := client.New(cfg, client.Options{Scheme: scheme}) + if err != nil { + return nil, fmt.Errorf("failed to create Kubernetes client: %w", err) + } + + return k8sClient, nil +} + +func CreateTemporarySecretFromEnv(temporarySecretName, domain string) error { + namespace := os.Getenv(envNameSpace) + if namespace == "" { + return fmt.Errorf("environment variable %s is not set", envNameSpace) + } + + podName := os.Getenv(envPodName) + if podName == "" { + return fmt.Errorf("environment variable %s is not set", envPodName) + } + + podUID := os.Getenv("POD_UID") + if podUID == "" { + return fmt.Errorf("environment variable %s is not set", podUID) + } + + k8sClient, err := createK8sClient() + if err != nil { + return fmt.Errorf("failed to create Kubernetes client: %w", err) + } + + ctx := context.Background() + return CreateTemporarySecret(ctx, k8sClient, temporarySecretName, domain, namespace, podName, podUID, defaultSecretsPath) +} diff --git a/auto-discovery/kubernetes/pull-secret-extractor/internal/secret_extraction/secret_extraction_test.go b/auto-discovery/kubernetes/pull-secret-extractor/internal/secret_extraction/secret_extraction_test.go new file mode 100644 index 0000000000..99ecb9ffb6 --- /dev/null +++ b/auto-discovery/kubernetes/pull-secret-extractor/internal/secret_extraction/secret_extraction_test.go @@ -0,0 +1,174 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +package secret_extraction + +import ( + "context" + "encoding/base64" + "encoding/json" + "os" + "path/filepath" + "testing" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/fake" +) + +func TestCreateTemporarySecret(t *testing.T) { + scheme := runtime.NewScheme() + v1.AddToScheme(scheme) + + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod", + Namespace: "test-namespace", + UID: types.UID("test-uid-123"), + }, + } + + k8sClient := fake.NewClientBuilder(). + WithScheme(scheme). + WithObjects(pod). + Build() + + tempDir := t.TempDir() + configPath := filepath.Join(tempDir, dockerConfigFileName) + + config := DockerConfigJSON{ + Auths: map[string]AuthEntry{ + "example.com": { + Auth: base64.StdEncoding.EncodeToString([]byte("testuser:testpass")), + }, + }, + } + + configData, _ := json.Marshal(config) + os.WriteFile(configPath, configData, 0644) + + ctx := context.Background() + err := CreateTemporarySecret(ctx, k8sClient, "test-secret", "example.com", "test-namespace", "test-pod", "test-uid-123", tempDir) + + if err != nil { + t.Fatalf("Expected no error, got: %v", err) + } + + secret := &v1.Secret{} + err = k8sClient.Get(ctx, client.ObjectKey{Name: "test-secret", Namespace: "test-namespace"}, secret) + if err != nil { + t.Fatalf("Secret was not created: %v", err) + } + + expectedUsername := "testuser" + expectedPassword := "testpass" + + if secret.StringData["username"] != expectedUsername { + t.Errorf("Expected username %s, got %s", expectedUsername, string(secret.StringData["username"])) + } + + if secret.StringData["password"] != expectedPassword { + t.Errorf("Expected password %s, got %s", expectedPassword, string(secret.StringData["password"])) + } + + if len(secret.OwnerReferences) != 1 { + t.Fatalf("Expected 1 owner reference, got %d", len(secret.OwnerReferences)) + } + + ownerRef := secret.OwnerReferences[0] + if ownerRef.Name != "test-pod" || ownerRef.UID != "test-uid-123" { + t.Errorf("Owner reference not set correctly: %+v", ownerRef) + } +} + +func TestReadDockerConfigs(t *testing.T) { + tempDir := t.TempDir() + + configPath := filepath.Join(tempDir, dockerConfigFileName) + config := DockerConfigJSON{ + Auths: map[string]AuthEntry{ + "registry.example.com": { + Username: "testuser", + Password: "testpass", + }, + }, + } + + configData, _ := json.Marshal(config) + os.WriteFile(configPath, configData, 0644) + + configs, err := readDockerConfigs(tempDir) + if err != nil { + t.Fatalf("Expected no error, got: %v", err) + } + + if len(configs) != 1 { + t.Fatalf("Expected 1 config, got %d", len(configs)) + } + + auth, exists := configs[0].Auths["registry.example.com"] + if !exists { + t.Fatal("Expected auth entry for registry.example.com") + } + + if auth.Username != "testuser" || auth.Password != "testpass" { + t.Errorf("Expected testuser/testpass, got %s/%s", auth.Username, auth.Password) + } +} + +func TestExtractCredentials(t *testing.T) { + tests := []struct { + name string + auth *AuthEntry + expectCreds bool + expectError bool + }{ + { + name: "base64 auth field", + auth: &AuthEntry{ + Auth: base64.StdEncoding.EncodeToString([]byte("user:pass")), + }, + expectCreds: true, + }, + { + name: "separate username/password fields", + auth: &AuthEntry{ + Username: "user", + Password: "pass", + }, + expectCreds: true, + }, + { + name: "nil auth entry", + auth: nil, + expectError: true, + }, + { + name: "empty auth entry", + auth: &AuthEntry{}, + expectError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + creds, err := extractCredentials(tt.auth) + + if tt.expectError && err == nil { + t.Error("Expected error, got none") + } + + if !tt.expectError && err != nil { + t.Errorf("Expected no error, got: %v", err) + } + + if tt.expectCreds && creds == nil { + t.Error("Expected credentials, got nil") + } + }) + } +} diff --git a/auto-discovery/kubernetes/pull-secret-extractor/main.go b/auto-discovery/kubernetes/pull-secret-extractor/main.go new file mode 100644 index 0000000000..00524801a7 --- /dev/null +++ b/auto-discovery/kubernetes/pull-secret-extractor/main.go @@ -0,0 +1,74 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +package main + +import ( + "flag" + "fmt" + "log" + "os" + + "github.com/secureCodeBox/auto-discovery/kubernetes/pull-secret-extractor/internal/docker_image" + secret_extraction "github.com/secureCodeBox/auto-discovery/kubernetes/pull-secret-extractor/internal/secret_extraction" +) + +const AppName = "pull-secret-extractor" + +type Config struct { + ImageID string + TemporarySecretName string +} + +func parseFlags() (*Config, error) { + config := &Config{} + + flag.StringVar(&config.ImageID, "imageID", "", "Docker image ID to extract domain from (required)") + flag.StringVar(&config.TemporarySecretName, "secret", "", "Name for the temporary secret (required)") + + flag.Parse() + + if config.ImageID == "" { + return nil, fmt.Errorf("image ID is required (use -imageID flag or provide as first argument)") + } + + if config.TemporarySecretName == "" { + return nil, fmt.Errorf("temporary secret name is required (use -secret flag or provide as second argument)") + } + + return config, nil +} + +func run(config *Config) error { + domain := docker_image.GetDomainFromDockerImage(config.ImageID) + if domain == "" { + return fmt.Errorf("failed to extract domain from image ID: %s", config.ImageID) + } + + if err := secret_extraction.CreateTemporarySecretFromEnv(config.TemporarySecretName, domain); err != nil { + return fmt.Errorf("failed to create temporary secret: %w", err) + } + + log.Printf("Successfully created temporary secret '%s' for domain '%s'", + config.TemporarySecretName, domain) + + return nil +} + +func main() { + log.SetPrefix(fmt.Sprintf("[%s] ", AppName)) + log.SetFlags(log.LstdFlags | log.Lshortfile) + + config, err := parseFlags() + if err != nil { + fmt.Fprintf(os.Stderr, "Error: %v\n\n", err) + flag.Usage() + os.Exit(1) + } + + if err := run(config); err != nil { + log.Printf("Application failed: %v", err) + os.Exit(1) + } +} diff --git a/auto-discovery/kubernetes/pull-secret-extractor/requirements.txt b/auto-discovery/kubernetes/pull-secret-extractor/requirements.txt deleted file mode 100644 index da7662dad2..0000000000 --- a/auto-discovery/kubernetes/pull-secret-extractor/requirements.txt +++ /dev/null @@ -1,17 +0,0 @@ -cachetools==5.2.1 -certifi==2024.7.4 -charset-normalizer==3.0.1 -google-auth==2.16.0 -idna==3.7 -kubernetes==25.3.0 -oauthlib==3.2.2 -pyasn1==0.4.8 -pyasn1-modules==0.2.8 -python-dateutil==2.8.2 -PyYAML==6.0.1 -requests==2.32.4 -requests-oauthlib==1.3.1 -rsa==4.9 -six==1.16.0 -urllib3==2.5.0 -websocket-client==1.4.2 diff --git a/auto-discovery/kubernetes/pull-secret-extractor/secret_extraction.py b/auto-discovery/kubernetes/pull-secret-extractor/secret_extraction.py deleted file mode 100644 index 1730a7dce5..0000000000 --- a/auto-discovery/kubernetes/pull-secret-extractor/secret_extraction.py +++ /dev/null @@ -1,128 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -import glob -import json -import sys -import base64 -import os - -from kubernetes import client, config - -from docker_image import get_domain_from_docker_image - - -def main(): - image_id = sys.argv[1] - temporary_secret_name = sys.argv[2] - - domain = get_domain_from_docker_image(image_id) - - raw_secrets = get_raw_secrets('/secrets') - correct_secret = get_correct_secret(domain, raw_secrets) - - if correct_secret: - username, password = get_user_and_password(correct_secret) - create_temporary_secret(username, password, temporary_secret_name) - print(f"Created temporary pull secret for domain: '{domain}'") - else: - print(f"No secrets found for domain: '{domain}'") - - -def get_raw_secrets(base_path: str): - """Reads in files called '.dockerconfigjson' in the path given and return the content of all files called so - :param base_path: Directory to search for dockerconfigjson files - :returns: List of secrets found in base_path - """ - raw_secrets = [] - for file_name in glob.glob(f'{base_path}/**/.dockerconfigjson', recursive=True): - with open(file_name) as file: - raw_secret = json.load(file) - raw_secrets.append(raw_secret) - return raw_secrets - - -def get_correct_secret(domain: str, secrets) -> dict[str, str]: - """Iterates over given list of secrets to find the secret that matches the URL in the given imageID - :param domain: The domain of the imageID of which the correct secret needs to be identified - :param secrets: List of secrets - :returns: Dict containing the secret matching the given imageID - """ - for secret in secrets: - for url, data in secret['auths'].items(): - if url == domain: - return data - - -def get_user_and_password(raw_secret: dict[str, str]) -> tuple[str, str]: - """Extracts username and password from a given secret - :param raw_secret: Dict containing the secret. Should contain key 'auth' (where username and password are - base64 encoded in a single line like: username:password), or 'username' and 'password' as a separate key - (also base64) - :returns: tuple containing username and password both base64 encoded - :raises KeyError: Structure of given secret does not contain expected structure. - """ - if 'auth' in raw_secret: - # secret is in form "username:password" (base64 encoded) - username_password_combo = decode_base64(raw_secret['auth']) - tmp_list = username_password_combo.split(":") - - # k8s wants the secrets as base64, so the individual values are converted back to base64 - username = encode_base64(tmp_list[0]) - password = encode_base64(tmp_list[1]) - return username, password - - elif 'username' in raw_secret and 'password' in raw_secret: - # username and password are already separated and base64 encoded, no need to do more - username = raw_secret['username'] - password = raw_secret['password'] - return username, password - - else: - raise KeyError('dockerconfigjson secret does not contain expected structure!') - - -def decode_base64(raw_string: str) -> str: - return base64.b64decode(raw_string).decode('utf-8') - - -def encode_base64(string: str) -> str: - return base64.b64encode(string.encode('utf-8')).decode('utf-8') - - -def create_temporary_secret(username: str, password: str, secret_name: str): - """Creates a secret with name 'secret_name' with 'username' and 'password' as data in given namespace. The secret has an ownerReference to the pod this container is running in. - :param username: base64 encoded string representing the desired value of the 'username' field in the secret - :param password: base64 encoded string representing the desired value of the 'password' field in the secret - :param secret_name: Name of the newly created secret - """ - config.load_incluster_config() - v1 = client.CoreV1Api() - - namespace = get_namespace() - - pod_name = get_pod_name() - pod = v1.read_namespaced_pod(name=pod_name, namespace=namespace) - - secret_data = {'username': username, 'password': password} - owner_references = client.V1OwnerReference(api_version='v1', name=pod_name, uid=pod.metadata.uid, kind='Pod') - metadata = client.V1ObjectMeta(name=secret_name, namespace=namespace, owner_references=[owner_references]) - secret_body = client.V1Secret(api_version='v1', kind='Secret', metadata=metadata, data=secret_data, type='Opaque') - v1.create_namespaced_secret(namespace=namespace, body=secret_body) - - -def get_pod_name() -> str: - """Read pod name from environment variable called 'POD_NAME'. - Should be set like this: https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/""" - return os.environ['POD_NAME'] - - -def get_namespace() -> str: - """Read pod name from environment variable called 'NAMESPACE'. - Should be set like this: https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/""" - return os.environ['NAMESPACE'] - - -if __name__ == '__main__': - main() diff --git a/auto-discovery/kubernetes/pull-secret-extractor/integration-test/test-pod.sh b/auto-discovery/kubernetes/pull-secret-extractor/test/integration/test-pod.sh similarity index 89% rename from auto-discovery/kubernetes/pull-secret-extractor/integration-test/test-pod.sh rename to auto-discovery/kubernetes/pull-secret-extractor/test/integration/test-pod.sh index f72670cbb4..e118627ec9 100755 --- a/auto-discovery/kubernetes/pull-secret-extractor/integration-test/test-pod.sh +++ b/auto-discovery/kubernetes/pull-secret-extractor/test/integration/test-pod.sh @@ -22,7 +22,7 @@ metadata: namespace: integration-test --- apiVersion: v1 -kind: Pod +kind: Pod metadata: name: init-container-test namespace: integration-test @@ -35,12 +35,15 @@ spec: initContainers: - name: init-container-test-container image: $1 - command: ["python"] - args: ["secret_extraction.py", "fake-registry.xyz/ubuntu:32131", "test-secret", "default"] + args: ["-imageID", "fake-registry.xyz/ubuntu:32131", "-secret", "test-secret", "default"] volumeMounts: - name: regcred-volume mountPath: "/secrets/regcred" env: + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid - name: POD_NAME valueFrom: fieldRef: diff --git a/auto-discovery/kubernetes/pull-secret-extractor/test_secrets/secret_1/.dockerconfigjson b/auto-discovery/kubernetes/pull-secret-extractor/test/testdata/secrets/secret_1/.dockerconfigjson similarity index 100% rename from auto-discovery/kubernetes/pull-secret-extractor/test_secrets/secret_1/.dockerconfigjson rename to auto-discovery/kubernetes/pull-secret-extractor/test/testdata/secrets/secret_1/.dockerconfigjson diff --git a/auto-discovery/kubernetes/pull-secret-extractor/test_secrets/secret_1/.dockerconfigjson.license b/auto-discovery/kubernetes/pull-secret-extractor/test/testdata/secrets/secret_1/.dockerconfigjson.license similarity index 100% rename from auto-discovery/kubernetes/pull-secret-extractor/test_secrets/secret_1/.dockerconfigjson.license rename to auto-discovery/kubernetes/pull-secret-extractor/test/testdata/secrets/secret_1/.dockerconfigjson.license diff --git a/auto-discovery/kubernetes/pull-secret-extractor/test_secrets/secret_1/not_a_docker_config_json b/auto-discovery/kubernetes/pull-secret-extractor/test/testdata/secrets/secret_1/not_a_docker_config_json similarity index 100% rename from auto-discovery/kubernetes/pull-secret-extractor/test_secrets/secret_1/not_a_docker_config_json rename to auto-discovery/kubernetes/pull-secret-extractor/test/testdata/secrets/secret_1/not_a_docker_config_json diff --git a/auto-discovery/kubernetes/pull-secret-extractor/test_secrets/secret_1/not_a_docker_config_json.license b/auto-discovery/kubernetes/pull-secret-extractor/test/testdata/secrets/secret_1/not_a_docker_config_json.license similarity index 100% rename from auto-discovery/kubernetes/pull-secret-extractor/test_secrets/secret_1/not_a_docker_config_json.license rename to auto-discovery/kubernetes/pull-secret-extractor/test/testdata/secrets/secret_1/not_a_docker_config_json.license diff --git a/auto-discovery/kubernetes/pull-secret-extractor/test_secrets/secret_2/.dockerconfigjson b/auto-discovery/kubernetes/pull-secret-extractor/test/testdata/secrets/secret_2/.dockerconfigjson similarity index 100% rename from auto-discovery/kubernetes/pull-secret-extractor/test_secrets/secret_2/.dockerconfigjson rename to auto-discovery/kubernetes/pull-secret-extractor/test/testdata/secrets/secret_2/.dockerconfigjson diff --git a/auto-discovery/kubernetes/pull-secret-extractor/test_secrets/secret_2/.dockerconfigjson.license b/auto-discovery/kubernetes/pull-secret-extractor/test/testdata/secrets/secret_2/.dockerconfigjson.license similarity index 100% rename from auto-discovery/kubernetes/pull-secret-extractor/test_secrets/secret_2/.dockerconfigjson.license rename to auto-discovery/kubernetes/pull-secret-extractor/test/testdata/secrets/secret_2/.dockerconfigjson.license diff --git a/auto-discovery/kubernetes/pull-secret-extractor/test_docker_image.py b/auto-discovery/kubernetes/pull-secret-extractor/test_docker_image.py deleted file mode 100644 index 945c84dd96..0000000000 --- a/auto-discovery/kubernetes/pull-secret-extractor/test_docker_image.py +++ /dev/null @@ -1,29 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -from unittest import TestCase - -from docker_image import get_domain_from_docker_image - - -class Test(TestCase): - def test_get_domain_from_docker_image_with_no_domain(self): - test_image = "foo/bar" - domain = get_domain_from_docker_image(test_image) - self.assertEqual("docker.io", domain) - - def test_get_domain_from_docker_image_with_dockerio_domain(self): - test_image = "docker.io/foo/bar" - domain = get_domain_from_docker_image(test_image) - self.assertEqual("docker.io", domain) - - def test_get_domain_from_docker_image_with_non_dockerio_domain(self): - test_image = "test.xyz/foo/bar" - domain = get_domain_from_docker_image(test_image) - self.assertEqual("test.xyz", domain) - - def test_get_domain_from_docker_image_with_single_world_image(self): - test_image = "ubuntu" - domain = get_domain_from_docker_image(test_image) - self.assertEqual("docker.io", domain) diff --git a/auto-discovery/kubernetes/pull-secret-extractor/test_secret_extraction.py b/auto-discovery/kubernetes/pull-secret-extractor/test_secret_extraction.py deleted file mode 100644 index a0a6191eb9..0000000000 --- a/auto-discovery/kubernetes/pull-secret-extractor/test_secret_extraction.py +++ /dev/null @@ -1,65 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -import sys -import unittest - -from unittest.mock import MagicMock - -# mock kubernetes import so it doesnt need to be installed to run these tests -sys.modules['kubernetes'] = MagicMock() -from secret_extraction import * - - -class MyTestCase(unittest.TestCase): - - def test_get_raw_secrets(self): - actual = get_raw_secrets('test_secrets') - - with open('test_secrets/secret_1/.dockerconfigjson') as file: - expected_secret_1 = json.load(file) - - with open('test_secrets/secret_2/.dockerconfigjson') as file: - expected_secret_2 = json.load(file) - - # for some reason assertCountEqual doesnt work here - self.assertIn(expected_secret_1, actual) - self.assertIn(expected_secret_2, actual) - - def test_get_correct_secret(self): - with open('test_secrets/secret_1/.dockerconfigjson') as file: - secret_list = [json.load(file)] - - with open('test_secrets/secret_2/.dockerconfigjson') as file: - secret_list.append(json.load(file)) - - actual = get_correct_secret('localhost:5000', secret_list) - - # testuser:testpassword base64 encoded - expected = {'auth': 'dGVzdHVzZXI6dGVzdHBhc3N3b3Jk'} - - self.assertCountEqual(expected, actual) - - def test_get_user_and_password_given_auth_string(self): - secret = {'auth': 'dGVzdHVzZXI6dGVzdHBhc3N3b3Jk'} - actual = get_user_and_password(secret) - - # testuser, testpassword base64 encoded - expected = ('dGVzdHVzZXI=', 'dGVzdHBhc3N3b3Jk') - - self.assertEqual(expected, actual) - - def test_get_and_password_given_username_and_password_as_separate_string(self): - secret = { - 'username': 'dGVzdHVzZXI=', - 'password': 'dGVzdHBhc3N3b3Jk' - } - actual = get_user_and_password(secret) - - expected = (secret['username'], secret['password']) - self.assertEqual(expected, actual) - - -if __name__ == '__main__': - unittest.main() diff --git a/bin/add-license-header.sh b/bin/add-license-header.sh index 98c66f3e59..2d2833c65f 100755 --- a/bin/add-license-header.sh +++ b/bin/add-license-header.sh @@ -17,7 +17,7 @@ # cat spdx-report.md | ./add-license-header.sh # # To generate the file list use `reuse lint`. This produces a Markdown report: -# docker run --rm --volume $(pwd):/data fsfe/reuse lint > spdx-report.md +# docker run --rm --volume $(pwd):/data fsfe/reuse --include-submodules lint > spdx-report.md # # See also: # - https://spdx.org diff --git a/bin/create-blog-post.sh b/bin/create-blog-post.sh deleted file mode 100755 index ef23022fef..0000000000 --- a/bin/create-blog-post.sh +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env bash - -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# -# Helper script to create new blog posts -# -# What does this script for you? -# 1. It creates the proper filename (eg. blog/2020-10-01-this-is-a-title.md). -# - current date -# - lower case -# - spaces replaced by dashes -# 2. Adds basic frontmatter into it. -# -# You may place a file .author_meta into the root of the repo to define some variables -# for the frontmatter. The script will tell you if no meta file was found. -# - -set -ue - -# @see: http://wiki.bash-hackers.org/syntax/shellvars -[ -z "${SCRIPT_DIRECTORY:-}" ] \ - && SCRIPT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" \ - && export SCRIPT_DIRECTORY - -BASE_DIR=$(dirname "${SCRIPT_DIRECTORY}")/documentation -BLOG_DIR="${BASE_DIR}/blog" -USAGE="Usage: $(basename "$0") 'The title of Your Post'" - -if (( $# != 1 )); then - echo "Error: The title is missing!" - echo "${USAGE}" - exit 1 -fi - -if [ '-h' = "${1}" ]; then - echo "${USAGE}" - exit 0 -fi - -AUTHOR_META_FILE="${BASE_DIR}/.author_meta" -if [ -f "${AUTHOR_META_FILE}" ]; then - echo "Using author meta file ${AUTHOR_META_FILE}." - # shellcheck disable=SC1090 - source "${AUTHOR_META_FILE}" -else - echo "No author meta file found at ${AUTHOR_META_FILE}!" - echo - echo "You could use one to predefine some variables. Just put this:" - echo - echo "AUTHOR='Gordon Shumway'" - echo "AUTHOR_TITLE='Core Developer'" - echo "AUTHOR_URL='https://...'" - echo "AUTHOR_IMAGE_URL='https://...'" - echo - echo "Into the file ${AUTHOR_META_FILE}." -fi - -TITLE="${1}" -TITLE_CLEANSED=$(echo "${TITLE}" | tr '[:upper:]' '[:lower:]' | tr ' ' '-') -DATE=$(date +'%Y-%m-%d') -BLOG_POST_FILE="${BLOG_DIR}/${DATE}-${TITLE_CLEANSED}.md" -cat << EOF > "${BLOG_POST_FILE}" ---- -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -title: ${TITLE} -author: ${AUTHOR:-} -author_title: ${AUTHOR_TITLE:-} -author_url: ${AUTHOR_URL:-} -author_image_url: ${AUTHOR_IMAGE_URL:-} -tags: -description: -image: -draft: true ---- -EOF diff --git a/bin/package-lock.json b/bin/package-lock.json index 1081a28d19..9447d2be42 100644 --- a/bin/package-lock.json +++ b/bin/package-lock.json @@ -5,14 +5,13 @@ "packages": { "": { "dependencies": { - "semver": "^7.6.3" + "semver": "^7.7.3" } }, "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "license": "ISC", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "bin": { "semver": "bin/semver.js" }, diff --git a/bin/package.json b/bin/package.json index 372e349e8b..ef45ab4247 100644 --- a/bin/package.json +++ b/bin/package.json @@ -1,5 +1,5 @@ { "dependencies": { - "semver": "^7.6.3" + "semver": "^7.7.3" } } diff --git a/demo-targets/bodgeit/container/docker-compose.yml b/demo-targets/bodgeit/container/docker-compose.yml deleted file mode 100644 index 18847da8db..0000000000 --- a/demo-targets/bodgeit/container/docker-compose.yml +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -version: "3.8" -services: - bodgeit: - image: psiinon/bodgeit:latest - ports: - - 8080:8080 -# Website will be available under http://localhost:8080/bodgeit diff --git a/demo-targets/bodgeit/questions.yml b/demo-targets/bodgeit/questions.yml deleted file mode 100644 index 8490f13fee..0000000000 --- a/demo-targets/bodgeit/questions.yml +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -categories: - - "Vulnerable App" - - "Demo Scan Target" -questions: [] diff --git a/demo-targets/bodgeit/tests/__snapshot__/bodgeit_test.yaml.snap b/demo-targets/bodgeit/tests/__snapshot__/bodgeit_test.yaml.snap index 3835ba9ab9..3a10cf6f3b 100644 --- a/demo-targets/bodgeit/tests/__snapshot__/bodgeit_test.yaml.snap +++ b/demo-targets/bodgeit/tests/__snapshot__/bodgeit_test.yaml.snap @@ -1,6 +1,6 @@ matches the snapshot: 1: | - raw: |2 + raw: | 1. Get the application URL by running these commands: 2: | apiVersion: apps/v1 diff --git a/demo-targets/dummy-ssh/Chart.yaml b/demo-targets/dummy-ssh/Chart.yaml index 8f1384f86d..09363fc74a 100644 --- a/demo-targets/dummy-ssh/Chart.yaml +++ b/demo-targets/dummy-ssh/Chart.yaml @@ -5,7 +5,8 @@ apiVersion: v2 version: v3.1.0-alpha1 type: application -appVersion: "v1.0.0" +# renovate: docker.io/securecodebox/dummy-ssh +appVersion: v1.0.0 name: dummy-ssh description: "SSH Server for scan testing." home: https://www.securecodebox.io diff --git a/demo-targets/dummy-ssh/container/Dockerfile b/demo-targets/dummy-ssh/container/Dockerfile index d48d82562e..08461af1c6 100644 --- a/demo-targets/dummy-ssh/container/Dockerfile +++ b/demo-targets/dummy-ssh/container/Dockerfile @@ -4,7 +4,7 @@ # From https://gdevillele.github.io/engine/examples/running_ssh_service/ # This file is authored by Docker Inc. and is not covered by the Apache2 Licence by the secureCodeBox project. -FROM ubuntu:16.04 +FROM ubuntu:24.04 RUN apt-get update && apt-get install -y openssh-server RUN mkdir /var/run/sshd diff --git a/demo-targets/dummy-ssh/container/docker-compose.yml b/demo-targets/dummy-ssh/container/docker-compose.yml deleted file mode 100644 index 06b9361792..0000000000 --- a/demo-targets/dummy-ssh/container/docker-compose.yml +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -version: "3.8" -services: - dummy_ssh: - build: - context: . - dockerfile: Dockerfile diff --git a/demo-targets/dummy-ssh/questions.yml b/demo-targets/dummy-ssh/questions.yml deleted file mode 100644 index 8490f13fee..0000000000 --- a/demo-targets/dummy-ssh/questions.yml +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -categories: - - "Vulnerable App" - - "Demo Scan Target" -questions: [] diff --git a/demo-targets/dummy-ssh/tests/__snapshot__/dummy-ssh_test.yaml.snap b/demo-targets/dummy-ssh/tests/__snapshot__/dummy-ssh_test.yaml.snap index 8de190c814..c0756779de 100644 --- a/demo-targets/dummy-ssh/tests/__snapshot__/dummy-ssh_test.yaml.snap +++ b/demo-targets/dummy-ssh/tests/__snapshot__/dummy-ssh_test.yaml.snap @@ -1,6 +1,6 @@ matches the snapshot: 1: | - raw: |2 + raw: | Demo SSH Server deployed. Note this should used for demo and test purposes. diff --git a/demo-targets/http-webhook/container/docker-compose.yml b/demo-targets/http-webhook/container/docker-compose.yml deleted file mode 100644 index 7ba5b45e2f..0000000000 --- a/demo-targets/http-webhook/container/docker-compose.yml +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -version: "3.8" -services: - my-http-listener: - image: mendhak/http-https-echo:18 - environment: - - HTTP_PORT=8888 - - HTTPS_PORT=9999 - ports: - - "8080:8888" - - "8443:9999" diff --git a/demo-targets/http-webhook/tests/__snapshot__/http-webhook_test.yaml.snap b/demo-targets/http-webhook/tests/__snapshot__/http-webhook_test.yaml.snap index 024edcd3d0..94194b0c4b 100644 --- a/demo-targets/http-webhook/tests/__snapshot__/http-webhook_test.yaml.snap +++ b/demo-targets/http-webhook/tests/__snapshot__/http-webhook_test.yaml.snap @@ -1,6 +1,6 @@ matches the snapshot: 1: | - raw: |2 + raw: | 1. Get the application URL by running these commands: 2: | apiVersion: apps/v1 diff --git a/demo-targets/juice-shop/Chart.yaml b/demo-targets/juice-shop/Chart.yaml index 37d0753231..f04442844b 100644 --- a/demo-targets/juice-shop/Chart.yaml +++ b/demo-targets/juice-shop/Chart.yaml @@ -4,7 +4,8 @@ apiVersion: v2 version: v3.1.0-alpha3 -appVersion: "v13.0.3" +# renovate: image=docker.io/bkimminich/juice-shop +appVersion: v19.1.1 name: juice-shop description: "OWASP Juice Shop: Probably the most modern and sophisticated insecure web application" type: application diff --git a/demo-targets/juice-shop/README.md b/demo-targets/juice-shop/README.md index 9ae7adcbd4..d1aaf9639b 100644 --- a/demo-targets/juice-shop/README.md +++ b/demo-targets/juice-shop/README.md @@ -3,7 +3,7 @@ title: "OWASP JuiceShop" category: "target" type: "Website" state: "released" -appVersion: "v13.0.3" +appVersion: "v19.1.1" usecase: "Modern insecure web application" --- diff --git a/demo-targets/juice-shop/container/docker-compose.yml b/demo-targets/juice-shop/container/docker-compose.yml deleted file mode 100644 index 7ffd2a7aac..0000000000 --- a/demo-targets/juice-shop/container/docker-compose.yml +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -version: "3.8" -services: - juice_shop: - image: bkimminich/juice-shop:v12.8.1 - ports: - - 3000:3000 -# Website will be available under http://localhost:3000/ diff --git a/demo-targets/juice-shop/questions.yml b/demo-targets/juice-shop/questions.yml deleted file mode 100644 index 8490f13fee..0000000000 --- a/demo-targets/juice-shop/questions.yml +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -categories: - - "Vulnerable App" - - "Demo Scan Target" -questions: [] diff --git a/demo-targets/juice-shop/tests/__snapshot__/juice-shop_test.yaml.snap b/demo-targets/juice-shop/tests/__snapshot__/juice-shop_test.yaml.snap index fd100f1438..735e87c3f8 100644 --- a/demo-targets/juice-shop/tests/__snapshot__/juice-shop_test.yaml.snap +++ b/demo-targets/juice-shop/tests/__snapshot__/juice-shop_test.yaml.snap @@ -1,12 +1,12 @@ matches the snapshot: 1: | - raw: |2 + raw: | 1. Get the application URL by running these commands: https://chart-example.localmap[path:/] 2: | apiVersion: v1 data: - customConfig.yml: |2 + customConfig.yml: | application: domain: juice-sh.op name: OWASP Juice Shop diff --git a/demo-targets/old-joomla/container/Dockerfile b/demo-targets/old-joomla/container/Dockerfile index ea279e86b1..ece74d23c4 100644 --- a/demo-targets/old-joomla/container/Dockerfile +++ b/demo-targets/old-joomla/container/Dockerfile @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 -FROM alpine:3.13 AS base +FROM alpine:3.22 AS base WORKDIR /html RUN apk add wget unzip \ diff --git a/demo-targets/old-joomla/questions.yml b/demo-targets/old-joomla/questions.yml deleted file mode 100644 index 8490f13fee..0000000000 --- a/demo-targets/old-joomla/questions.yml +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -categories: - - "Vulnerable App" - - "Demo Scan Target" -questions: [] diff --git a/demo-targets/old-joomla/tests/__snapshot__/old-joomla_test.yaml.snap b/demo-targets/old-joomla/tests/__snapshot__/old-joomla_test.yaml.snap index a683a28857..5a8d342b20 100644 --- a/demo-targets/old-joomla/tests/__snapshot__/old-joomla_test.yaml.snap +++ b/demo-targets/old-joomla/tests/__snapshot__/old-joomla_test.yaml.snap @@ -1,6 +1,6 @@ matches the snapshot: 1: | - raw: |2 + raw: | 1. Get the application URL by running these commands: 2: | apiVersion: apps/v1 diff --git a/demo-targets/old-typo3/container/Dockerfile b/demo-targets/old-typo3/container/Dockerfile index 9b4c8b0a42..bf50c3b7f2 100644 --- a/demo-targets/old-typo3/container/Dockerfile +++ b/demo-targets/old-typo3/container/Dockerfile @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 -FROM martinhelmich/typo3:9.4 +FROM martinhelmich/typo3:9.5 RUN rm /var/www/html/FIRST_INSTALL \ && rm -r /var/www/html/typo3conf diff --git a/demo-targets/old-typo3/questions.yml b/demo-targets/old-typo3/questions.yml deleted file mode 100644 index 8490f13fee..0000000000 --- a/demo-targets/old-typo3/questions.yml +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -categories: - - "Vulnerable App" - - "Demo Scan Target" -questions: [] diff --git a/demo-targets/old-typo3/tests/__snapshot__/old-typo3_test.yaml.snap b/demo-targets/old-typo3/tests/__snapshot__/old-typo3_test.yaml.snap index 1afbb74652..2e066d0952 100644 --- a/demo-targets/old-typo3/tests/__snapshot__/old-typo3_test.yaml.snap +++ b/demo-targets/old-typo3/tests/__snapshot__/old-typo3_test.yaml.snap @@ -1,6 +1,6 @@ matches the snapshot: 1: | - raw: |2 + raw: | 1. Get the application URL by running these commands: 2: | apiVersion: apps/v1 diff --git a/demo-targets/old-wordpress/container/Dockerfile b/demo-targets/old-wordpress/container/Dockerfile index 14fb0399db..a606fbaa2a 100644 --- a/demo-targets/old-wordpress/container/Dockerfile +++ b/demo-targets/old-wordpress/container/Dockerfile @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 -FROM alpine:3.13 AS base +FROM alpine:3.22 AS base RUN apk add wget unzip \ && wget https://downloads.wordpress.org/plugin/sqlite-integration.1.8.1.zip \ && unzip sqlite-integration.1.8.1.zip \ diff --git a/demo-targets/old-wordpress/questions.yml b/demo-targets/old-wordpress/questions.yml deleted file mode 100644 index 8490f13fee..0000000000 --- a/demo-targets/old-wordpress/questions.yml +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -categories: - - "Vulnerable App" - - "Demo Scan Target" -questions: [] diff --git a/demo-targets/old-wordpress/tests/__snapshot__/old-wordpress_test.yaml.snap b/demo-targets/old-wordpress/tests/__snapshot__/old-wordpress_test.yaml.snap index 40ce2b37bd..b7cc885edd 100644 --- a/demo-targets/old-wordpress/tests/__snapshot__/old-wordpress_test.yaml.snap +++ b/demo-targets/old-wordpress/tests/__snapshot__/old-wordpress_test.yaml.snap @@ -1,6 +1,6 @@ matches the snapshot: 1: | - raw: |2 + raw: | Old Wordpress Instance deployed. Note this should used for demo and test purposes. diff --git a/demo-targets/swagger-petstore/Chart.yaml b/demo-targets/swagger-petstore/Chart.yaml index ef1b87bcb2..6eb6147e08 100644 --- a/demo-targets/swagger-petstore/Chart.yaml +++ b/demo-targets/swagger-petstore/Chart.yaml @@ -4,7 +4,8 @@ apiVersion: v2 version: v3.1.0-alpha1 -appVersion: "1.0.3" +# renovate: image=docker.io/swaggerapi/petstore3 +appVersion: 1.0.27 name: swagger-petstore description: "This is the sample petstore application" type: application diff --git a/demo-targets/swagger-petstore/README.md b/demo-targets/swagger-petstore/README.md index 1174ee3c3e..fcf7600c1c 100644 --- a/demo-targets/swagger-petstore/README.md +++ b/demo-targets/swagger-petstore/README.md @@ -3,7 +3,7 @@ title: "Swagger Petstore API" category: "target" type: "Website" state: "released" -appVersion: "1.0.3" +appVersion: "1.0.27" usecase: "Modern insecure web application" --- @@ -58,7 +58,7 @@ helm upgrade --install swagger-petstore oci://ghcr.io/securecodebox/helm/swagger | annotations | object | `{}` | add annotations to the deployment, service and pods | | fullnameOverride | string | `""` | | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images | -| image.repository | string | `"docker.io/swaggerapi/petstore"` | Container Image | +| image.repository | string | `"docker.io/swaggerapi/petstore3"` | Container Image | | image.tag | string | defaults to the appVersion | The image tag | | imagePullSecrets | list | `[]` | Define imagePullSecrets when a private registry is used (see: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) | | ingress.annotations | object | `{}` | | diff --git a/demo-targets/swagger-petstore/container/docker-compose.yml b/demo-targets/swagger-petstore/container/docker-compose.yml deleted file mode 100644 index e32fe55143..0000000000 --- a/demo-targets/swagger-petstore/container/docker-compose.yml +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -version: "3.8" -services: - swagger_petstore: - image: swaggerapi/petstore3:unstable - ports: - - 8080:8080 -# Website will be available under http://localhost:8080/ diff --git a/demo-targets/swagger-petstore/docs/README.ArtifactHub.md b/demo-targets/swagger-petstore/docs/README.ArtifactHub.md index a231aa5bb6..a182797210 100644 --- a/demo-targets/swagger-petstore/docs/README.ArtifactHub.md +++ b/demo-targets/swagger-petstore/docs/README.ArtifactHub.md @@ -65,7 +65,7 @@ helm upgrade --install swagger-petstore oci://ghcr.io/securecodebox/helm/swagger | annotations | object | `{}` | add annotations to the deployment, service and pods | | fullnameOverride | string | `""` | | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images | -| image.repository | string | `"docker.io/swaggerapi/petstore"` | Container Image | +| image.repository | string | `"docker.io/swaggerapi/petstore3"` | Container Image | | image.tag | string | defaults to the appVersion | The image tag | | imagePullSecrets | list | `[]` | Define imagePullSecrets when a private registry is used (see: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) | | ingress.annotations | object | `{}` | | diff --git a/demo-targets/swagger-petstore/tests/__snapshot__/swagger-petstore_test.yaml.snap b/demo-targets/swagger-petstore/tests/__snapshot__/swagger-petstore_test.yaml.snap index 2208317b3e..d9eda818f4 100644 --- a/demo-targets/swagger-petstore/tests/__snapshot__/swagger-petstore_test.yaml.snap +++ b/demo-targets/swagger-petstore/tests/__snapshot__/swagger-petstore_test.yaml.snap @@ -1,6 +1,6 @@ matches the snapshot: 1: | - raw: |2 + raw: | 1. Get the application URL by running these commands: 2: | apiVersion: apps/v1 @@ -48,7 +48,7 @@ matches the snapshot: value: http://swagger-petstore.demo-targets.svc - name: SWAGGER_URL value: http://swagger-petstore.demo-targets.svc - image: docker.io/swaggerapi/petstore:0.0.0 + image: docker.io/swaggerapi/petstore3:0.0.0 imagePullPolicy: IfNotPresent livenessProbe: httpGet: diff --git a/demo-targets/swagger-petstore/values.yaml b/demo-targets/swagger-petstore/values.yaml index a82df8e3c6..9394fff041 100644 --- a/demo-targets/swagger-petstore/values.yaml +++ b/demo-targets/swagger-petstore/values.yaml @@ -10,7 +10,7 @@ replicaCount: 1 image: # image.repository -- Container Image - repository: docker.io/swaggerapi/petstore + repository: docker.io/swaggerapi/petstore3 # image.tag -- The image tag # @default -- defaults to the appVersion tag: null diff --git a/demo-targets/unsafe-https/Chart.yaml b/demo-targets/unsafe-https/Chart.yaml index a5b935dd6f..52372843a8 100644 --- a/demo-targets/unsafe-https/Chart.yaml +++ b/demo-targets/unsafe-https/Chart.yaml @@ -5,7 +5,8 @@ apiVersion: v2 version: v3.1.0-alpha1 type: application -appVersion: "v1.0.0" +# renovate: image=docker.io/securecodebox/unsafe-https +appVersion: v1.0.0 name: unsafe-https description: "Self-signed https Server for scan testing." home: https://www.securecodebox.io diff --git a/demo-targets/unsafe-https/container/Dockerfile b/demo-targets/unsafe-https/container/Dockerfile index 5920ae7f34..82760b1bf9 100644 --- a/demo-targets/unsafe-https/container/Dockerfile +++ b/demo-targets/unsafe-https/container/Dockerfile @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 -FROM nginx:1.17-alpine +FROM nginx:1.29-alpine COPY index.html /usr/share/nginx/html/index.html COPY nginx.conf /etc/nginx/nginx.conf COPY site.crt /etc/nginx/my-site.com.crt diff --git a/demo-targets/unsafe-https/container/docker-compose.yml b/demo-targets/unsafe-https/container/docker-compose.yml deleted file mode 100644 index fe73e2a474..0000000000 --- a/demo-targets/unsafe-https/container/docker-compose.yml +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -version: "3.8" -services: - unsafe_https: - build: - context: . - dockerfile: Dockerfile diff --git a/demo-targets/unsafe-https/questions.yml b/demo-targets/unsafe-https/questions.yml deleted file mode 100644 index 8490f13fee..0000000000 --- a/demo-targets/unsafe-https/questions.yml +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -categories: - - "Vulnerable App" - - "Demo Scan Target" -questions: [] diff --git a/demo-targets/unsafe-https/tests/__snapshot__/unsafe-https_test.yaml.snap b/demo-targets/unsafe-https/tests/__snapshot__/unsafe-https_test.yaml.snap index 979ea466bd..175e11372a 100644 --- a/demo-targets/unsafe-https/tests/__snapshot__/unsafe-https_test.yaml.snap +++ b/demo-targets/unsafe-https/tests/__snapshot__/unsafe-https_test.yaml.snap @@ -1,6 +1,6 @@ matches the snapshot: 1: | - raw: |2 + raw: | Demo Unsafe Https Server deployed. Note this should only be used for demo and test purposes. diff --git a/demo-targets/vulnerable-log4j/questions.yml b/demo-targets/vulnerable-log4j/questions.yml deleted file mode 100644 index 8490f13fee..0000000000 --- a/demo-targets/vulnerable-log4j/questions.yml +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -categories: - - "Vulnerable App" - - "Demo Scan Target" -questions: [] diff --git a/demo-targets/vulnerable-log4j/tests/__snapshot__/vulnerable-log4j_test.yaml.snap b/demo-targets/vulnerable-log4j/tests/__snapshot__/vulnerable-log4j_test.yaml.snap index 754289a782..9b15039fcf 100644 --- a/demo-targets/vulnerable-log4j/tests/__snapshot__/vulnerable-log4j_test.yaml.snap +++ b/demo-targets/vulnerable-log4j/tests/__snapshot__/vulnerable-log4j_test.yaml.snap @@ -1,6 +1,6 @@ matches the snapshot: 1: | - raw: |2 + raw: | Vulnerable log4j Instance deployed. Note this should used for demo and test purposes. diff --git a/documentation/README.md b/documentation/README.md index 415f12c2dd..33129489f6 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -106,7 +106,7 @@ Recommended websites for free icons or images: ## Documentation Guide -Since we work with various different tools, it is even more important to keep a clean and well structured Documentation. Our website's purpose is to provide a comfortable navigation and clear overview. But since no one is going to update the documentation if it's untraceable, it is also very important to keep the documentation's location clear and as less spread as possible throughout our project. So no single-page documentation hidden in the deep structure of a remote repository! In general we keep specific documentation in the respective directory (e.g. the Amass documentation is a README.md in the Amass directory). Documentation can also be housed in this repository, if it is not specifically categorized to something, but follows the guidelines of the documentation build scripts. One key feature our documentations share in order to be put on the website is a frontmatter in each documentation. It is mandatory since at least a title (and for integrations also a description) are required. But it also can provide helpful other information very easily, for a documentation see [frontmatter]. Don't be afraid to use it for including important information, which you can't get/provide otherwise very well, but don't overuse it! For more detailed examples see the following sections. +Since we work with various different tools, it is even more important to keep a clean and well structured Documentation. Our website's purpose is to provide a comfortable navigation and clear overview. But since no one is going to update the documentation if it's untraceable, it is also very important to keep the documentation's location clear and as less spread as possible throughout our project. So no single-page documentation hidden in the deep structure of a remote repository! In general we keep specific documentation in the respective directory (e.g. the nmap documentation is a README.md in the nmap directory). Documentation can also be housed in this repository, if it is not specifically categorized to something, but follows the guidelines of the documentation build scripts. One key feature our documentations share in order to be put on the website is a frontmatter in each documentation. It is mandatory since at least a title (and for integrations also a description) are required. But it also can provide helpful other information very easily, for a documentation see [frontmatter]. Don't be afraid to use it for including important information, which you can't get/provide otherwise very well, but don't overuse it! For more detailed examples see the following sections. ### Adding a Scanner or Hook diff --git a/documentation/blog/2020-09-08-blinmaker.md b/documentation/blog/2020-09-08-blinmaker.md index 4c481415eb..7e522883b2 100644 --- a/documentation/blog/2020-09-08-blinmaker.md +++ b/documentation/blog/2020-09-08-blinmaker.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: Blinmaker -author: Daniel Patanin -author_title: Maintainer of securecodebox.io -author_url: https://github.com/dpatanin -author_image_url: https://avatars1.githubusercontent.com/u/44839597?s=400&u=df006f35797ebb585d8279513305a0bbf1f616b5&v=4 +authors: [daniel_patanin] tags: [cooking, blini] description: This is my first post on securecodebox.io. image: /img/blog/2020-09-08-blini.jpg diff --git a/documentation/blog/2020-10-12-whats-going-on.md b/documentation/blog/2020-10-12-whats-going-on.md index 41f8399275..1a8a93d028 100644 --- a/documentation/blog/2020-10-12-whats-going-on.md +++ b/documentation/blog/2020-10-12-whats-going-on.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: What's Going On -author: Sven Strittmatter -author_title: Core Developer -author_url: https://github.com/Weltraumschaf -author_image_url: https://www.gravatar.com/avatar/3fe213284598b5cb69009665902c77a1 +authors: [sven_strittmatter] tags: - secureCodeBox - v1 diff --git a/documentation/blog/2020-10-15-sundown-and-eol-of-version-1.md b/documentation/blog/2020-10-15-sundown-and-eol-of-version-1.md index 15cc812c17..e0c5f3a8e0 100644 --- a/documentation/blog/2020-10-15-sundown-and-eol-of-version-1.md +++ b/documentation/blog/2020-10-15-sundown-and-eol-of-version-1.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: Sundown and EOL of Version 1 -author: Sven Strittmatter -author_title: Core Developer -author_url: https://github.com/Weltraumschaf -author_image_url: https://www.gravatar.com/avatar/3fe213284598b5cb69009665902c77a1 +authors: [sven_strittmatter] tags: - eol - sundown diff --git a/documentation/blog/2020-10-16-release-of-securecodebox-version-2.md b/documentation/blog/2020-10-16-release-of-securecodebox-version-2.md index 9b4226de11..db38c8b922 100644 --- a/documentation/blog/2020-10-16-release-of-securecodebox-version-2.md +++ b/documentation/blog/2020-10-16-release-of-securecodebox-version-2.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: Release of Version 2 -author: Sven Strittmatter -author_title: Core Developer -author_url: https://github.com/Weltraumschaf -author_image_url: https://www.gravatar.com/avatar/3fe213284598b5cb69009665902c77a1 +authors: [sven_strittmatter] tags: - secureCodeBox - release diff --git a/documentation/blog/2021-01-27-drop-support-of-k8s-1.16.md b/documentation/blog/2021-01-27-drop-support-of-k8s-1.16.md index 6c00c4c99b..04640ab34c 100644 --- a/documentation/blog/2021-01-27-drop-support-of-k8s-1.16.md +++ b/documentation/blog/2021-01-27-drop-support-of-k8s-1.16.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: Drop Support of k8s 1.16 -author: Sven Strittmatter -author_title: Core Developer -author_url: https://github.com/Weltraumschaf -author_image_url: https://www.gravatar.com/avatar/3fe213284598b5cb69009665902c77a1 +authors: [sven_strittmatter] tags: - secureCodeBox - v2 @@ -20,6 +17,8 @@ image: /img/blog/2021-01-27-drop.jpg Photo by [Levi XU](https://unsplash.com/@xusanfeng) on [Unsplash](https://unsplash.com/s/photos/drop). -As [documented](/docs/getting-started/installation#version-support) we only support the latest four releases of [Kubernetes](https://kubernetes.io/). This means we **removed support** for [Kubernetes](https://kubernetes.io/) 1.16 with the _secureCodeBox_ [release 2.3.0](https://github.com/secureCodeBox/secureCodeBox/releases/tag/v2.3.0). +As [documented](/docs/getting-started/installation#supported-kubernetes-version) we only support the latest four releases of [Kubernetes](https://kubernetes.io/). This means we **removed support** for [Kubernetes](https://kubernetes.io/) 1.16 with the _secureCodeBox_ [release 2.3.0](https://github.com/secureCodeBox/secureCodeBox/releases/tag/v2.3.0). + + If you rely on that particular version of [Kubernetes](https://kubernetes.io/), we may help you with custom paid support. Please contact us via [email](mailto:securecodebox@iteratec.com) or open an [GitHub issue](https://github.com/secureCodeBox/secureCodeBox/issues). diff --git a/documentation/blog/2021-06-07-why-securecodebox-version-2.md b/documentation/blog/2021-06-07-why-securecodebox-version-2.md index 0753225210..9a43cecebb 100644 --- a/documentation/blog/2021-06-07-why-securecodebox-version-2.md +++ b/documentation/blog/2021-06-07-why-securecodebox-version-2.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: Why secureCodeBox Version 2 -author: Sven Strittmatter -author_title: Core Developer -author_url: https://github.com/Weltraumschaf -author_image_url: https://www.gravatar.com/avatar/3fe213284598b5cb69009665902c77a1 +authors: [sven_strittmatter] tags: - secureCodeBox - architecture diff --git a/documentation/blog/2021-07-20-the-architecture-of-securecodebox-v2.md b/documentation/blog/2021-07-20-the-architecture-of-securecodebox-v2.md index cef8f1e97e..c9c27aa34d 100644 --- a/documentation/blog/2021-07-20-the-architecture-of-securecodebox-v2.md +++ b/documentation/blog/2021-07-20-the-architecture-of-securecodebox-v2.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: The New Architecture -author: Sven Strittmatter -author_title: Core Developer -author_url: https://github.com/Weltraumschaf -author_image_url: https://www.gravatar.com/avatar/3fe213284598b5cb69009665902c77a1 +authors: [sven_strittmatter] tags: - secureCodeBox - architecture diff --git a/documentation/blog/2021-08-09-integrating-windows-scanners.md b/documentation/blog/2021-08-09-integrating-windows-scanners.md index d9973afd0b..8f42e1a0f8 100644 --- a/documentation/blog/2021-08-09-integrating-windows-scanners.md +++ b/documentation/blog/2021-08-09-integrating-windows-scanners.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: Windows Scanners and the secureCodeBox -author: Sebastian Franz -author_title: Contributor -author_url: https://github.com/SebieF -author_image_url: https://avatars.githubusercontent.com/u/32578476?v=4 +authors: [sebastian_franz] tags: - secureCodeBox - windows diff --git a/documentation/blog/2021-09-07-how-we-work.md b/documentation/blog/2021-09-07-how-we-work.md index 33320bc058..ffbf108bef 100644 --- a/documentation/blog/2021-09-07-how-we-work.md +++ b/documentation/blog/2021-09-07-how-we-work.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: How Our Core Development Team Works -author: Sebastian Franz -author_title: Core Developer -author_url: https://github.com/SebieF -author_image_url: https://avatars.githubusercontent.com/u/32578476?v=4 +authors: [sebastian_franz] tags: - secureCodeBox - agile diff --git a/documentation/blog/2021-10-27-sast-scanning.md b/documentation/blog/2021-10-27-sast-scanning.md index 463f3b4d78..e86968b20a 100644 --- a/documentation/blog/2021-10-27-sast-scanning.md +++ b/documentation/blog/2021-10-27-sast-scanning.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: Introducing SAST Scanning With secureCodeBox 3.3 -author: Max Maass -author_title: Core Developer -author_url: https://github.com/malexmave -author_image_url: https://avatars.githubusercontent.com/u/1688580?v=4 +authors: [max_maass] tags: - secureCodeBox - SAST @@ -272,7 +269,7 @@ spec: initContainers: - name: "git-clone" # Use a container with the git binary - image: bitnami/git + image: alpine/git # We are assembling the git clone URL with HTTP authentication, # using the same personal access token as in the git-repo-scanner. # Note that using {{{triple braces}}} is important, as otherwise the diff --git a/documentation/blog/2022-01-18-log4shell.md b/documentation/blog/2022-01-18-log4shell.md index 7a8f1af9e2..4d33820b02 100644 --- a/documentation/blog/2022-01-18-log4shell.md +++ b/documentation/blog/2022-01-18-log4shell.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: How We Used the secureCodeBox In Our Log4Shell Incident Response -author: The secureCodeBox Team -author_title: Core Developer -author_url: https://github.com/secureCodeBox -author_image_url: https://avatars.githubusercontent.com/u/34573705?v=4 +authors: [securecodebox_team] tags: - secureCodeBox - case study diff --git a/documentation/blog/2023-09-01-automate-zap-with-authentication.md b/documentation/blog/2023-09-01-automate-zap-with-authentication.md index c6eaf9e311..2907e34b29 100644 --- a/documentation/blog/2023-09-01-automate-zap-with-authentication.md +++ b/documentation/blog/2023-09-01-automate-zap-with-authentication.md @@ -4,15 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: Automate ZAP with Authentication -authors: - - name: Rebecca Falke - title: Core Developer - url: https://github.com/rebeccan - image_url: https://avatars.githubusercontent.com/u/5824721?s=400&u=0e2d51378109239b2e5822a2c9a43b04b96c43fb&v=4 - - name: Max Maass - title: Core Developer - url: https://github.com/malexmave - image_url: https://avatars.githubusercontent.com/u/1688580?v=4 +authors: [rebecca_falke, max_maass] tags: - secureCodeBox - ZAP automation diff --git a/documentation/blog/2023-09-01-sbom-part-one-generation.md b/documentation/blog/2023-09-01-sbom-part-one-generation.md index b4f579a1b1..35ce469f5d 100644 --- a/documentation/blog/2023-09-01-sbom-part-one-generation.md +++ b/documentation/blog/2023-09-01-sbom-part-one-generation.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: 'Developing an SBOM Workflow – Part 1: SBOM Generation' -author: Lukas Fischer -author_title: Core Developer -author_url: https://github.com/o1oo11oo -author_image_url: https://avatars.githubusercontent.com/u/1590475?v=4 +authors: [lukas_fischer] tags: - secureCodeBox - comparison diff --git a/documentation/blog/2023-09-15-sbom-part-two-consumption.md b/documentation/blog/2023-09-15-sbom-part-two-consumption.md index 125dec5f7c..cf7a03a047 100644 --- a/documentation/blog/2023-09-15-sbom-part-two-consumption.md +++ b/documentation/blog/2023-09-15-sbom-part-two-consumption.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: 'Developing an SBOM Workflow – Part 2: SBOM Consumption' -author: Lukas Fischer -author_title: Core Developer -author_url: https://github.com/o1oo11oo -author_image_url: https://avatars.githubusercontent.com/u/1590475?v=4 +authors: [lukas_fischer] tags: - secureCodeBox - comparison diff --git a/documentation/blog/2024-06-28-helm-chart-oci-registry-migration.md b/documentation/blog/2024-06-28-helm-chart-oci-registry-migration.md index 49a224a22c..2a176ddd2d 100644 --- a/documentation/blog/2024-06-28-helm-chart-oci-registry-migration.md +++ b/documentation/blog/2024-06-28-helm-chart-oci-registry-migration.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: "Migrating our Helm Charts to OCI registries" -author: Jannik Hollenbach -author_title: Core Developer -author_url: https://github.com/J12934 -author_image_url: https://avatars.githubusercontent.com/u/13718901?v=4 +authors: [jannik_hollenbach] tags: - secureCodeBox - helm @@ -18,6 +15,8 @@ description: All secureCodeBox helm charts will be provided via OCI registry bas With the secureCodeBox 4.6.0 release, we are transitioning our installation instructions from the old `https://charts.securecodebox.io` Helm registry to the new Helm registry infrastructure, which uses Open Container Initiative (`OCI`) images to store charts. + + ## What Will Happen? - The existing registry (`https://charts.securecodebox.io`) will be deprecated with secureCodeBox 4.6.0 and will be shut down at the end of the year. diff --git a/documentation/blog/2024-08-20-google-summer-of-code.md b/documentation/blog/2024-08-20-google-summer-of-code.md index 45eb5574a2..4df501a8d2 100644 --- a/documentation/blog/2024-08-20-google-summer-of-code.md +++ b/documentation/blog/2024-08-20-google-summer-of-code.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: 'Streamlining Security Scans with secureCodeBox: My Google Summer of Code Journey' -author: Thibaut Batale -author_title: Gsoc'24 Contributor -author_url: https://github.com/Freedisch -author_image_url: https://avatars.githubusercontent.com/u/82499435?s=96&v=4 +authors: [thibaut_batale] tags: - Google summer of code - scbctl @@ -22,7 +19,9 @@ image: /img/blog/2024-08-20-gsoc.png --- -Hey there, I’m Thibaut Batale, and I’m thrilled to share my experience as a Google Summer of Code contributor with OWASP secureCodeBox. Being selected to participate in this program was a unique opportunity, but what excited me the most was being chosen for the very first project I applied to. I wanted to spend this summer battling with Kubernetes, and I got exactly what I wished for—and more. +Hey there, I'm Thibaut Batale, and I'm thrilled to share my experience as a Google Summer of Code contributor with OWASP secureCodeBox. Being selected to participate in this program was a unique opportunity, but what excited me the most was being chosen for the very first project I applied to. I wanted to spend this summer battling with Kubernetes, and I got exactly what I wished for—and more. + + If you’re curious about my contributions during GSoC 2024, you can check out my [Pull Requests](https://github.com/secureCodeBox/secureCodeBox/pulls?q=is:pr+author:Freedisch+is:closed) on GitHub. You can also find more details about my project by visiting the [Project link](https://summerofcode.withgoogle.com/programs/2024/projects/vFuhwP9m). diff --git a/documentation/blog/2024-10-25-removing-mozilla-ssh_scan-scantype-in-4.10.md b/documentation/blog/2024-10-25-removing-mozilla-ssh_scan-scantype-in-4.10.md index 9f2eb69aac..eab9a3d8f8 100644 --- a/documentation/blog/2024-10-25-removing-mozilla-ssh_scan-scantype-in-4.10.md +++ b/documentation/blog/2024-10-25-removing-mozilla-ssh_scan-scantype-in-4.10.md @@ -5,10 +5,7 @@ title: Removing Mozilla ssh_scan ScanType in 4.10.0 description: In release 4.10.0, we are removing the ssh-scan ScanType due to the deletion of the associated Docker Hub repository. Users are advised to switch to the newer ssh-audit scanner, introduced after the deprecation of Mozilla's ssh_scan project. -author: Jannik Hollenbach -author_title: Core Developer -author_url: https://github.com/J12934 -author_image_url: https://avatars.githubusercontent.com/u/13718901?v=4 +authors: [jannik_hollenbach] tags: - secureCodeBox - ssh @@ -18,6 +15,8 @@ tags: We are removing the ssh-scan ScanType With release 4.10.0. The ssh-scan ScanType was using the [mozilla/ssh_scan](https://github.com/mozilla/ssh_scan) project. + + We already had the release scheduled for the next breaking release (v5.0.0), but we can't wait until then as the Docker Hub repository (`docker.io/mozilla/ssh_scan`) which contained the scanner was already deleted by either Mozilla or DockerHub. This makes using the scanner in any version no longer possible. diff --git a/documentation/blog/2024-10-25-run-x86-images-with-kubernetes-on-apple-silicon.md b/documentation/blog/2024-10-25-run-x86-images-with-kubernetes-on-apple-silicon.md index ed2ba89b06..24c69bb6f4 100644 --- a/documentation/blog/2024-10-25-run-x86-images-with-kubernetes-on-apple-silicon.md +++ b/documentation/blog/2024-10-25-run-x86-images-with-kubernetes-on-apple-silicon.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: Run x86 Images With Kubernetes on Apple Silicon -author: Sven Strittmatter -author_title: Core Developer -author_url: https://github.com/Weltraumschaf -author_image_url: https://www.gravatar.com/avatar/3fe213284598b5cb69009665902c77a1 +authors: [sven_strittmatter] tags: - secureCodeBox - v2 @@ -23,6 +20,8 @@ Cover photo by [Bill Fairs](https://unsplash.com/@moonboyz) on [Unsplash](https: Maybe you've heard from the shiny new CPUs from Apple: [Silicon](https://en.wikipedia.org/wiki/Apple_silicon). Besides the good things (low power consumption, less fan noise) they have not so shiny drawbacks. One ran into is the problem of running containers built with/for x86 architecture. Yes, the problem itself is completely solved: Multi arch images. But, not every project builds them. No, I'm not looking at you [DefectDojo](https://www.defectdojo.org/) 😉 BTW _secureCodeBox_ provides multi arch images 🤗 So, I tinkered around with my Mac to get our _secureCodeBox_ setup with DefectDojo up and running on Silicon Macs. Since there was not much help out there in the Internet I use this post to summarize the steps to get it run, for later reference. + + ## Colima FTW I use [Colima](https://github.com/abiosoft/colima) since roundabout a year now as drop in replacement for Docker Desktop. Works great. It was never necessary to read docs. It runs x86 images emulated via Qemu. But running single containers is not sufficient for _secureCodeBox_. Kubernetes is mandatory. Until now, I used Minikube, but it can't run x86 images on Silicon Macs. KIND also does not support them, as my colleagues told me. Some days ago, I told a friend about Colima, and he said: "Oh, nice. It can start a Kubernetes cluster." diff --git a/documentation/blog/2024-12-27-meet-us-at-38c3.md b/documentation/blog/2024-12-27-meet-us-at-38c3.md index 5c64b8a468..d76df5fdca 100644 --- a/documentation/blog/2024-12-27-meet-us-at-38c3.md +++ b/documentation/blog/2024-12-27-meet-us-at-38c3.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: Meet Us At 38C3 -author: Sven Strittmatter -author_title: Core Developer -author_url: https://github.com/Weltraumschaf -author_image_url: https://www.gravatar.com/avatar/3fe213284598b5cb69009665902c77a1 +authors: [sven_strittmatter] tags: - events - conferences diff --git a/documentation/blog/2025-02-07-we-remove-vagrant-all-setup.md b/documentation/blog/2025-02-07-we-remove-vagrant-all-setup.md index 3695d5dab5..c28129d851 100644 --- a/documentation/blog/2025-02-07-we-remove-vagrant-all-setup.md +++ b/documentation/blog/2025-02-07-we-remove-vagrant-all-setup.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: We Remove Vagrant Setup -author: Sven Strittmatter -author_title: Core Developer -author_url: https://github.com/Weltraumschaf -author_image_url: https://www.gravatar.com/avatar/3fe213284598b5cb69009665902c77a1 +authors: [sven_strittmatter] tags: - eol - macos diff --git a/documentation/blog/2025-07-10-try-out-securecodebox-as-a-service.md b/documentation/blog/2025-07-10-try-out-securecodebox-as-a-service.md index 2407942903..0b0c729211 100644 --- a/documentation/blog/2025-07-10-try-out-securecodebox-as-a-service.md +++ b/documentation/blog/2025-07-10-try-out-securecodebox-as-a-service.md @@ -4,10 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 title: secureCodeBox as a Service -author: Sven Strittmatter -author_title: Core Developer -author_url: https://github.com/Weltraumschaf -author_image_url: https://www.gravatar.com/avatar/3fe213284598b5cb69009665902c77a1 +authors: [sven_strittmatter] tags: - kubernetes - release diff --git a/documentation/blog/2025-08-18-announcing-securecodebox-v5.md b/documentation/blog/2025-08-18-announcing-securecodebox-v5.md new file mode 100644 index 0000000000..e4a799eea2 --- /dev/null +++ b/documentation/blog/2025-08-18-announcing-securecodebox-v5.md @@ -0,0 +1,95 @@ +--- +# SPDX-FileCopyrightText: the secureCodeBox authors +# +# SPDX-License-Identifier: Apache-2.0 + +title: "Announcing secureCodeBox v5.0.0: Major Modernization and Breaking Changes" +authors: [jannik_hollenbach] +tags: + - secureCodeBox + - v5 + - release + - breaking-changes + - modernization +description: secureCodeBox v5.0.0 brings significant modernization with scanner updates, CommonJS to ESM migration, and important infrastructure changes including MinIO deployment updates. +--- + +We're excited to announce the release of secureCodeBox v5.0.0! This major version brings significant modernization efforts, performance improvements, and important breaking changes that strengthen the foundation of our security scanning platform. + + + +## Major Breaking Changes + +### Scanner Ecosystem Overhaul + +We've made significant changes to our scanner lineup to improve performance and maintainability: + +**Removed Scanners:** +- `zap-baseline-scan` and `zap-advanced` - replaced by the more powerful `zap-automation-framework` +- `amass` - replaced by `subfinder`. While amass is an amazing tool, its recent focus on becoming a standalone platform/database for attack surfaces made integration and updates in secureCodeBox increasingly challenging +- `kubeaudit` - users should migrate to `trivy` with Kubernetes mode +- `typo3scan`, `doggo`, and `cmseek` - removed due to maintenance overhead + +**New Addition:** +- **`subfinder`** - A very good replacement for subdomain discovery that's also generally quicker and produces similar results to previous tools. This represents a significant improvement in our subdomain enumeration capabilities. + +### CommonJS to ESM Migration: A Technical Leap Forward + +One of the most significant technical improvements in v5.0.0 is the complete migration of all parsers and hooks from CommonJS to ECMAScript Modules (ESM). This modernization effort brings several benefits: + +- **Performance Improvements**: ESM provides better tree-shaking and optimization opportunities, leading to reduced CPU load and faster execution times +- **Modern JavaScript Support**: Enables us to leverage the latest JavaScript features and maintain compatibility with modern Node.js versions +- **Dependency Updates**: As part of this migration, we've updated to `@kubernetes/client-node v1.x` and other modern dependencies +- **Future-Proofing**: ESM is the standard for JavaScript modules, ensuring long-term compatibility and maintainability + +This migration required significant refactoring work but results in a more robust and performant codebase that will serve as a solid foundation for future developments. + +### MinIO Infrastructure Changes: Ensuring Stability + +We've replaced the Bitnami MinIO subchart with a direct MinIO deployment due to upstream stability issues. The upstream minio/charts and images were no longer providing a stable environment, requiring us to implement a more reliable solution. + +**Important Migration Notes:** +- **Data Migration**: Data will NOT be migrated automatically from previous MinIO deployments. However, since secureCodeBox's S3 storage is designed for temporary file storage during scan runtime, this is usually not an issue +- **Backup Recommendation**: For users with important data, we recommend performing a backup before upgrading +- **Production Environments**: Continue using external S3-compatible storage solutions for production deployments + +### Additional Breaking Changes + +- **Kubernetes RBAC**: Renamed ClusterRole from `manager-role` to `securecodebox-manager-role` for better naming consistency +- **Trivy Scope**: Changed default Kubernetes scope from cluster to namespace for improved security posture +- **Elasticsearch**: Dropped integrated Elasticsearch and Kibana Helm charts, changed default index from `scbv2` to `scb` + +## Significant Performance Improvements + +Beyond the breaking changes, v5.0.0 includes impressive performance enhancements achieved by bundling the parser & hook SDK: + +- **Reduced CPU Load**: Up to 5x reduction in CPU usage across parsers and hooks +- **Faster Execution**: Parser and hook execution times improved by up to 2x +- **Enhanced Security**: Updated security contexts and resource configurations for better container security +- **Scanner Updates**: Multiple scanner versions updated including gitleaks, nuclei, semgrep, and trivy + +These performance improvements represent some of the most significant optimizations in secureCodeBox's history, directly impacting resource efficiency and scan completion times. + +## Kubernetes Service AutoDiscovery Enhancement + +We've migrated the Kubernetes Service AutoDiscovery feature to use the ZAP Automation Framework, providing better integration and more consistent scanning capabilities. + +## Migration Guide + +For detailed migration instructions and breaking change information, please refer to our [full release notes](https://github.com/secureCodeBox/secureCodeBox/releases/tag/v5.0.0) on GitHub. + +**Key Migration Steps:** +1. Review removed scanners and update your scan configurations +2. Plan for MinIO data migration if using persistent storage +3. Update any custom RBAC references to the new ClusterRole names +4. Test scanner replacements (especially `subfinder` for `amass` users) + +## Looking Forward + +Version 5.0.0 represents a significant milestone in secureCodeBox's evolution. The modernization efforts, particularly the ESM migration and infrastructure updates, provide a solid foundation for future innovations while improving performance and maintainability. + +We encourage all users to carefully review the breaking changes and plan their migration accordingly. As always, our community is ready to help with any questions or issues you encounter during the upgrade process. + +For the complete changelog and technical details, visit the [v5.0.0 release page](https://github.com/secureCodeBox/secureCodeBox/releases/tag/v5.0.0) on GitHub. + +Happy scanning! 🔍 diff --git a/documentation/blog/authors.yml b/documentation/blog/authors.yml new file mode 100644 index 0000000000..4a7bfcff26 --- /dev/null +++ b/documentation/blog/authors.yml @@ -0,0 +1,57 @@ +# SPDX-FileCopyrightText: the secureCodeBox authors +# +# SPDX-License-Identifier: Apache-2.0 + +sven_strittmatter: + name: Sven Strittmatter + title: Core Developer + url: https://github.com/Weltraumschaf + image_url: https://www.gravatar.com/avatar/3fe213284598b5cb69009665902c77a1 + +daniel_patanin: + name: Daniel Patanin + title: Maintainer of securecodebox.io + url: https://github.com/dpatanin + image_url: https://avatars1.githubusercontent.com/u/44839597?s=400&u=df006f35797ebb585d8279513305a0bbf1f616b5&v=4 + +sebastian_franz: + name: Sebastian Franz + title: Core Developer + url: https://github.com/SebieF + image_url: https://avatars.githubusercontent.com/u/32578476?v=4 + +max_maass: + name: Max Maass + title: Core Developer + url: https://github.com/malexmave + image_url: https://avatars.githubusercontent.com/u/1688580?v=4 + +rebecca_falke: + name: Rebecca Falke + title: Core Developer + url: https://github.com/rebeccan + image_url: https://avatars.githubusercontent.com/u/5824721?s=400&u=0e2d51378109239b2e5822a2c9a43b04b96c43fb&v=4 + +lukas_fischer: + name: Lukas Fischer + title: Core Developer + url: https://github.com/o1oo11oo + image_url: https://avatars.githubusercontent.com/u/1590475?v=4 + +jannik_hollenbach: + name: Jannik Hollenbach + title: Core Developer + url: https://github.com/J12934 + image_url: https://avatars.githubusercontent.com/u/13718901?v=4 + +securecodebox_team: + name: The secureCodeBox Team + title: Core Developer + url: https://github.com/secureCodeBox + image_url: https://avatars.githubusercontent.com/u/34573705?v=4 + +thibaut_batale: + name: Thibaut Batale + title: Gsoc'24 Contributor + url: https://github.com/Freedisch + image_url: https://avatars.githubusercontent.com/u/82499435?s=96&v=4 \ No newline at end of file diff --git a/documentation/docs/12-mentions.md b/documentation/docs/12-mentions.md index ee3b7c28cb..56f3c6c66a 100644 --- a/documentation/docs/12-mentions.md +++ b/documentation/docs/12-mentions.md @@ -11,6 +11,7 @@ Here we collect blog posts, articles, talks about etc. _secureCodeBox_. They are ## Blog Posts and Articles +- [Automating Penetration Testing with SecureCodeBox on Kubernetes Kind Clusters Using GitHub Actions][gharbi-post] 🇬🇧 by [Yasmine Gharbi][gharbi-author]. - [Wprowadzenie do OWASP secureCodeBox][lukasz-post] 🇵🇱 by [Łukasz Mieczkowski][lukasz-blog]. - [Exploring secureCodeBox — An Open-Source Continuous Security Testing Solution for DevSecOps][theowni-post] 🇬🇧 by [Krzysztof Pranczk][theowni-author]. - [SecureCodeBox — k8s based, toolchain for continuous security scans][gortega-post] 🇬🇧 by [Gustavo Ortega][gortega-author]. @@ -30,6 +31,8 @@ Here we collect blog posts, articles, talks about etc. _secureCodeBox_. They are - [Interview with RadioTux on YouTube][radiotux-youtube] 🇩🇪 ([Podcast Episode][radiotux-podcast]). - [35 DevSecOps Tools to Add Sec to Your DevOps][thechief.io] 🇬🇧. +[gharbi-author]: https://www.linkedin.com/in/yasmine-gharbi-39b67221a/ +[gharbi-post]: https://medium.com/@gyasmine29/automating-penetration-testing-with-securecodebox-on-kubernetes-kind-clusters-using-github-actions-27230b8b087c [theowni-post]: https://itnext.io/exploring-securecodebox-an-open-source-continuous-security-testing-solution-for-devsecops-b233fc5341e1 [theowni-author]: https://medium.com/@theowni [gortega-post]: https://gortega.medium.com/securecodebox-an-interesting-tool-bab410185b77 diff --git a/documentation/docs/api/crds/cascading-rule.md b/documentation/docs/api/crds/cascading-rule.md index a91d0d6e46..827f4286fd 100644 --- a/documentation/docs/api/crds/cascading-rule.md +++ b/documentation/docs/api/crds/cascading-rule.md @@ -7,44 +7,60 @@ title: "CascadingRule" sidebar_position: 7 --- -## Specification (Spec) +CascadingRules are Custom Resource Definitions (CRDs) used to define how scans can be started automatically based on the results of previous scans. This allows you to run large exploratory scans and automatically start more in-depth scans on the targets found by the initial scans. -CascadingRules are Custom Resource Definitions (CRD's) used to define how scans can be started automatically based on the results of previous scans. This lets you run large exploratory scans and automatically start more in depth scans on the targets found by the initial scans. +You can find a more concrete example of how this works in the [network scanning how-to](/docs/how-tos/scanning-networks). -You can find a more concrete example on how this works in the [network scanning how-to](/docs/how-tos/scanning-networks). +## Specification (Spec) ### Matches (Required) -### Matches.AnyOf (Required) +The `matches` field defines which findings should trigger the CascadingRule. + +#### Matches.AnyOf (Required) + +The `matches.anyOf` field consists of a list of matching rules. +These rules are compared using a partial deep comparison, meaning that all specified fields in the rule must exactly match the corresponding fields in the finding. -The `matches.anyOf` fields consists of a list of objects / hashes. -These objects are compared using a partial deep comparison, meaning that all field of the object must exactly match the finding. +If multiple `anyOf` rules are specified, at least one must match the finding. +If multiple rules match, the CascadingRule will still only create one scan. -If multiple anyOf rules are specified at least one must match the finding. -If multiple rules are matching, the CascadingRule will still only create one scan. +Each rule can match against the following finding fields: + +- `name`: The name of the finding +- `category`: The category of the finding (e.g., "Open Port", "Subdomain") +- `description`: The description of the finding +- `location`: The location where the finding was discovered +- `severity`: The severity level (e.g., "HIGH", "MEDIUM", "LOW", "INFORMATIONAL") +- `osi_layer`: The OSI layer (e.g., "NETWORK", "APPLICATION") +- `attributes`: Key-value pairs of additional finding attributes (supports string and numeric values) ### ScanLabels & ScanAnnotations (Optional) -Configures additional labels/annotations/ added to each subsequent scan (child). These labels/annotations overwrite any existing labels/annotations. You can use a simple templating scheme to gather details about the parent scan or finding (use `{{variable}}`, see example below). The following variables are available: +Configures additional labels and annotations added to each subsequent scan (child). These labels and annotations override any existing ones. You can use a simple templating scheme to gather details about the parent scan or finding (use `{{variable}}`, see example below). The following variables are available: -- The parent [scan](/docs/api/crds/scan) (e.g. `metadata.name`). -- The related [finding](/docs/api/finding) (e.g. `category`, `attributes.hostname`). +- The parent [scan](/docs/api/crds/scan) (e.g., `{{metadata.name}}`). +- The related [finding](/docs/api/finding) (e.g., `{{category}}`, `{{attributes.hostname}}`). - Custom variables (prepended with `$.`): - - `hostOrIP`: `finding.hostname || finding.ip_address` + - `{{$.hostOrIP}}`: Returns `finding.hostname || finding.ip_address` If you need more custom variables, please don't hesitate to [create an issue](https://github.com/secureCodeBox/secureCodeBox/issues/new?assignees=&labels=enhancement&template=feature_request.md)! ### ScanSpec (Required) -Contains the [spec of the scan](/docs/api/crds/scan#specification-spec) which is supposed to be started of the a finding matches the CascadingRule. +Contains the [spec of the scan](/docs/api/crds/scan#specification-spec) that should be started when a finding matches the CascadingRule. -The `scanType`, `parameters`, values specified in `env` variables, as well as the `command` and `env` of any included `initContainers`, can use [mustache](https://mustache.github.io/mustache.5.html) templates to refer to fields of the finding the CascadingRule has been applied to. The finding is passed in directly into the mustache templating call, so that fields of the findings can be directly referenced. E.g. the location can be directly referred to by: `{{location}}`. +The `scanType`, `parameters`, values specified in `env` variables, as well as the `command` and `env` of any included `initContainers`, can use [Mustache](https://mustache.github.io/mustache.5.html) templates to refer to fields of the finding the CascadingRule has been applied to. The finding is passed directly into the Mustache templating call, so finding fields can be directly referenced. For example, the location can be referenced as: `{{location}}`. -For convenience a helper object has been added to the mustache call under the `$` shorthand. +For convenience, a helper object has been added to the Mustache call under the `$` shorthand. This helper object has the following attributes: -- `$.hostOrIP` returns either the hostname (if available) or the hostname of the current finding. +- `{{$.hostOrIP}}` returns either the hostname (if available) or the IP address of the current finding. + +## Status + +The CascadingRule status is currently empty and managed entirely by Kubernetes. Future versions may include additional status information such as the number of scans triggered by this rule. ## Example @@ -59,13 +75,31 @@ metadata: spec: matches: anyOf: + - category: "Open Port" + attributes: + state: "open" - category: "Subdomain" osi_layer: "NETWORK" + - name: "HTTP Service" + severity: "INFORMATIONAL" + scanLabels: + scan.securecodebox.io/cascade-from: "{{metadata.name}}" + scan.securecodebox.io/finding-category: "{{category}}" + scanAnnotations: + cascading.securecodebox.io/matched-finding: "{{name}}" + cascading.securecodebox.io/target-host: "{{$.hostOrIP}}" scanSpec: scanType: "nmap" parameters: # Treat all hosts as online -- skip host discovery - "-Pn" - # Target Port of the finding - - "{{location}}" + # Perform service version detection + - "-sV" + # Target the specific host/port from the finding + - "{{$.hostOrIP}}" + env: + - name: TARGET_HOST + value: "{{$.hostOrIP}}" + - name: FINDING_CATEGORY + value: "{{category}}" ``` diff --git a/documentation/docs/api/crds/parse-definition.md b/documentation/docs/api/crds/parse-definition.md index 94093f3a9a..bd0ce573af 100644 --- a/documentation/docs/api/crds/parse-definition.md +++ b/documentation/docs/api/crds/parse-definition.md @@ -7,45 +7,86 @@ title: "ParseDefinition" sidebar_position: 5 --- -ParseDefinitions are Custom Resource Definitions (CRD's) used to describe to the secureCodeBox how it can convert a raw finding report (e.g. XML report from nmap) into the generic [secureCodeBox finding format](/docs/api/finding). +ParseDefinitions are Custom Resource Definitions (CRDs) that describe how the secureCodeBox can convert a raw finding report (e.g., XML report from nmap) into the generic [secureCodeBox finding format](/docs/api/finding). -ParseDefinitions are generally packaged together with a [ScanType](/docs/api/crds/scan-type/). -A scanType will reference the **name** of a _ParseDefinition_ via the [extractResults.type field](/docs/api/crds/scan-type#extractresultstype-required). +ParseDefinitions are typically packaged together with a [ScanType](/docs/api/crds/scan-type/). +A ScanType references the **name** of a ParseDefinition via the [extractResults.type field](/docs/api/crds/scan-type#extractresultstype-required). ## Specification (Spec) ### Image (Required) -`image` is the reference to the parser container image which can transform the raw scan report into findings. +`image` is the reference to the parser container image that can transform the raw scan report into findings. -To see how to write parsers and package them into images, check out the [documentation page on integrating new scanners](/docs/contributing/integrating-a-scanner). +To learn how to write parsers and package them into images, see the [documentation on integrating new scanners](/docs/contributing/integrating-a-scanner). ### ImagePullSecrets (Optional) -`imagePullSecrets` can be used to integrate private parser images. -This uses the kubernetes default [imagePullSecrets structure](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/). +`imagePullSecrets` can be used to access private parser images. +This uses the standard Kubernetes [imagePullSecrets structure](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/). + +### ImagePullPolicy (Optional) + +`imagePullPolicy` defines when the container image should be pulled. Valid values are: + +- `Always`: Always pull the image +- `IfNotPresent` (default): Pull the image only if not present locally +- `Never`: Never pull the image + +Defaults to `Always` if the `:latest` tag is specified, otherwise `IfNotPresent`. + +### ContentType (Optional) + +`contentType` specifies the format of the scan result file. Valid values are: + +- `Text` (default): The scan result is a text file +- `Binary`: The scan result is a binary file + +This helps the parser understand how to process the input data. ### TTLSecondsAfterFinished (Optional) -`ttlSecondsAfterFinished` can be used to automatically delete the completed Kubernetes job used to run the parser. -This sets the `ttlSecondsAfterFinished` field on the created job. This requires your cluster to have the [TTLAfterFinished](https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/) feature gate enabled in your cluster. +`ttlSecondsAfterFinished` can be used to automatically delete the completed Kubernetes Job used to run the parser. +This sets the `ttlSecondsAfterFinished` field on the created Job. This requires your cluster to have the [TTLAfterFinished](https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/) feature gate enabled. ### ScopeLimiterAliases (Optional) `scopeLimiterAliases` can be used in combination with `scopeLimiter` to create aliases for fields in findings. -The goal of this field is to ensure that the `scopeSelector` can always select an alias, regardless of the underlying representation of the data in a finding. +This ensures that the `scopeSelector` can always select an alias, regardless of the underlying data representation in a finding. This field supports Mustache templating and has access to the finding object. +### Env (Optional) + +`env` allows you to specify environment variables for the parser container. +This uses the same API as the `env` property on Kubernetes Pods. + +See the [Kubernetes documentation](https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) for more details. + +### Volumes and VolumeMounts (Optional) + +`volumes` and `volumeMounts` allow you to specify volumes and their mount points for the parser container. +This can be useful for providing additional data or configuration files to the parser. + +These use the same API as the `volumes` and `volumeMounts` properties on Kubernetes Pods. + +See the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-volume-storage/) for more details. + +### NodeSelector (Optional) + +`nodeSelector` allows you to specify simple node selection constraints to control which nodes the parser runs on. + +See the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/) for more details. + See the [Scope HowTo](/docs/how-tos/scope) for more information. ### Affinity and Tolerations (optional) -[`affinity`](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) and [`tolerations`](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) can be used to control which nodes the parser is executed on. -The values should be set via Helm values (during install) or by specifying `affinity` and/or `tolerations` in the `Scan` specification. +[`affinity`](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) and [`tolerations`](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) can be used to control which nodes the parser is executed on with more advanced rules than nodeSelector. +These values are typically set via Helm values during installation. ### Resources (Optional) -`resources` lets you overwrite the resource limits and requests for the parser container. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +`resources` lets you override the resource limits and requests for the parser container. See the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for more details. ```yaml resources: @@ -79,29 +120,45 @@ resources: limits: null ``` +## Status + +The ParseDefinition status is currently empty and managed entirely by Kubernetes. Future versions may include additional status information. + ## Example ```yaml apiVersion: execution.securecodebox.io/v1 kind: ParseDefinition metadata: - name: zap-xml + name: nmap-xml spec: - affinity: - foo: bar - env: [] - image: docker.io/securecodebox/parser-zap-automation-framework:0.0.0 + image: docker.io/securecodebox/parser-nmap:latest imagePullPolicy: IfNotPresent + contentType: Text + env: + - name: DEBUG + value: "false" imagePullSecrets: - - name: foo + - name: private-registry-secret + nodeSelector: + kubernetes.io/arch: amd64 resources: - foo: bar + requests: + cpu: 200m + memory: 100Mi + limits: + cpu: 400m + memory: 200Mi scopeLimiterAliases: - foo: bar + ip: "{{attributes.ip_address}}" + hostname: "{{attributes.hostname}}" + ttlSecondsAfterFinished: 300 tolerations: - - foo: bar - ttlSecondsAfterFinished: null + - key: "parser-only" + operator: "Equal" + value: "true" + effect: "NoSchedule" ``` -The Parse definition is different when integrating a new scanner. We use specific conventions when adding new ParseDefinitions to the secureCodeBox repository. -More information can be found on the [templates folder documentation page for integrating new scanners](/docs/contributing/integrating-a-scanner/templates-dir) +When integrating a new scanner, the ParseDefinition follows specific conventions used in the secureCodeBox repository. +More information can be found in the [templates folder documentation for integrating new scanners](/docs/contributing/integrating-a-scanner/templates-dir). diff --git a/documentation/docs/api/crds/scan-completion-hook.md b/documentation/docs/api/crds/scan-completion-hook.md index ca7ff3ad8e..03a6c76de4 100644 --- a/documentation/docs/api/crds/scan-completion-hook.md +++ b/documentation/docs/api/crds/scan-completion-hook.md @@ -7,7 +7,7 @@ title: "ScanCompletionHook" sidebar_position: 6 --- -ScanCompletionHooks are Custom Resource Definitions (CRD's) used to define custom behavior which should be run after a scan has been completed. +ScanCompletionHooks are Custom Resource Definitions (CRDs) used to define custom behavior that should be run after a scan has been completed. For more detailed explanations on how a new hook can be integrated, see the [hooks section](/docs/contributing/integrating-a-hook) in the contribution part of our docs. @@ -17,9 +17,9 @@ For more detailed explanations on how a new hook can be integrated, see the [hoo The `type` field can be either `ReadOnly` or `ReadAndWrite`. -`ReadOnly` hooks only have read rights on the findings and the raw scan reports (e.g. XML output from nmap). These are usually used to export the findings into a external system like "Elasticsearch" or "DefectDojo" or to send out notifications to chats like "Slack". ReadOnly hooks are executed in parallel to speed up their runtime. +`ReadOnly` hooks only have read access to the findings and raw scan reports (e.g., XML output from nmap). These are typically used to export findings to external systems like "Elasticsearch" or "DefectDojo" or to send notifications to chat systems like "Slack". ReadOnly hooks are executed in parallel to speed up their runtime. -`ReadAndWrite` hooks have the ability to update both the findings and raw scan reports. This can be used to attach additional metadata to the findings by comparing the findings to external inventory systems or APIs of cloud providers. +`ReadAndWrite` hooks can update both findings and raw scan reports. This can be used to attach additional metadata to findings by comparing them against external inventory systems or cloud provider APIs. ### Priority (Optional) @@ -48,53 +48,59 @@ The following diagram shows an example run: ### Image (Required) -The `image` field contains a container image reference for the image supposed to run as the hook. +The `image` field contains a container image reference for the image that should run as the hook. ### ImagePullSecrets (Optional) -The `imagePullSecrets` field can be used to specify pull secrets used to access the hooks image from a private registry. +The `imagePullSecrets` field can be used to specify pull secrets for accessing the hook's image from a private registry. ### ImagePullPolicy (Optional) -The `imagePullPolicy` field can be used to specify under which circumstances the images should be pulled from the registry. -One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. +The `imagePullPolicy` field specifies when the image should be pulled from the registry. +Valid values are `Always`, `Never`, or `IfNotPresent`. Defaults to `Always` if the `:latest` tag is specified, otherwise `IfNotPresent`. See the [Kubernetes docs](https://kubernetes.io/docs/concepts/containers/images#updating-images) for more information. ### Env (Optional) -The `env` field can be used to specify env variables and to mount secrets into containers. +The `env` field can be used to specify environment variables and mount secrets into containers. ### Volumes (Optional) -`volumes` lets you specify Kubernetes volumes that you want to use and make available to the hook. -Similarly to `env`, it can be used to pass data into a container. -It has to be combined with [`volumeMounts`](#volumemounts-optional) to be useful (see below). +`volumes` lets you specify Kubernetes volumes to make available to the hook. +Similar to `env`, it can be used to pass data into a container. +It must be combined with [`volumeMounts`](#volumemounts-optional) to be useful (see below). ### VolumeMounts (Optional) -`volumeMounts` let you specify where you want the previously-created volumes to be mounted inside the container. -It has the same API as the `volumeMounts` property on Kubernetes pods. +`volumeMounts` lets you specify where previously-created volumes should be mounted inside the container. +It uses the same API as the `volumeMounts` property on Kubernetes Pods. ### Affinity and Tolerations (optional) -[`affinity`](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) and [`tolerations`](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) can be used to control which nodes the parser is executed on. -The values should be set via Helm values (during install) or by specifying `affinity` and/or `tolerations` in the `Scan` specification. +### NodeSelector (Optional) + +[`nodeSelector`](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/) allows you to specify simple node selection constraints to control which nodes the hook runs on. + +### Affinity and Tolerations (Optional) + +[`affinity`](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) and [`tolerations`](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) can be used to control which nodes the hook is executed on with more advanced rules than nodeSelector. +These values are typically set via Helm values during installation. ### ServiceAccountName (Optional) -The `serviceAccountName` field can be used to specify a custom ServiceAccount to use for the Kubernetes Job running the hook. -Should only be used if your hook needs specific RBAC Access. Otherwise the hook is run using a `scan-completion-hook` service account. +The `serviceAccountName` field can be used to specify a custom ServiceAccount for the Kubernetes Job running the hook. +This should only be used if your hook needs specific RBAC access. Otherwise, the hook runs using a `scan-completion-hook` service account. -The service account should have at least `get` rights on `scans.execution.securecodebox.io`, and `get` & `patch` on `scans.execution.securecodebox.io/status` so that the hooks can work correctly. +The service account should have at least `get` permissions on `scans.execution.securecodebox.io`, and `get` & `patch` permissions on `scans.execution.securecodebox.io/status` for hooks to work correctly. ### TTLSecondsAfterFinished (Optional) -`ttlSecondsAfterFinished` can be used to automatically delete the completed Kubernetes job used to run the hook. -This sets the `ttlSecondsAfterFinished` field on the created job. This requires your cluster to have the [TTLAfterFinished](https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/) feature gate enabled in your cluster. +`ttlSecondsAfterFinished` can be used to automatically delete the completed Kubernetes Job used to run the hook. +This sets the `ttlSecondsAfterFinished` field on the created Job. This requires your cluster to have the [TTLAfterFinished](https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/) feature gate enabled. ### Resources (Optional) -`resources` lets you overwrite the resource limits and requests for the hook container. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +`resources` lets you override the resource limits and requests for the hook container. See the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for more details. ```yaml resources: @@ -128,6 +134,10 @@ resources: limits: null ``` +## Status + +The ScanCompletionHook status is currently empty and managed entirely by Kubernetes. Future versions may include additional status information. + ## Example ```yaml @@ -139,8 +149,11 @@ spec: type: ReadOnly priority: 2 image: docker.io/securecodebox/persistence-elastic:latest + imagePullPolicy: IfNotPresent imagePullSecrets: - name: image-pull-secret + nodeSelector: + kubernetes.io/arch: amd64 serviceAccountName: elastic-persistence env: - name: ELASTICSEARCH_ADDRESS @@ -155,12 +168,19 @@ spec: secretKeyRef: key: password name: elastic-persistence-credentials + volumes: + - name: config + configMap: + name: elastic-config + volumeMounts: + - name: config + mountPath: /etc/elastic ttlSecondsAfterFinished: 60 resources: requests: - cpu: 42mi + cpu: 200m memory: 256Mi limits: - cpu: 4 - memory: 4Gi + cpu: 400m + memory: 512Mi ``` diff --git a/documentation/docs/api/crds/scan-type.md b/documentation/docs/api/crds/scan-type.md index e62ddf822f..31f8a3177f 100644 --- a/documentation/docs/api/crds/scan-type.md +++ b/documentation/docs/api/crds/scan-type.md @@ -7,35 +7,39 @@ title: "ScanType" sidebar_position: 4 --- -The ScanType Custom Resource Definition (CRD) is used to define to the secureCodeBox how a specific scanner can be executed in Kubernetes. The main part of the ScanType is the [JobTemplate](#jobtemplate-required), which contains a Kubernetes Job definition that will be used to construct the scans Job. +The ScanType Custom Resource Definition (CRD) defines how a specific scanner can be executed in Kubernetes. The main component is the [JobTemplate](#jobtemplate-required), which contains a Kubernetes Job definition used to construct the scan's Job. ## Specification (Spec) ### ExtractResults (Required) -The `extractResults` field contains an object (fields of the object listed below) which describes what types of results this scanType produced and from where these should be extracted. +The `extractResults` field contains an object that describes the type of results this ScanType produces and where they should be extracted from. #### ExtractResults.Type (Required) -The `type` field indicates the type of the file. -Usually a combination of the scanner name and file type. E.g. `nmap-xml` +The `type` field indicates the format of the result file. +This is typically a combination of the scanner name and file type, such as `nmap-xml`. -The type is used to determine which parser would be used to handle this result file. +This type determines which parser will be used to process the result file. #### ExtractResults.Location (Required) -The `location` field describes from where the result file can be extracted. -The absolute path on the containers file system. +The `location` field specifies where the result file can be extracted from. +This must be an absolute path on the container's filesystem. -Must be located in `/home/securecodebox/` so that the result is reachable by the secureCodeBox Lurker sidecar which performs the actual extraction of the result. -E.g. `/home/securecodebox/nmap-results.xml` +The file must be located within `/home/securecodebox/` so that it's accessible to the secureCodeBox Lurker sidecar, which performs the actual result extraction. +Example: `/home/securecodebox/nmap-results.xml` ### JobTemplate (Required) -Template of the Kubernetes job to create when running the scan. +Template for the Kubernetes Job to create when running the scan. -For info about the JobTemplate generic parameters, see here: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/job-v1/#JobSpec -When specified, as with the `ttlSecondsAfterFinished` parameter, the values from `values.yaml` will be used in the JobTemplate. +For information about JobTemplate parameters, see the [Kubernetes API Reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/job-v1/#JobSpec). +When parameters like `ttlSecondsAfterFinished` are specified, values from `values.yaml` will be used in the JobTemplate. + +## Status + +The ScanType status is currently empty and managed entirely by Kubernetes. Future versions may include additional status information. ## Example @@ -47,7 +51,7 @@ metadata: spec: extractResults: type: nmap-xml - location: "/home/securecodebox/nmap-results.json" + location: "/home/securecodebox/nmap-results.xml" jobTemplate: spec: {{- if .Values.scanner.ttlSecondsAfterFinished }} diff --git a/documentation/docs/api/crds/scan.md b/documentation/docs/api/crds/scan.md index e637c660ec..a0574b0e53 100644 --- a/documentation/docs/api/crds/scan.md +++ b/documentation/docs/api/crds/scan.md @@ -8,7 +8,7 @@ sidebar_position: 2 --- The Scan Custom Resource Definition (CRD) lets you define how a specific scan should be configured. -The secureCodeBox Operator will then use this specification to execute the scan. +The secureCodeBox Operator uses this specification to execute the scan. ## Specification (Spec) @@ -18,16 +18,16 @@ The `scanType` references the **name** of a [ScanType Custom Resource](/docs/api ### Parameters (Required) -`parameters` is a string array of command line flags which are passed to the scanner. +`parameters` is a string array of command line flags that are passed to the scanner. -These usually contain scanner specific configurations and target specification. +These typically contain scanner-specific configurations and target specifications. ### Env (Optional) -`env` lets you pass in custom environment variables to the scan container. -This can be useful to pass in secret values like login credentials scanner require without having to define them in plain text. +`env` lets you pass custom environment variables to the scan container. +This can be useful for passing secret values like login credentials that scanners require without defining them in plain text. -Env has the same API as "env" property on Kubernetes Pods. +The `env` field has the same API as the "env" property on Kubernetes Pods. See: @@ -36,9 +36,9 @@ See: ### Volumes (Optional) -`volumes` lets you specify Kubernetes volumes that you want to use and make available to the scan container. -Similarly to `env`, it can be used to pass data into a container. -It has to be combined with [`volumeMounts`](#volumemounts-optional) to be useful (see below). +`volumes` lets you specify Kubernetes volumes to make available to the scan container. +Similar to `env`, it can be used to pass data into a container. +It must be combined with [`volumeMounts`](#volumemounts-optional) to be useful (see below). It can also be used in combination with `initContainers` to provision files, VCS repositories, or other content into a scanner - see [`initContainers`](#initcontainers-optional) for an example. `volumes` has the same API as the `volumes` property on Kubernetes pods. @@ -50,7 +50,7 @@ See: ### VolumeMounts (Optional) -`volumeMounts` let you specify where you want the previously-created volumes to be mounted inside the container. +`volumeMounts` lets you specify where previously-created volumes should be mounted inside the container. It is used in combination with [`volumes`](#volumes-optional) (see above). `volumeMounts` has the same API as the `volumeMounts` property on Kubernetes pods. @@ -62,10 +62,10 @@ See: ### InitContainers (Optional) -`initContainers` lets you specify a (set of) container(s) that are run before the scan itself. -You can specify arbitrary containers with any command that you desire. -By default, init containers do not share a file system with the scan job. -If you want to use init containers to provision files or directories for the scan job, you need to explicitly create a volume and mount it to both the init container and the scan job itself (using the [`volumeMounts`](#volumemounts-optional) discussed above). +`initContainers` lets you specify one or more containers that run before the scan itself. +You can specify arbitrary containers with any commands you need. +By default, init containers do not share a filesystem with the scan job. +To use init containers for provisioning files or directories for the scan job, you must explicitly create a volume and mount it to both the init container and the scan job using [`volumeMounts`](#volumemounts-optional). For example, if you want to download a file that contains a list of scan targets for nmap, you could configure the scan like this: ```yaml @@ -112,9 +112,26 @@ See: - [Documentation](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/) - [API Reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#containers) -### Affinity and Tolerations (optional) +### ResourceMode (Optional) -[`affinity`](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) and [`tolerations`](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) can be used to control which nodes the parser is executed on. +The `resourceMode` specifies whether the scan should use namespace-local or cluster-wide resources (ScanType vs. ClusterScanType). Valid values are: + +- `"namespaceLocal"` (default): Uses ScanType resources from the same namespace +- `"clusterWide"`: Uses ClusterScanType resources available cluster-wide + +### NodeSelector (Optional) + +[`nodeSelector`](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/) allows you to specify a simple node selection constraint to control which nodes the scan can be scheduled on. + +```yaml +nodeSelector: + kubernetes.io/arch: amd64 + node-type: scanner +``` + +### Affinity and Tolerations (Optional) + +[`affinity`](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) and [`tolerations`](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) can be used to control which nodes the scan is executed on with more advanced rules than nodeSelector. ### Cascades (Optional) @@ -122,7 +139,7 @@ See: The cascades config in the scans spec contains [Kubernetes Label Selectors](https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/label-selector/) which allow you to select which [CascadingRule](https://www.securecodebox.io/docs/api/crds/cascading-rule) are allowed to be used by the cascading logic. -Furthermore, in the cascade config you can specify whether cascading scan should inherit parent fields: +Furthermore, in the cascade config you can specify whether cascading scans should inherit fields from the parent scan: - `inheritLabels`: `true` - `inheritAnnotations`: `true` @@ -134,8 +151,8 @@ Furthermore, in the cascade config you can specify whether cascading scan should - `inheritTolerations`: `true` These fields will merge the parent's entries with entries defined in the cascading rules. -Entries defined in cascading rules will only apply to the current scan. -There are two exceptions to this rule: in the case of Affinity and Tolerations, entries will be replaced instead of merged, and will be used for all following scans. +Entries defined in cascading rules apply only to the current scan. +There are two exceptions: for Affinity and Tolerations, entries are replaced rather than merged and apply to all subsequent scans. :::caution Defining identical entries in both the Scan AND the Cascading Rule resource will lead to undefined behaviour. @@ -147,9 +164,9 @@ For an example on how they can be used see the [Scanning Networks HowTo](https:/ #### ScopeLimiter (Optional) -`scopeLimiter` allows you to define certain rules to which cascading scans must comply before they may cascade. -For example, you can define that you can only trigger a follow-up scan against a host if its IP address is within your predefined IP range. -You can use Mustache templating in order to select certain properties from findings. +`scopeLimiter` allows you to define rules that cascading scans must comply with before they may cascade. +For example, you can define that follow-up scans against a host are only allowed if its IP address is within a predefined IP range. +You can use Mustache templating to select specific properties from findings. Under `scopeLimiter`, you may specify `anyOf`, `noneOf`, and `allOf` with a selector to limit your scope. If you specify multiple fields, all the rules must pass. @@ -171,16 +188,18 @@ These annotations can only be added on the initial scan (i.e., they cannot be mo `values` is a list of values for which the selector should pass. +The `validOnMissingRender` field in scopeLimiter defines whether a condition should match when a templating variable is not present in the finding. Defaults to `false`. + ##### Selecting lists A custom rendering function has been provided to select attributes in findings that are in a list. An example finding: ```json title="Finding" { - name: "Subdomains found", - category: "Subdomain" - attributes: { - domains: ["example.com", "subdomain.example.com"], + "name": "Subdomains found", + "category": "Subdomain", + "attributes": { + "domains": ["example.com", "subdomain.example.com"] } } ``` @@ -202,17 +221,17 @@ Some findings have data in lists of objects, such as the following: ```json title="Finding" { - name: "Subdomains found", - category: "Subdomain" - attributes: { - addresses: [ + "name": "Subdomains found", + "category": "Subdomain", + "attributes": { + "addresses": [ { - domain: "example.com", - ip: "127.0.0.1", + "domain": "example.com", + "ip": "127.0.0.1" }, { - domain: "subdomain.example.com", - ip: "127.0.0.2", + "domain": "subdomain.example.com", + "ip": "127.0.0.2" } ] } @@ -235,10 +254,10 @@ You can also manually split values from findings if your finding is like so: ```json title="Finding" { - name: "Subdomains found", - category: "Subdomain" - attributes: { - domains: "example.com,subdomain.example.com", + "name": "Subdomains found", + "category": "Subdomain", + "attributes": { + "domains": "example.com,subdomain.example.com" } } ``` @@ -306,9 +325,9 @@ See the [Scope HowTo](/docs/how-tos/scope) for more information. `hookSelector` allows you to select which hooks to run using [Kubernetes Label Selectors](https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/label-selector/). -You can only select hooks in the namespace in which the scan is running. +You can only select hooks within the namespace where the scan is running. -Leaving this field undefined will select all available hooks in this namespace. +Leaving this field undefined selects all available hooks in the namespace. ```yaml hookSelector: @@ -328,7 +347,7 @@ For more examples on how this field can be used, see the [Hook HowTo](/docs/how- ### Resources (Optional) -`resources` lets you overwrite the resource limits and requests for the primary scanner container from the values defined in the [ScanType](./scan-type). See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +`resources` lets you override the resource limits and requests for the primary scanner container from the values defined in the [ScanType](./scan-type). See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ ```yaml resources: @@ -348,7 +367,7 @@ ttlSecondsAfterFinished: 30 #deletes the scan after 30 seconds after completion ``` :::note -ttlSecondsAfterFinished can also be set for the scan (as part of the [jobTemplate](https://www.securecodebox.io/docs/api/crds/scan-type#jobtemplate-required)), [parser](https://www.securecodebox.io/docs/api/crds/parse-definition) and [hook](https://www.securecodebox.io/docs/api/crds/scan-completion-hook#ttlsecondsafterfinished-optional) jobs individually. Setting these will only deleted the jobs not the entire scan. +ttlSecondsAfterFinished can also be set for the scan (as part of the [jobTemplate](https://www.securecodebox.io/docs/api/crds/scan-type#jobtemplate-required)), [parser](https://www.securecodebox.io/docs/api/crds/parse-definition) and [hook](https://www.securecodebox.io/docs/api/crds/scan-completion-hook#ttlsecondsafterfinished-optional) jobs individually. Setting these will only delete the jobs, not the entire scan. ::: ## Metadata @@ -358,7 +377,7 @@ Metadata is a standard field on Kubernetes resources. It contains multiple relev ## Status Defines the observed state of a Scan. This will be filled by Kubernetes. -It contains (see: [Go Type ScanStatus](https://github.com/secureCodeBox/secureCodeBox/blob/main/operator/apis/execution/v1/scan_types.go#L49)) +It contains (see: [Go Type ScanStatus](https://github.com/secureCodeBox/secureCodeBox/blob/main/operator/apis/execution/v1/scan_types.go#L169)) - `State`: State of the scan (See: [secureCodeBox | ScanControler](https://github.com/secureCodeBox/secureCodeBox/blob/main/operator/controllers/execution/scans/scan_controller.go#L105)) - `FinishedAt`: Time when scan, parsers and hooks for this scan are marked as 'Done' @@ -367,7 +386,7 @@ It contains (see: [Go Type ScanStatus](https://github.com/secureCodeBox/secureCo - `RawResultFile`: Filename of the result file of the scanner. e.g. `nmap-result.xml` - `FindingDownloadLink`: Link to download the finding json file from. Valid for 7 days - `RawResultDownloadLink`: RawResultDownloadLink link to download the raw result file from. Valid for 7 days -- `Findings`: FindingStats (See [Go Type FindingStats](https://github.com/secureCodeBox/secureCodeBox/blob/main/operator/apis/execution/v1/scan_types.go#L89)) +- `Findings`: FindingStats (See [Go Type FindingStats](https://github.com/secureCodeBox/secureCodeBox/blob/main/operator/apis/execution/v1/scan_types.go#L218)) - `ReadAndWriteHookStatus`: Status of the Read and Write Hooks ## Example @@ -375,7 +394,6 @@ It contains (see: [Go Type ScanStatus](https://github.com/secureCodeBox/secureCo ```yaml apiVersion: "execution.securecodebox.io/v1" kind: Scan -status: # Set during runtime. Do not edit via values.yaml etc. metadata: name: "nmap-scanme.nmap.org" annotations: @@ -383,6 +401,7 @@ metadata: scope.cascading.securecodebox.io/domain: "example.com" spec: scanType: "nmap" + resourceMode: "namespaceLocal" parameters: # Use nmap's service detection feature - "-sV" @@ -395,15 +414,17 @@ spec: name: zap-customer-credentials - name: GREETING value: "Hello from the secureCodeBox :D" + nodeSelector: + kubernetes.io/arch: amd64 cascades: inheritLabels: false inheritAnnotations: true matchLabels: securecodebox.io/intensive: light - matchExpression: - key: "securecodebox.io/invasive" - operator: In - values: [non-invasive, invasive] + matchExpressions: + - key: "securecodebox.io/invasive" + operator: In + values: [non-invasive, invasive] scopeLimiter: validOnMissingRender: true allOf: @@ -421,4 +442,5 @@ spec: limits: cpu: 4 memory: 4Gi + ttlSecondsAfterFinished: 300 ``` diff --git a/documentation/docs/api/crds/scheduled-scan.md b/documentation/docs/api/crds/scheduled-scan.md index fe94853a50..20bf95c960 100644 --- a/documentation/docs/api/crds/scheduled-scan.md +++ b/documentation/docs/api/crds/scheduled-scan.md @@ -7,26 +7,28 @@ title: "ScheduledScan" sidebar_position: 3 --- -The ScheduledScan Custom Resource Definition (CRD) lets you define a [Scan](/docs/api/crds/scan-type/) which gets repeated in a specific time interval. E.g. every 24 hours or every 7 days. +The ScheduledScan Custom Resource Definition (CRD) lets you define a [Scan](/docs/api/crds/scan-type/) that gets repeated at specific time intervals, such as every 24 hours or every 7 days. ## Specification (Spec) ### Interval -The `interval` specifies the interval between two scans. -Either [`interval`](#interval) or [`schedule`](#schedule) need to be set, they are mutually exclusive. +The `interval` specifies the time interval between consecutive scans. +Either [`interval`](#interval) or [`schedule`](#schedule) must be set, as they are mutually exclusive. Specified as a [golang duration string](https://golang.org/pkg/time/#ParseDuration). +E.g. `24h` for 24 hours, or `1h30m` for 1 hour and 30 minutes. + :::caution -The biggest duration golang time strings support is **hours**. Longer durations e.g. days / weeks need to specified as multiples of hours. -We plan to improve this in the future, by providing a custom format which also supports days and weeks. +The largest duration unit that golang time strings support is **hours**. Longer durations (e.g., days or weeks) must be specified as multiples of hours. +We plan to improve this in the future by providing a custom format that also supports days and weeks. ::: ### Schedule -Schedule let's you define a [cron expression](https://en.wikipedia.org/wiki/Cron) to control precisely when the scan is executed. -Either [`interval`](#interval) or [`schedule`](#schedule) need to be set, they are mutually exclusive. +The `schedule` lets you define a [cron expression](https://en.wikipedia.org/wiki/Cron) to control precisely when the scan is executed. +Either [`interval`](#interval) or [`schedule`](#schedule) must be set, as they are mutually exclusive. ### ScanSpec (Required) @@ -36,15 +38,29 @@ See the `spec` field of the [Scan CRD](/docs/api/crds/scan-type/) for all suppor ### SuccessfulJobsHistoryLimit (Optional) -The `successfulJobsHistoryLimit` controls how many completed scans are supposed to be kept until the oldest one will be deleted. +The `successfulJobsHistoryLimit` controls how many completed scans are retained before the oldest ones are deleted. -Defaults to 3 if not set. When set to `0`, scans will be deleted directly after their completion. +Defaults to 3 if not set. When set to `0`, scans are deleted immediately after completion. ### FailedJobsHistoryLimit (Optional) -The `failedJobsHistoryLimit` controls how many failed scans are supposed to be kept until the oldest one will be deleted. +The `failedJobsHistoryLimit` controls how many failed scans are retained before the oldest ones are deleted. + +Defaults to 3 if not set. When set to `0`, scans are deleted immediately after failure. + +### ConcurrencyPolicy (Optional) + +The `concurrencyPolicy` specifies how to treat concurrent executions of a ScheduledScan. Valid values are: + +- `"Allow"` (default): allows scheduled scans to run concurrently +- `"Forbid"`: forbids concurrent runs, skipping the next run if the previous run hasn't finished yet +- `"Replace"`: cancels the currently running scan and replaces it with a new one + +### RetriggerOnScanTypeChange (Optional) + +When `retriggerOnScanTypeChange` is enabled, it will automatically trigger a new scan if the referenced ScanType is updated. -Defaults to 1 if not set. When set to `0`, scans will be deleted directly after failure. +Defaults to `false` if not set. ## Example with an Interval @@ -58,11 +74,13 @@ spec: scanSpec: scanType: "nmap" parameters: - # Use nmaps service detection feature + # Use nmap's service detection feature - "-sV" - scanme.nmap.org successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 5 + concurrencyPolicy: "Allow" + retriggerOnScanTypeChange: false ``` ## Example with a Cron Schedule @@ -77,9 +95,11 @@ spec: scanSpec: scanType: "nmap" parameters: - # Use nmaps service detection feature + # Use nmap's service detection feature - "-sV" - scanme.nmap.org successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 5 + concurrencyPolicy: "Forbid" + retriggerOnScanTypeChange: true ``` diff --git a/documentation/docs/architecture/09_architecture_decisions/adr_0002.md b/documentation/docs/architecture/09_architecture_decisions/adr_0002.md index 13c2344601..5758865afb 100644 --- a/documentation/docs/architecture/09_architecture_decisions/adr_0002.md +++ b/documentation/docs/architecture/09_architecture_decisions/adr_0002.md @@ -12,7 +12,7 @@ sidebar_label: "ADR-0002" |----------------|----------| | **Status**: | ACCEPTED | | **Date**: | 2020-05-20 | -| **Author(s)**: | Jannik Hollenbach [jannick.hollenbach@iteratec.com](mailto:jannick.hollenbach@iteratec.com), Jorge Estigarribia [jorge.estigarribia@iteratec.com](mailto:jorge.estigarribia@iteratec.com), Robert Seedorff [Robert.Seedorff@iteratec.com](mailto:Robert.Seedorff@iteratec.com), Sven Strittmatter [sven.strittmatter@iteratec.com](mailto:Sven.Strittmatter@iteratec.com) | +| **Author(s)**: | Jannik Hollenbach [jannik.hollenbach@iteratec.com](mailto:jannik.hollenbach@iteratec.com), Jorge Estigarribia [jorge.estigarribia@iteratec.com](mailto:jorge.estigarribia@iteratec.com), Robert Seedorff [Robert.Seedorff@iteratec.com](mailto:Robert.Seedorff@iteratec.com), Sven Strittmatter [sven.strittmatter@iteratec.com](mailto:Sven.Strittmatter@iteratec.com) | ## Context diff --git a/documentation/docs/architecture/09_architecture_decisions/adr_0003.md b/documentation/docs/architecture/09_architecture_decisions/adr_0003.md index a9f6673120..ecc18045e0 100644 --- a/documentation/docs/architecture/09_architecture_decisions/adr_0003.md +++ b/documentation/docs/architecture/09_architecture_decisions/adr_0003.md @@ -12,7 +12,7 @@ sidebar_label: "ADR-0003" |----------------|----------| | **Status**: | ACCEPTED | | **Date**: | 2020-05-20 | -| **Author(s)**: | Jannik Hollenbach [jannick.hollenbach@iteratec.com](mailto:jannick.hollenbach@iteratec.com), Robert Seedorff [Robert.Seedorff@iteratec.com](mailto:Robert.Seedorff@iteratec.com), Sven Strittmatter [sven.strittmatter@iteratec.com](mailto:Sven.Strittmatter@iteratec.com) | +| **Author(s)**: | Jannik Hollenbach [jannik.hollenbach@iteratec.com](mailto:jannik.hollenbach@iteratec.com), Robert Seedorff [Robert.Seedorff@iteratec.com](mailto:Robert.Seedorff@iteratec.com), Sven Strittmatter [sven.strittmatter@iteratec.com](mailto:Sven.Strittmatter@iteratec.com) | ## Context diff --git a/documentation/docs/architecture/09_architecture_decisions/adr_0009.md b/documentation/docs/architecture/09_architecture_decisions/adr_0009.md index 402006e216..4e82be5c7e 100644 --- a/documentation/docs/architecture/09_architecture_decisions/adr_0009.md +++ b/documentation/docs/architecture/09_architecture_decisions/adr_0009.md @@ -12,7 +12,7 @@ sidebar_label: "ADR-0009" |----------------|----------| | **Status**: | ACCEPTED | | **Date**: | 2021-10-07 | -| **Author(s)**: | Max Maass [max.maass@iteratec.com](mailto:max.maass@iteratec.com), Jannik Hollenbach [jannick.hollenbach@iteratec.com](mailto:jannick.hollenbach@iteratec.com) | +| **Author(s)**: | Max Maass [max.maass@iteratec.com](mailto:max.maass@iteratec.com), Jannik Hollenbach [jannik.hollenbach@iteratec.com](mailto:jannik.hollenbach@iteratec.com) | ## Context @@ -155,7 +155,7 @@ spec: mountPath: "/etc/rules" initContainers: - name: git-clone - image: bitnami/git + image: alpine/git command: - git - clone diff --git a/documentation/docs/architecture/09_architecture_decisions/adr_0012.md b/documentation/docs/architecture/09_architecture_decisions/adr_0012.md index 91a2d80e57..ef5cecf3ca 100644 --- a/documentation/docs/architecture/09_architecture_decisions/adr_0012.md +++ b/documentation/docs/architecture/09_architecture_decisions/adr_0012.md @@ -13,7 +13,7 @@ sidebar_label: "ADR-0012" | -------------- | -------------------------------------------------------------------------------------- | | **Status**: | OPEN | | **Date**: | 2022-06-17 | -| **Author(s)**: | Jannik Hollenbach [jannick.hollenbach@iteratec.com](mailto:jannick.hollenbach@iteratec.com), Max Maass [max.maass@iteratec.com](mailto:max.maass@iteratec.com) | +| **Author(s)**: | Jannik Hollenbach [jannik.hollenbach@iteratec.com](mailto:jannik.hollenbach@iteratec.com), Max Maass [max.maass@iteratec.com](mailto:max.maass@iteratec.com) | ## Context diff --git a/documentation/docs/architecture/09_architecture_decisions/adr_0015.md b/documentation/docs/architecture/09_architecture_decisions/adr_0015.md index 192b9dca3e..fa8144ed82 100644 --- a/documentation/docs/architecture/09_architecture_decisions/adr_0015.md +++ b/documentation/docs/architecture/09_architecture_decisions/adr_0015.md @@ -13,7 +13,7 @@ sidebar_label: "ADR-0015" | -------------- | ------------------------------------------------------------------------------------------------------ | | **Status**: | ACCEPTED | | **Date**: | 2022-09-13 | -| **Author(s)**: | Jannik Hollenbach [jannick.hollenbach@iteratec.com](mailto:jannick.hollenbach@iteratec.com), Sven Strittmatter [sven.strittmatter@iteratec.com](mailto:Sven.Strittmatter@iteratec.com) | +| **Author(s)**: | Jannik Hollenbach [jannik.hollenbach@iteratec.com](mailto:jannik.hollenbach@iteratec.com), Sven Strittmatter [sven.strittmatter@iteratec.com](mailto:Sven.Strittmatter@iteratec.com) | :::info This ADR should have been written prior to implementation. But we started documenting ADR later. This ADR has therefore been written retrospectively to record the decision made at that time. diff --git a/documentation/docs/architecture/09_architecture_decisions/adr_0016.md b/documentation/docs/architecture/09_architecture_decisions/adr_0016.md index ca1a36741c..80f704c6c4 100644 --- a/documentation/docs/architecture/09_architecture_decisions/adr_0016.md +++ b/documentation/docs/architecture/09_architecture_decisions/adr_0016.md @@ -13,7 +13,7 @@ sidebar_label: "ADR-0016" | -------------- | ------------------------------------------------------------------------------------------------------ | | **Status**: | ACCEPTED | | **Date**: | 2022-09-13 | -| **Author(s)**: | Jannik Hollenbach [jannick.hollenbach@iteratec.com](mailto:jannick.hollenbach@iteratec.com), Sven Strittmatter [sven.strittmatter@iteratec.com](mailto:Sven.Strittmatter@iteratec.com) | +| **Author(s)**: | Jannik Hollenbach [jannik.hollenbach@iteratec.com](mailto:jannik.hollenbach@iteratec.com), Sven Strittmatter [sven.strittmatter@iteratec.com](mailto:Sven.Strittmatter@iteratec.com) | :::info This ADR should have been written prior to implementation. But we started documenting ADR later. This ADR has therefore been written retrospectively to record the decision made at that time. diff --git a/documentation/docs/architecture/09_architecture_decisions/adr_0020.md b/documentation/docs/architecture/09_architecture_decisions/adr_0020.md new file mode 100644 index 0000000000..dab19dab88 --- /dev/null +++ b/documentation/docs/architecture/09_architecture_decisions/adr_0020.md @@ -0,0 +1,211 @@ +--- +# SPDX-FileCopyrightText: the secureCodeBox authors +# +# SPDX-License-Identifier: Apache-2.0 + +title: "ADR-0020: Adopting Common Expression Language (CEL) for CascadingRule Matching" +sidebar_label: "ADR-0020" +--- +# ADR-0020: Adopting Common Expression Language (CEL) for CascadingRule Matching + +| | | +|----------------|----------------------------------------------------------------------------------------------| +| **Status**: | PROPOSED | +| **Date**: | 2025-10-14 | +| **Author(s)**: | Jannik Hollenbach [jannik.hollenbach@iteratec.com](mailto:jannik.hollenbach@iteratec.com) | + +## Context + +CascadingRules in secureCodeBox currently use a custom `matches` object syntax to define which findings should trigger subsequent scans. The current implementation uses a declarative YAML structure with `anyOf` rules that perform partial deep comparison against finding fields: + +```yaml +spec: + matches: + anyOf: + - category: "Open Port" + attributes: + port: 22 + state: open + - category: "Open Port" + attributes: + service: "ssh" + state: open +``` + +While this approach works well for simple matching scenarios, it has several limitations: + +1. **Limited Expressiveness**: The current syntax only supports exact matching and partial deep comparison. Complex conditions like range checks, regex patterns, logical combinations beyond `anyOf`, or computed values are not possible without extending the custom syntax. +2. **Maintenance Burden**: Every new matching requirement necessitates extending the custom matcher implementation. This creates ongoing maintenance overhead and increases the complexity of the codebase. +3. **Lack of Flexibility**: Common use cases like checking if a port is within a range (e.g., `port >= 8000 && port <= 9000`), matching against multiple patterns, or combining conditions with complex boolean logic require workarounds or are simply not possible. + +[Common Expression Language (CEL)](https://github.com/google/cel-spec) is a non-Turing complete expression language designed for evaluating expressions in a safe, fast, and portable manner. It is already widely adopted in the Kubernetes ecosystem, particularly in: + +- Kubernetes ValidatingAdmissionPolicy (since v1.26) +- Kubernetes Custom Resource Definitions (CRD validation rules) +- Istio authorization policies +- Various other cloud-native projects + +CEL provides a familiar C-like syntax and is specifically designed for configuration and policy evaluation use cases, making it an ideal fit for CascadingRule matching logic. + +## Decision + +We propose migrating the CascadingRule `matches` specification from the current custom object syntax to use Common Expression Language (CEL) expressions. + +### Proposed Syntax + +Instead of the current `matches.anyOf` structure, users would write CEL expressions that evaluate to a boolean: + +```yaml +spec: + matches: + expression: | + (finding.category == "Open Port" && finding.attributes.port == 22 && finding.attributes.state == "open") || + (finding.category == "Open Port" && finding.attributes.service == "ssh" && finding.attributes.state == "open") +``` + +Or more concisely: + +```yaml +spec: + matches: + expression: | + finding.category == "Open Port" && + finding.attributes.state == "open" && + (finding.attributes.port == 22 || finding.attributes.service == "ssh") +``` + +### Advanced Use Cases Enabled by CEL + +CEL would enable powerful matching scenarios that are currently impossible: + +**Range Checks:** +```yaml +expression: | + finding.category == "Open Port" && + finding.attributes.port >= 8000 && + finding.attributes.port <= 9000 +``` + +**Regex Matching:** +```yaml +expression: | + finding.category == "Subdomain" && + finding.attributes.hostname.matches("^.*\\.example\\.com$") +``` + +**Complex Boolean Logic:** +```yaml +expression: | + (finding.severity in ["HIGH", "CRITICAL"] && finding.category == "Vulnerability") || + (finding.category == "Open Port" && finding.attributes.port in [22, 23, 3389]) +``` + +**Computed Values:** +```yaml +expression: | + finding.category == "Open Port" && + has(finding.attributes.service) && + finding.attributes.service.startsWith("http") +``` + +### Migration Strategy + +To ensure backward compatibility and smooth migration: + +1. **Dual Support Period**: Support both the legacy `matches.anyOf` syntax and the new `matches.expression` syntax simultaneously for at least two major versions. + +2. **Automatic Translation (Preferred Approach)**: Implement automatic runtime translation of `matches.anyOf` to CEL expressions: + - When a CascadingRule contains only `matches.anyOf`, automatically translate it to an equivalent CEL expression at runtime + - Log an informational message indicating the automatic translation occurred + - This approach eliminates the need for complex conflict resolution logic + - Users can gradually migrate at their own pace without breaking changes + - The translation logic can be removed in a future major version when `anyOf` support is dropped + + **If automatic translation is implemented, the conflict resolution below becomes unnecessary.** + +3. **Conflict Resolution (Alternative if no automatic translation)**: When both `matches.anyOf` and `matches.expression` are specified in the same CascadingRule: + - Generally automatic translation would be prefered as it eliminates manual work and potential errors, but if that turns out to be hard to achieve, manual translation might be the only option. + - **CEL takes precedence**: The `matches.expression` will be evaluated and `matches.anyOf` will be ignored + - **Emit a warning**: Log a warning message and add a Kubernetes event to the CascadingRule resource indicating the conflict + - **Add status condition**: Update the CascadingRule status with a condition indicating that both matchers were specified and CEL was used + + Example warning message: + ``` + Warning: CascadingRule 'nmap-hostscan' specifies both 'matches.anyOf' and 'matches.expression'. + Using CEL expression and ignoring anyOf matcher. Please remove the deprecated 'matches.anyOf' field. + ``` + +4. **Translation Documentation**: Provide documentation to help users manually translate existing `anyOf` rules to CEL expressions to better help users understanding of the new syntax. + +5. (consider) **Validation**: Implement comprehensive validation of CEL expressions at CRD admission time to catch syntax errors early. We have avoided validating webhooks so far, as they have a overhead in terms of cert management, but might be worthwhile for this issue. + +6. **Documentation**: Create extensive documentation with examples showing common patterns and migration guides. + +7. **Proposed Deprecation Path**: + - Version 5.x: Introduce CEL support with automatic translation of `anyOf` (if implemented) or dual support, mark `anyOf` as deprecated with informational/warning messages + - Version 6.0.0: Remove support for `anyOf` syntax and automatic translation logic + +## Consequences + +### Positive Consequences + +1. **Increased Flexibility**: Users can express arbitrarily complex matching logic without waiting for custom syntax extensions. +2. **Reduced Maintenance**: The secureCodeBox team no longer needs to maintain and extend custom matching logic. CEL is maintained by Google and the broader community. +3. **Industry Standard**: CEL is becoming the de facto standard for policy expressions in Kubernetes, making it familiar to many users. +4. **Better Tooling**: CEL has existing tooling, documentation, and community support that users can leverage. +5. **Type Safety**: CEL provides compile-time type checking, catching errors before runtime. +6. **Security**: CEL is non-Turing complete and designed to be safe for user-provided expressions, preventing infinite loops or resource exhaustion. + +### Negative Consequences + +1. **Breaking Change**: Eventually removing the `anyOf` syntax will require users to migrate their existing CascadingRules. +2. **Learning Curve**: Users unfamiliar with CEL will need to learn a new expression syntax, though it's relatively simple and well-documented. +3. **Migration Effort**: Existing CascadingRules will need to be updated, requiring effort from users and clear migration documentation. +4. **Increased Complexity**: The cascading hook codebase will temporarily be more complex during the dual-support period. +5. **Dependency Addition**: Adding the cel library increases the dependency footprint of the operator. +6. **Error Messages**: CEL error messages may be less intuitive than custom validation errors, requiring careful wrapping and contextualization. +7. **Potential Confusion**: During the dual-support period, users might accidentally specify both matchers, though the clear precedence rule and warnings mitigate this risk. + +### Mitigation Strategies + +- **If automatic translation is implemented**: The migration becomes seamless with minimal user impact +- Provide comprehensive migration guides with side-by-side examples +- Create a validation tool or script to help users test their CEL expressions +- Maintain the dual-support period for sufficient time to allow gradual migration +- Offer community support and examples for common migration scenarios +- If no automatic translation: Implement clear conflict detection with actionable warning messages +- Add linting/validation in CI/CD pipelines to detect deprecated usage early + +## Alternatives Considered + +### 1. Extend the Current Custom Syntax + +We could continue extending the `matches` object with new fields and operators (e.g., `allOf`, `noneOf`, etc.). + +**Rejected because**: This would perpetuate the maintenance burden and still wouldn't provide the full flexibility of a proper expression language. Each new requirement would require code changes and releases. + +### 2. Use JSONPath or JMESPath + +These are query languages designed for JSON data extraction and filtering. + +**Rejected because**: While powerful for data extraction, they are less intuitive for boolean logic and condition evaluation. CEL is specifically designed for policy evaluation use cases. + +### 3. Use JavaScript or Lua + +Embed a scripting language for maximum flexibility. + +**Rejected because**: Full scripting languages are Turing complete and pose security risks when evaluating user-provided code. They also have higher performance overhead and complexity. CEL's non-Turing complete nature makes it safer and more appropriate for this use case. + +### 4. Use Rego (Open Policy Agent) + +Rego is the policy language used by Open Policy Agent. + +**Rejected because**: While Rego is powerful, it has a steeper learning curve and is less widely adopted in the Kubernetes ecosystem compared to CEL. CEL's integration with Kubernetes CRDs and admission policies makes it a more natural fit. + +## References + +- [CEL Specification](https://github.com/google/cel-spec) +- [cel-go Implementation](https://github.com/google/cel-go) +- [cel-js Implementation](https://github.com/marcbachmann/cel-js) +- [Kubernetes CEL Validation](https://kubernetes.io/docs/reference/using-api/cel/) +- [Current CascadingRule Documentation](https://www.securecodebox.io/docs/api/crds/cascading-rule) \ No newline at end of file diff --git a/documentation/docs/contributing/integrating-a-hook/dockerfile.md b/documentation/docs/contributing/integrating-a-hook/dockerfile.md index 56bbb9db2d..2d2f1cf08d 100644 --- a/documentation/docs/contributing/integrating-a-hook/dockerfile.md +++ b/documentation/docs/contributing/integrating-a-hook/dockerfile.md @@ -12,11 +12,11 @@ If you use the provided _hook-sdk_, you won't need to apply any changes to it. ```Dockerfile ARG baseImageTag -FROM node:22-alpine as build +FROM node:24-alpine as build RUN mkdir -p /home/app WORKDIR /home/app COPY package.json package-lock.json ./ -RUN npm ci --omit=dev +RUN npm ci --omit=dev --ignore-scripts --ignore-scripts FROM securecodebox/hook-sdk-nodejs:${baseImageTag:-latest} WORKDIR /home/app/hook-wrapper/hook/ diff --git a/documentation/docs/contributing/integrating-a-scanner/parser-dir.md b/documentation/docs/contributing/integrating-a-scanner/parser-dir.md index 5c0ac46331..5840f449b3 100644 --- a/documentation/docs/contributing/integrating-a-scanner/parser-dir.md +++ b/documentation/docs/contributing/integrating-a-scanner/parser-dir.md @@ -20,7 +20,7 @@ FROM node:22-alpine as build RUN mkdir -p /home/app WORKDIR /home/app COPY package.json package-lock.json ./ -RUN npm ci --omit=dev +RUN npm ci --omit=dev --ignore-scripts FROM securecodebox/parser-sdk-nodejs:${baseImageTag:-latest} WORKDIR /home/app/parser-wrapper/parser/ @@ -28,7 +28,7 @@ COPY --from=build --chown=root:root --chmod=755 /home/app/node_modules/ ./node_m COPY --chown=root:root --chmod=755 ./parser.js ./parser.js ``` -If your parser does not require any external dependencies, A multi-stage build is not needed. +If your parser does not require any external dependencies, A multi-stage build is not needed. Instead, a simpler Dockerfile can be used. ```dockerfile @@ -94,7 +94,7 @@ Please provide some tests for your parser in the `parser.test.js` file. To make import { validateParser } from "@securecodebox/parser-sdk-nodejs/parser-utils"; const findings = await parse(fileContent); -await expect(validateParser(findings)).resolves.toBeUndefined(); +expect(validateParser(findings)).toBeUndefined(); ``` If you need additional files for your test please save these in the `__testFiles__` directory. Please take a look at [Integration Tests | secureCodeBox](/docs/contributing/integrating-a-scanner/integration-tests) for more information. diff --git a/documentation/docs/contributing/local-deployment.md b/documentation/docs/contributing/local-deployment.md index fd4151197b..6bbde9ddd4 100644 --- a/documentation/docs/contributing/local-deployment.md +++ b/documentation/docs/contributing/local-deployment.md @@ -82,11 +82,11 @@ task: [build-operator-image] docker build -t ${IMG_NS}/operator:${IMG_TAG} /src/ => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 966B 0.0s => [internal] load metadata for gcr.io/distroless/static:nonroot 0.4s - => [internal] load metadata for docker.io/library/golang:1.24.2 1.0s + => [internal] load metadata for docker.io/library/golang:1.24.5 1.0s => [auth] library/golang:pull token for registry-1.docker.io 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 291B 0.0s - => [builder 1/11] FROM docker.io/library/golang:1.24.2@sha256:30baaea08c5d1e858329c50f29fe381e9b7d7bced11a0f5f1f69a1504cdfbf5 0.0s + => [builder 1/11] FROM docker.io/library/golang:1.24.5@sha256:30baaea08c5d1e858329c50f29fe381e9b7d7bced11a0f5f1f69a1504cdfbf5 0.0s => [stage-1 1/3] FROM gcr.io/distroless/static:nonroot@sha256:627d6c5a23ad24e6bdff827f16c7b60e0289029b0c79e9f7ccd54ae3279fb45f 0.0s => [internal] load build context 0.0s => => transferring context: 2.91kB 0.0s @@ -105,11 +105,11 @@ task: [build-operator-image] docker build -t ${IMG_NS}/operator:${IMG_TAG} /src/ [+] Building 1.1s (15/15) FINISHED docker:desktop-linux => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 820B 0.0s - => [internal] load metadata for docker.io/library/golang:1.24.2 1.0s + => [internal] load metadata for docker.io/library/golang:1.24.5 1.0s => [internal] load metadata for gcr.io/distroless/static:nonroot 0.4s => [internal] load .dockerignore 0.0s => => transferring context: 171B 0.0s - => [builder 1/11] FROM docker.io/library/golang:1.24.2@sha256:30baaea08c5d1e858329c50f29fe381e9b7d7bced11a0f5f1f69a1504cdfbf5 0.0s + => [builder 1/11] FROM docker.io/library/golang:1.24.5@sha256:30baaea08c5d1e858329c50f29fe381e9b7d7bced11a0f5f1f69a1504cdfbf5 0.0s => [stage-1 1/3] FROM gcr.io/distroless/static:nonroot@sha256:627d6c5a23ad24e6bdff827f16c7b60e0289029b0c79e9f7ccd54ae3279fb45f 0.0s => [internal] load build context 0.0s => => transferring context: 81B 0.0s diff --git a/documentation/docs/contributing/project-management.md b/documentation/docs/contributing/project-management.md index d33a6c62d5..73ec7464e6 100644 --- a/documentation/docs/contributing/project-management.md +++ b/documentation/docs/contributing/project-management.md @@ -12,22 +12,38 @@ Under the topic "project management" we describe how we do the organizational st - We use GitHub for source code and issue management: - We have an own organization named [secureCodeBox](https://github.com/secureCodeBox/). - - Management of issues is done with a belonging [project](https://github.com/orgs/secureCodeBox/projects/6). + - Management of issues is done with a corresponding [project](https://github.com/orgs/secureCodeBox/projects/6). - We use the OWASP Google Workspace: - A [shared drive][google-shared-drive] to store meeting notes. - And a project calendar: - - [internal link](https://calendar.google.com/calendar/u/0?cid=Y19mODdhNThiMGNmZjNmMWMwMTk5ZjlhNDc1MjVjMmNiMGU3NjkwZmRjMTliZTI2NDlmMGU5YjlmMDA1ZTc3Mjc4QGdyb3VwLmNhbGVuZGFyLmdvb2dsZS5jb20) - - [public link](https://calendar.google.com/calendar/u/0/embed?src=c_f87a58b0cff3f1c0199f9a47525c2cb0e7690fdc19be2649f0e9b9f005e77278@group.calendar.google.com&ctz=Europe/Berlin) + - [Internal link](https://calendar.google.com/calendar/u/0?cid=Y19mODdhNThiMGNmZjNmMWMwMTk5ZjlhNDc1MjVjMmNiMGU3NjkwZmRjMTliZTI2NDlmMGU5YjlmMDA1ZTc3Mjc4QGdyb3VwLmNhbGVuZGFyLmdvb2dsZS5jb20) + - [Public link](https://calendar.google.com/calendar/u/0/embed?src=c_f87a58b0cff3f1c0199f9a47525c2cb0e7690fdc19be2649f0e9b9f005e77278@group.calendar.google.com&ctz=Europe/Berlin) ## Teams -In our GitHub organization we have several teams: +### GitHub -1. _admin-team_: members are the _project leads_. +In our [GitHub organization](https://github.com/secureCodeBox) we have several teams: + +1. _admin-team_: Members are the _project leads_. 2. _core-team_: Company sponsored core team. 3. _contributor-team_: Active contributors from the community. 4. _bot-team_: Team containing all bots allowed to push directly to the main branch. +### DockerHub + +In our [DockerHub organization](https://hub.docker.com/u/securecodebox) we have several teams: + +1. _adminteam_: Members are the _project leads_. +2. _coreteam_: Company sponsored core team. +3. _botteam_: Team containing all bot accounts. + +### Sonatype (Maven Central) + +In our [Sonatype organization](https://central.sonatype.com/) we have the namespace "io.securecodebox" for Java Maven artifacts. + +Users of this namespace are the _project leads_ and a bot user for deployments. + ## Organizational - The _project leads_ do a regular sync meeting: @@ -37,6 +53,29 @@ In our GitHub organization we have several teams: ## On- and Off-Boarding -**TODO** Describe on-/off-boarding +For on- and off-boarding we create an issue for each member. On- and off-boardings need to be done by a member of the _admin-team_. + +### On-boarding + +- _core-team_: + - Add to our GitHub organization with following roles: + - core-team + - contributer-Team +- _admin-team_ (additionally to the _core-team_ on-boarding): + - Add to our GitHub organization with following roles: + - admin-team + - Register user at [Sonatype](https://central.sonatype.com/) & add to namespace "io.securecodebox" + - Add to [OWASP valut](https://team-securecodebox.1password.com/). + +### Off-boarding + +- _core-team_: + - Remove role: + - core-team +- _admin-team_: + - Remove role: + - admin-team + - Remove user from namespace "io.securecodebox" in [SonaType](https://central.sonatype.com/). + - Remove access to [OWASP vault](https://team-securecodebox.1password.com/). [google-shared-drive]: https://drive.google.com/drive/folders/1cwAjEyEabdj4By-Ox6ho49NiT-vQUeDq?usp=drive_link diff --git a/documentation/docs/contributing/test-concept/scanner-test.md b/documentation/docs/contributing/test-concept/scanner-test.md index 831772513a..5af9945986 100644 --- a/documentation/docs/contributing/test-concept/scanner-test.md +++ b/documentation/docs/contributing/test-concept/scanner-test.md @@ -12,7 +12,7 @@ We employ two types of tests: Unit tests for the parser and integration-tests. B ### Unit Tests for Parser -Each scanner has a parser and each parser has a unit test file. The unit test file is named parser.test.js. This file contains different test scenarios. In each test, the results from parser.js and the folder `_snapshots_` are compared. If they are the same, the unit test is successful. +Each scanner has a parser and each parser has a unit test file. The unit test file is named parser.test.js. This file contains different test scenarios. In each test, the results from parser.js and the folder `_snapshots_` are compared. If they are the same, the unit test is successful. A unit test can look like this: ```js @@ -24,7 +24,7 @@ test("parser parses large json result without vulnerable extensions successfully } ); const findings = await parse(JSON.parse(fileContent)); - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchSnapshot(); }); @@ -42,24 +42,27 @@ in the scanner directory. Each scanner has a folder with integration tests. For the integration tests we check the results of the `scan` function. This function runs an actual SCB scan in the Kind Cluster (Through the [Scan CRD](/docs/api/crds/scan)). It expects the following parameters: Name of the scan, scanType, scanner-specific parameters for the scan and the allowed timeout. -An integration test for, for example, the amass scanner looks like this: +An integration test for, for example, the nmap scanner looks like this: ```js test( - "amass should find at least 20 subdomains", + "nmap should identify open ports of bodgeit", async () => { - const { count } = await scan( - "amass-scanner-dummy-scan", - "amass", - ["-passive", "-noalts", "-norecursive", "-d", "owasp.org"], + const { count, categories } = await scan( + "nmap-scanner-dummy-scan", + "nmap", + ["bodgeit.demo-targets.svc"], 180 ); - expect(count).toBeGreaterThanOrEqual(20); + expect(count).toBe(2); + expect(categories["Host"]).toBe(1); + expect(categories["Open Port"]).toBe(1); }, - { timeout: 6 * 60 * 1000 }, + { timeout: 3 * 60 * 1000 }, ); ``` -For this test to be considered successful, it has to match the expected condition. In this case, the condition is that the count of the findings is greater or equal to 20. +For this test to be considered successful, it has to match the expected condition. + ### How to Run an Integration Test To run the test it suffices to run: diff --git a/documentation/docs/getting-started/installation.md b/documentation/docs/getting-started/installation.md index 09745da488..7733bbfd94 100644 --- a/documentation/docs/getting-started/installation.md +++ b/documentation/docs/getting-started/installation.md @@ -24,10 +24,18 @@ You're now ready to install your [first scan types and start your first scans](/ ## Supported Kubernetes Version -The secureCodeBox supports the 4 latest Kubernetes releases (`v1.33`, `v1.32`, `v1.31` & `v1.30`). Older versions might also work but are not officially supported or tested. +The secureCodeBox supports the 4 latest Kubernetes releases (`v1.35`, `v1.34`, `v1.33` & `v1.32`). Older versions might also work but are not officially supported or tested. ## Accessing the included MinIO Instance +:::warning Development/Quickstart Only +The included MinIO instance is intended **only for development, testing, and quickstart purposes**. For production environments, you should use either: +- A managed S3-compatible storage service from your cloud provider (AWS S3, Google Cloud Storage, etc.) +- An externally managed MinIO instance (e.g., via the MinIO Operator) + +This provides better reliability, scalability, and security compared to the embedded MinIO instance. +::: + The default secureCodeBox Operator includes a [MinIO](https://min.io/) instance, which acts as a local S3 filestorage API used by the secureCodeBox to store the results files of its scans. You can switch it out with a S3 compatible API provided by most cloud providers. You can access the MinIO instance included in the default installation like the following: @@ -47,7 +55,9 @@ If you find yourself running these snippets regularly, you might want to check o ## Operator Configuration Options -### Using a hosted S3 Buckets as storage backend +### Using a hosted S3 Buckets as storage backend (Recommended for Production) + +For production environments, it is **strongly recommended** to replace the default MinIO instance with a managed S3-compatible storage service from your cloud provider. This provides better reliability, scalability, security, and backup capabilities. To change out the default MinIO instance with a S3 Bucket from a cloud provider you can update the helm values to connect the operator with you S3 bucket. @@ -69,11 +79,202 @@ s3: ``` :::info -Instead of using access keys it is possible to use **IAM roles** for more fine grained access management. To achieve that set in your helm values - -1. `s3.authType` to `aws-irsa`, and -2. `s3.awsStsEndpoint` to your desired region (`https://sts.REGION.amazonaws.com`). - ::: +Instead of using access keys, it is possible to use [EKS Pod Identities](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html) or [IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) in secureCodeBox to authenticate to the S3 bucket using short-lived, automatically rotated credentials. + +However, because these credentials are short-lived (maximum lifetime of 12 hours), scans started by the operator in this setup are limited in their maximum duration. The tokens are automatically rotated when they reach 20% of their remaining lifetime. This means: + +- In the worst-case scenario, a scan might start right before a token rotation occurs +- At this point, the current token has approximately 2.4 hours remaining (20% of 12 hours) +- The scan will use this current token for its entire duration +- If the scan runs longer than 2.4 hours, it will complete successfully but fail when attempting to save results to S3 because the token has expired + +Therefore, scans must complete within 2.4 hours to ensure results can be persisted to S3. Depending on the expected scan duration in your setup, this limitation can pose a problem. See: [Issue secureCodeBox/secureCodeBox#2255](https://github.com/secureCodeBox/secureCodeBox/issues/2255) + +
+ Example Pod Identity Setup (recommended over IRSA) + + Terraform/OpenTofu setup for the IAM Role & Policy: + ```tf + resource "aws_iam_policy" "securecodebox_s3_policy" { + name = "securecodebox-s3-${var.bucket_name}-access" + description = "IAM policy for secureCodeBox to access S3 bucket ${var.bucket_name}" + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Action = [ + "s3:GetObject", + "s3:PutObject", + "s3:DeleteObject", + "s3:GetObjectVersion", + "s3:PutObjectAcl", + "s3:GetObjectAcl" + ] + Resource = [ + "arn:aws:s3:::${var.bucket_name}/*" + ] + }, + { + Effect = "Allow" + Action = [ + "s3:ListBucket", + "s3:GetBucketLocation", + "s3:GetBucketVersioning" + ] + Resource = [ + "arn:aws:s3:::${var.bucket_name}" + ] + } + ] + }) + } + + # IAM Role for secureCodeBox with EKS Pod Identity + resource "aws_iam_role" "securecodebox_role" { + name = "securecodebox-role" + + max_session_duration = 12 * 60 * 60 // 12h, session duration needs to be this long to allow the operator to create presigned urls with a longer lifetime + + # Use EKS Pod Identity for the operator service account. + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Principal = { + Service = "pods.eks.amazonaws.com" + } + Action = [ + "sts:AssumeRole", + "sts:TagSession" + ] + } + ] + }) + } + + # Attach the S3 policy to the role + resource "aws_iam_role_policy_attachment" "securecodebox_s3_policy_attachment" { + role = aws_iam_role.securecodebox_role.name + policy_arn = aws_iam_policy.securecodebox_s3_policy.arn + } + + # Create EKS Pod Identity Association + resource "aws_eks_pod_identity_association" "securecodebox_operator" { + cluster_name = var.cluster_name + namespace = "securecodebox-system" + service_account = "securecodebox-operator" + role_arn = aws_iam_role.securecodebox_role.arn + } + ``` + + secureCodeBox Operator values: + + ```yaml + minio: + enabled: false + s3: + enabled: true + authType: "aws-iam" + bucket: + endpoint: "s3..amazonaws.com" + ``` +
+ +
+ Example IRSA Setup + + Terraform/OpenTofu setup for the IAM Role & Policy: + ```tf + resource "aws_iam_policy" "securecodebox_s3_policy" { + name = "securecodebox-s3-${var.bucket_name}-access" + description = "IAM policy for secureCodeBox to access S3 bucket ${var.bucket_name}" + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Action = [ + "s3:GetObject", + "s3:PutObject", + "s3:DeleteObject", + "s3:GetObjectVersion", + "s3:PutObjectAcl", + "s3:GetObjectAcl" + ] + Resource = [ + "arn:aws:s3:::${var.bucket_name}/*" + ] + }, + { + Effect = "Allow" + Action = [ + "s3:ListBucket", + "s3:GetBucketLocation", + "s3:GetBucketVersioning" + ] + Resource = [ + "arn:aws:s3:::${var.bucket_name}" + ] + } + ] + }) + } + + # IAM Role for secureCodeBox with EKS Pod Identity + resource "aws_iam_role" "securecodebox_role" { + name = "securecodebox-role" + + max_session_duration = 12 * 60 * 60 // 12h, session duration needs to be this long to allow the operator to create presigned urls with a longer lifetime + + # Use IRSA (IAM Roles for Service Accounts) via the cluster OIDC provider. + # The cluster OIDC issuer is available from the data.aws_eks_cluster.cluster data source. + # The Federated principal is the cluster's OIDC provider ARN in the account. + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Principal = { + Federated = "arn:aws:iam::${var.aws_account_id}:oidc-provider/${var.oidc_provider}" + } + Action = "sts:AssumeRoleWithWebIdentity" + Condition = { + StringEquals = { + "${var.oidc_provider}:sub" = "system:serviceaccount:securecodebox-system:securecodebox-operator" + } + } + } + ] + }) + } + + # Attach the S3 policy to the role + resource "aws_iam_role_policy_attachment" "securecodebox_s3_policy_attachment" { + role = aws_iam_role.securecodebox_role.name + policy_arn = aws_iam_policy.securecodebox_s3_policy.arn + } + ``` + + secureCodeBox Operator values: + + ```yaml + minio: + enabled: false + s3: + enabled: true + authType: "aws-iam" + bucket: + endpoint: "s3..amazonaws.com" + serviceAccount: + annotations: + eks.amazonaws.com/role-arn: + ``` +
+::: #### Google Cloud Storage @@ -120,13 +321,13 @@ You can optionally deploy SCB scanner charts for each security scanner you want ```bash # The following chart will be installed in the `default` namespace by you can choose the namespace of your choice by # adding `--namespace YOURNAMESPACE` to each line -helm upgrade --install amass oci://ghcr.io/securecodebox/helm/amass helm upgrade --install gitleaks oci://ghcr.io/securecodebox/helm/gitleaks helm upgrade --install kube-hunter oci://ghcr.io/securecodebox/helm/kube-hunter helm upgrade --install nikto oci://ghcr.io/securecodebox/helm/nikto helm upgrade --install nmap oci://ghcr.io/securecodebox/helm/nmap helm upgrade --install ssh-audit oci://ghcr.io/securecodebox/helm/ssh-audit helm upgrade --install sslyze oci://ghcr.io/securecodebox/helm/sslyze +helm upgrade --install subfinder oci://ghcr.io/securecodebox/helm/subfinder helm upgrade --install trivy oci://ghcr.io/securecodebox/helm/trivy helm upgrade --install wpscan oci://ghcr.io/securecodebox/helm/wpscan helm upgrade --install zap-automation-framework oci://ghcr.io/securecodebox/helm/zap-automation-framework diff --git a/documentation/docs/getting-started/upgrading.md b/documentation/docs/getting-started/upgrading.md index 5f77c14536..d15c90a361 100644 --- a/documentation/docs/getting-started/upgrading.md +++ b/documentation/docs/getting-started/upgrading.md @@ -14,10 +14,12 @@ sidebar_position: 3 ### Removed / Replaced ScanTypes -* `typo3scan` was removed as the scanner itself [isn't maintaned anymore](https://github.com/whoot/Typo3Scan?tab=readme-ov-file#unsupported). Most security aspects of typo3 are now hard to verify from the outside as it requires authentication (which is really good). Some typo3 security aspects (e.g. a incomplete installation) can be verified by [nuclei](https://www.securecodebox.io/docs/scanners/nuclei). +* `zap-baseline-scan` and `zap-advanced` in favor of the `zap-automation-framework`. The `zap-automation-framework` ScanTpye includes all functionalities of the removed ScanTypes and can be customized easily. The default ScanType for the AutoDiscovery has been changed to the `zap-automation-framework` as well. For migrating to the `zap-automation-framework` please refer to [migration to zap-automation framework](/docs/scanners/zap-automation-framework#migration-to-zap-automation-framework) guide. +* `amass` has been replaced with `subfinder`. Amass is still an amzing tool, but with its focus on becoming more of a standalone platform / database for attack surfaces keeping it integrated and updated in the secureCodeBox was getting harder and harder. [subfinder](https://github.com/projectdiscovery/subfinder) is a very good replacement for subdomain discovery, thats also generally quicker and produces a similar result. * `kubeaudit` was removed as the scanner itself [isn't maintaned anymore](https://github.com/Shopify/kubeaudit?tab=readme-ov-file#-deprecation-notice-). As a replacement you can use the `trivy` with it's `k8s` scanning mode, see [trivy ScanType k8s example](https://www.securecodebox.io/docs/scanners/trivy#k8s). +* `typo3scan` was removed as the scanner itself [isn't maintaned anymore](https://github.com/whoot/Typo3Scan?tab=readme-ov-file#unsupported). Most security aspects of typo3 are now hard to verify from the outside as it requires authentication (which is really good). Some typo3 security aspects (e.g. a incomplete installation) can be verified by [nuclei](https://www.securecodebox.io/docs/scanners/nuclei). * `doggo` was removed. Doggo was added primarily as an experimentation to be used to deduplicate duplicate scan target from cascading rules based on DNS entries. That approach hasn't worked out unfortunately. The doggo integration has been non-functional for a while (see: https://github.com/secureCodeBox/secureCodeBox/issues/2853). As an alternative, nuclei already includes some DNS record based checks, if checks for specific records are required custom nuclei rules could be used to fulfil those requirements. -* `zap-baseline-scan` and `zap-advanced` in favor of the `zap-automation-framework`. The `zap-automation-framework` ScanTpye includes all functionalities of the removed ScanTypes and can be customized easily. The default ScanType for the AutoDiscovery has been changed to the `zap-automation-framework` as well. For migrating to the `zap-automation-framework` please refer to [migration to zap-automation framework](/docs/scanners/zap-automation-framework#migration-to-zap-automation-framework) guide. +* `cmseek` was removed. cmseek has seen little updates in the last years. Our secureCodeBox integration with cmseek was always pretty basic, only supporting joomla (a specfifc CMS) results, which hasn't been a big focus for us. As a replacement we recommend using nuclei which has joomla rules which will likely receive more updates in the future. ➡️ [Reference: #2670](https://github.com/secureCodeBox/secureCodeBox/issues/2670) @@ -49,6 +51,23 @@ If you had previously ingested finding using the scbv2 index prefix you can keep ➡️ [Reference: #2892](https://github.com/secureCodeBox/secureCodeBox/issues/2892) +### Replaced Bitnami MinIO Subchart with Direct MinIO Deployment + +Due to upcoming deprecations in Bitnami Helm charts, the operator's MinIO integration has been changed from using the Bitnami MinIO subchart to a direct MinIO deployment using the official `docker.io/minio/minio` image. + +**⚠️ Important Migration Notes:** +- **Data will NOT be migrated automatically** from the old Bitnami MinIO deployment to the new direct MinIO deployment +- If you have important scan data stored in the old MinIO instance, you must manually backup and restore it before upgrading +- The new MinIO deployment uses different naming conventions and storage configurations + +**For Production Environments:** +The included MinIO deployment is intended **only for quickstart and development setups**. For production environments, you should: +- Use an external S3-compatible storage service (AWS S3, Google Cloud Storage, etc.) +- Set `minio.enabled=false` and configure the `s3` section in your values +- Refer to the [installation documentation](installation.md) for external storage configuration + +If you need to continue using the embedded MinIO for development, the new deployment will create a fresh MinIO instance with the same default bucket configuration. + ## From 3.X to 4.X ### Renamed the docker images of demo-targets to include a "demo-target-" prefix diff --git a/documentation/docs/how-tos/scope.md b/documentation/docs/how-tos/scope.md index bfc4735f44..a6b0ab3653 100644 --- a/documentation/docs/how-tos/scope.md +++ b/documentation/docs/how-tos/scope.md @@ -11,7 +11,7 @@ sidebar_position: 7 ## Introduction In this step-by-step tutorial, we will go through all the required stages to set up engagement scope enforcement with secureCodeBox. -In this example, we are going to set up Amass and Nmap and run a scan with rules set-up so that we don't scan domains which are out-of-scope. +In this example, we are going to set up subfinder and Nmap and run a scan with rules set-up so that we don't scan domains which are out-of-scope. ## Setup @@ -19,11 +19,11 @@ For the sake of the tutorial, we assume that you have your Kubernetes cluster al If not, check out the [installation](/docs/getting-started/installation/) for more information. We also assume that you have the latest version of cascading scans installed. -We will start by installing Amass and Nmap: +We will start by installing subfinder and Nmap: ```bash -helm upgrade --install amass oci://ghcr.io/securecodebox/helm/amass -Release "amass" does not exist. Installing it now. +helm upgrade --install subfinder oci://ghcr.io/securecodebox/helm/subfinder +Release "subfinder" does not exist. Installing it now. [...] helm upgrade --install nmap oci://ghcr.io/securecodebox/helm/nmap Release "nmap" does not exist. Installing it now. @@ -33,14 +33,14 @@ Release "nmap" does not exist. Installing it now. ## Start Scan With Scope Limit Next, we can start creating our scan definition. -Let's assume that we would like amass to scan `nmap.org` for subdomains, but we would only like to run nmap on `scanme.nmap.org`. +Let's assume that we would like subfinder to scan `nmap.org` for subdomains, but we would only like to run nmap on `scanme.nmap.org`. In the example below, we only cascade if our `scope.cascading.securecodebox.io/domain` equals `{{attributes.name}}`. ```yaml apiVersion: "execution.securecodebox.io/v1" kind: Scan metadata: - name: "amass-scan" + name: "subdomain-scan" annotations: scope.cascading.securecodebox.io/domain: "scanme.nmap.org" spec: @@ -50,7 +50,7 @@ spec: - key: "scope.cascading.securecodebox.io/domain" operator: "In" values: ["{{attributes.name}}"] - scanType: "amass" + scanType: "subfinder" parameters: - "-d" - "nmap.org" @@ -64,23 +64,23 @@ Running this scan results in the following state: ```shell $ kubectl get scans -amass-scan amass Done 65 -nmap-scan-nmap-hostscan-86f2m nmap Done 6 +subdomain-scan subfinder Done 65 +nmap-scan-nmap-hostscan-86f2m nmap Done 6 $ kubectl get pods -cascading-scans-amass-scan-8cssx--1-hh2w6 0/1 Completed 0 2m51s -cascading-scans-nmap-scan-nmap-hostscan-86f2m-4mljv--1-7zgm2 0/1 Completed 0 2m23s -parse-amass-scan-zfhxg--1-shwkj 0/1 Completed 0 2m54s -parse-nmap-scan-nmap-hostscan-86f2m-d6jh6--1-ztgls 0/1 Completed 0 2m26s -scan-amass-scan-79h5f--1-vk7v5 0/2 Completed 0 4m22s -scan-nmap-scan-nmap-hostscan-86f2m-54pkd--1-pfpp6 0/2 Completed 0 2m48s +cascading-scans-subdomain-scan-8cssx--1-hh2w6 0/1 Completed 0 2m51s +cascading-scans-nmap-scan-nmap-hostscan-86f2m-4mljv--1-7zgm2 0/1 Completed 0 2m23s +parse-subdomain-scan-zfhxg--1-shwkj 0/1 Completed 0 2m54s +parse-nmap-scan-nmap-hostscan-86f2m-d6jh6--1-ztgls 0/1 Completed 0 2m26s +scan-subdomain-scan-79h5f--1-vk7v5 0/2 Completed 0 4m22s +scan-nmap-scan-nmap-hostscan-86f2m-54pkd--1-pfpp6 0/2 Completed 0 2m48s ``` -As you can see, amass found 65 domain names, but only a single nmap scan was created. +As you can see, subfinder found 65 domain names, but only a single nmap scan was created. In the cascading scans logs, you will see that lots of rules were not triggered as the domain was out of scope. ```shell -$ kubectl logs cascading-scans-amass-scan-8cssx--1-hh2w6 -Starting hook for Scan "amass-scan" +$ kubectl logs cascading-scans-subfinder-scan-8cssx--1-hh2w6 +Starting hook for Scan "subfinder-scan" Fetched 65 findings from the file storage Fetching CascadingScans using LabelSelector: "" Fetched 2 CascadingRules @@ -97,7 +97,7 @@ As an example, let's say you want to set up Nikto as a scanner. This scanner cascades on Nmap's open port finding and uses `$.hostOrIp` to start the scan. In some cases, nmap can return a hostname different to the original hostname, thus with scope rules we want to check for this. Preferably, we would like to use the same rule as above. -Unfortunately, nmap gives its hostname in `attributes.hostname` instead of the defined `attributes.name` (Amass finding). +Unfortunately, nmap gives its hostname in `attributes.hostname` instead of the defined `attributes.name` (subfinder finding). This results in the scope rule failing, and prevents Nikto from getting cascaded. To solve this situation, you have two options: @@ -112,7 +112,7 @@ Example: apiVersion: "execution.securecodebox.io/v1" kind: Scan metadata: - name: "amass-scan" + name: "subfinder-scan" annotations: scope.cascading.securecodebox.io/domain: "scanme.nmap.org" spec: @@ -124,7 +124,7 @@ spec: - key: "scope.cascading.securecodebox.io/domain" operator: "In" values: ["{{attributes.name}}"] - scanType: "amass" + scanType: "subfinder" parameters: - "-d" - "nmap.org" @@ -136,9 +136,9 @@ A more fool-proof solution is to ensure that the hostname field is available in When deploying your scanner, you can define `scopeLimiterAliases`. ```shell -$ helm upgrade --install amass oci://ghcr.io/securecodebox/helm/amass \ +$ helm upgrade --install subfinder oci://ghcr.io/securecodebox/helm/subfinder \ --set="parser.scopeLimiterAliases.hostname=\{\{attributes.name\}\}" -Release "amass" has been upgraded. Happy Helming! +Release "subfinder" has been upgraded. Happy Helming! [...] $ helm upgrade --install nmap oci://ghcr.io/securecodebox/helm/nmap \ --set="parser.scopeLimiterAliases.hostname=\{\{attributes.hostname\}\}" @@ -152,11 +152,11 @@ The aliases are added to the scanner's parse definition: apiVersion: execution.securecodebox.io/v1 kind: ParseDefinition metadata: - name: amass-jsonl + name: subfinder-jsonl namespace: default spec: env: [] - image: docker.io/securecodebox/parser-amass:3.5.0 + image: docker.io/securecodebox/parser-subfinder:3.16.0 imagePullPolicy: IfNotPresent scopeLimiterAliases: hostname: "{{attributes.name}}" @@ -173,14 +173,14 @@ scopeLimiter: values: ["{{$.hostname}}"] ``` -Running this scan inside the cluster runs Amass, Nmap, and Nikto as expected. +Running this scan inside the cluster runs subfinder, Nmap, and Nikto as expected. ```shell $ kubectl get scans -NAME TYPE STATE FINDINGS -amass-scan amass Done 65 -nikto-scan-nmap-hostscan-rhhqz-nikto-http-ps8cl nikto Done 6 -nmap-scan-nmap-hostscan-rhhqz nmap Done 6 +NAME TYPE STATE FINDINGS +subdomain-scan subfinder Done 65 +nikto-scan-nmap-hostscan-rhhqz-nikto-http-ps8cl nikto Done 6 +nmap-scan-nmap-hostscan-rhhqz nmap Done 6 ``` :::caution diff --git a/documentation/docusaurus.config.js b/documentation/docusaurus.config.js index c84e2f2b3b..81989509d0 100644 --- a/documentation/docusaurus.config.js +++ b/documentation/docusaurus.config.js @@ -9,6 +9,9 @@ module.exports = { url: "https://www.securecodebox.io", baseUrl: "/", onBrokenLinks: "throw", + onBrokenMarkdownLinks: "throw", + onDuplicateRoutes: "throw", + onBrokenAnchors: "throw", favicon: "img/Favicon.svg", organizationName: "secureCodeBox", // Usually your GitHub org/user name. projectName: "secureCodeBox", // Usually your repo name. @@ -167,5 +170,5 @@ module.exports = { ], ], themes: ["@docusaurus/theme-live-codeblock"], - plugins: ["docusaurus-plugin-sass", "@cmfcmf/docusaurus-search-local"], + plugins: ["docusaurus-plugin-sass", "docusaurus-lunr-search"], }; diff --git a/documentation/package-lock.json b/documentation/package-lock.json index 83e3880023..0c07d264fb 100644 --- a/documentation/package-lock.json +++ b/documentation/package-lock.json @@ -9,315 +9,254 @@ "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "@cmfcmf/docusaurus-search-local": "^1.2.0", - "@docusaurus/core": "^3.8.1", - "@docusaurus/preset-classic": "^3.8.1", - "@docusaurus/theme-live-codeblock": "^3.8.1", - "@mdx-js/react": "^3.1.0", + "@docusaurus/core": "^3.9.2", + "@docusaurus/preset-classic": "^3.9.2", + "@docusaurus/theme-live-codeblock": "^3.9.2", + "@mdx-js/react": "^3.1.1", "clsx": "^2.1.1", "colors": "^1.4.0", + "docusaurus-lunr-search": "^3.6.0", "docusaurus-plugin-sass": "^0.2.6", "gray-matter": "^4.0.3", "mustache": "^4.2.0", "node-fetch": "^3.1.1", "prism-react-renderer": "^2.4.1", - "react": "^19.1.0", - "react-dom": "^19.1.0", - "rimraf": "^6.0.1", - "sass": "1.89" + "react": "^19.2.4", + "react-dom": "^19.2.4", + "rimraf": "^6.1.2", + "sass": "1.97" }, "devDependencies": { "@docusaurus/module-type-aliases": "^3.6.0", - "@docusaurus/tsconfig": "^3.8.1", + "@docusaurus/tsconfig": "^3.9.2", "@docusaurus/types": "^3.6.0", - "@types/node": "^24.0.13", - "@types/react": "^19.1.8", + "@types/node": "^25.0.10", + "@types/react": "^19.2.9", "@types/react-helmet": "^6.1.11", "@types/react-router-dom": "^5.1.8", - "sass-loader": "^16.0.5", - "typescript": "^5.8.3" + "sass-loader": "^16.0.6", + "typescript": "^5.9.3" }, "engines": { "node": ">=18.0" } }, - "node_modules/@algolia/autocomplete-core": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.12.1.tgz", - "integrity": "sha512-Paf1MEdsU8EA5eApJlp6yNJGn6IfWec6UoJyv6fzI+T2v9nU4ynH4nkq07hzOilImVy33vFlzh1+D7jcU2lMFg==", - "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.12.1", - "@algolia/autocomplete-shared": "1.12.1" - } - }, - "node_modules/@algolia/autocomplete-js": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-js/-/autocomplete-js-1.12.1.tgz", - "integrity": "sha512-o8OVeyTSCJ1n5xnULBqlJ3gcimlyevUeNUmGXuHgd6K2TeHmZ8EgaxHWuyzOdgWNjcJpCpjDh4Q/hEvQq3svDQ==", + "node_modules/@ai-sdk/gateway": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-2.0.0.tgz", + "integrity": "sha512-Gj0PuawK7NkZuyYgO/h5kDK/l6hFOjhLdTq3/Lli1FTl47iGmwhH1IZQpAL3Z09BeFYWakcwUmn02ovIm2wy9g==", + "license": "Apache-2.0", "dependencies": { - "@algolia/autocomplete-core": "1.12.1", - "@algolia/autocomplete-preset-algolia": "1.12.1", - "@algolia/autocomplete-shared": "1.12.1", - "htm": "^3.1.1", - "preact": "^10.13.2" + "@ai-sdk/provider": "2.0.0", + "@ai-sdk/provider-utils": "3.0.12", + "@vercel/oidc": "3.0.3" }, - "peerDependencies": { - "@algolia/client-search": ">= 4.5.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.12.1.tgz", - "integrity": "sha512-wZnfgmJA+g+WWkyXRZqv9NvRtOrZCnsZMpSvGe4QdQatEWRTAn2hry1cHMj8+sxwpqQQE7Kt/GAZhElrmErPkw==", - "dependencies": { - "@algolia/autocomplete-shared": "1.12.1" + "engines": { + "node": ">=18" }, "peerDependencies": { - "search-insights": ">= 1 < 3" + "zod": "^3.25.76 || ^4.1.8" } }, - "node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.12.1.tgz", - "integrity": "sha512-fbciiuDZ6WsQOhf3Rdm4ctZpOGngg8hNtss4FCJz4FGnGSUxs+H0n38k+FbQ3vcfzQ0nsdAjXWwM4G0OLJE3Mw==", + "node_modules/@ai-sdk/provider": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-2.0.0.tgz", + "integrity": "sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA==", + "license": "Apache-2.0", "dependencies": { - "@algolia/autocomplete-shared": "1.12.1" + "json-schema": "^0.4.0" }, - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/autocomplete-shared": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.12.1.tgz", - "integrity": "sha512-Q2NQ9pxSpwi0WsLlGtrnE+nMo4ERgB4YlYi7eW7EIUtD0LSixLQeOqlNNYIhFUYbNYpfG5s9L3W8PMfS2M4qOg==", - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/autocomplete-theme-classic": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-theme-classic/-/autocomplete-theme-classic-1.12.1.tgz", - "integrity": "sha512-oKmMEWAtASUizKc73RKS5vzu0iURM+joVdlAkOVuCpjajUJ98ejMnk43ht4FKPBXDBAVSlM4SmS05lHIpYVLIg==" - }, - "node_modules/@algolia/cache-browser-local-storage": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.20.0.tgz", - "integrity": "sha512-uujahcBt4DxduBTvYdwO3sBfHuJvJokiC3BP1+O70fglmE1ShkH8lpXqZBac1rrU3FnNYSUs4pL9lBdTKeRPOQ==", - "dependencies": { - "@algolia/cache-common": "4.20.0" - } - }, - "node_modules/@algolia/cache-common": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.20.0.tgz", - "integrity": "sha512-vCfxauaZutL3NImzB2G9LjLt36vKAckc6DhMp05An14kVo8F1Yofb6SIl6U3SaEz8pG2QOB9ptwM5c+zGevwIQ==" - }, - "node_modules/@algolia/cache-in-memory": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.20.0.tgz", - "integrity": "sha512-Wm9ak/IaacAZXS4mB3+qF/KCoVSBV6aLgIGFEtQtJwjv64g4ePMapORGmCyulCFwfePaRAtcaTbMcJF+voc/bg==", - "dependencies": { - "@algolia/cache-common": "4.20.0" + "engines": { + "node": ">=18" } }, - "node_modules/@algolia/client-abtesting": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.27.0.tgz", - "integrity": "sha512-SITU5umoknxETtw67TxJu9njyMkWiH8pM+Bvw4dzfuIrIAT6Y1rmwV4y0A0didWoT+6xVuammIykbtBMolBcmg==", - "license": "MIT", + "node_modules/@ai-sdk/provider-utils": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.12.tgz", + "integrity": "sha512-ZtbdvYxdMoria+2SlNarEk6Hlgyf+zzcznlD55EAl+7VZvJaSg2sqPvwArY7L6TfDEDJsnCq0fdhBSkYo0Xqdg==", + "license": "Apache-2.0", "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" + "@ai-sdk/provider": "2.0.0", + "@standard-schema/spec": "^1.0.0", + "eventsource-parser": "^3.0.5" }, "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-abtesting/node_modules/@algolia/client-common": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.27.0.tgz", - "integrity": "sha512-tnFOzdNuMzsz93kOClj3fKfuYoF3oYaEB5bggULSj075GJ7HUNedBEm7a6ScrjtnOaOtipbnT7veUpHA4o4wEQ==", - "license": "MIT", - "engines": { - "node": ">= 14.0.0" + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" } }, - "node_modules/@algolia/client-abtesting/node_modules/@algolia/requester-browser-xhr": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.27.0.tgz", - "integrity": "sha512-ErenYTcXl16wYXtf0pxLl9KLVxIztuehqXHfW9nNsD8mz9OX42HbXuPzT7y6JcPiWJpc/UU/LY5wBTB65vsEUg==", - "license": "MIT", + "node_modules/@ai-sdk/react": { + "version": "2.0.76", + "resolved": "https://registry.npmjs.org/@ai-sdk/react/-/react-2.0.76.tgz", + "integrity": "sha512-ggAPzyaKJTqUWigpxMzI5DuC0Y3iEpDUPCgz6/6CpnKZY/iok+x5xiZhDemeaP0ILw5IQekV0kdgBR8JPgI8zQ==", + "license": "Apache-2.0", "dependencies": { - "@algolia/client-common": "5.27.0" + "@ai-sdk/provider-utils": "3.0.12", + "ai": "5.0.76", + "swr": "^2.2.5", + "throttleit": "2.1.0" }, "engines": { - "node": ">= 14.0.0" + "node": ">=18" + }, + "peerDependencies": { + "react": "^18 || ^19 || ^19.0.0-rc", + "zod": "^3.25.76 || ^4.1.8" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } } }, - "node_modules/@algolia/client-abtesting/node_modules/@algolia/requester-node-http": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.27.0.tgz", - "integrity": "sha512-Nx9EdLYZDsaYFTthqmc0XcVvsx6jqeEX8fNiYOB5i2HboQwl8pJPj1jFhGqoGd0KG7KFR+sdPO5/e0EDDAru2Q==", + "node_modules/@algolia/abtesting": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.6.1.tgz", + "integrity": "sha512-wV/gNRkzb7sI9vs1OneG129hwe3Q5zPj7zigz3Ps7M5Lpo2hSorrOnXNodHEOV+yXE/ks4Pd+G3CDFIjFTWhMQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.27.0" + "@algolia/client-common": "5.40.1", + "@algolia/requester-browser-xhr": "5.40.1", + "@algolia/requester-fetch": "5.40.1", + "@algolia/requester-node-http": "5.40.1" }, "engines": { "node": ">= 14.0.0" } }, - "node_modules/@algolia/client-account": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.20.0.tgz", - "integrity": "sha512-GGToLQvrwo7am4zVkZTnKa72pheQeez/16sURDWm7Seyz+HUxKi3BM6fthVVPUEBhtJ0reyVtuK9ArmnaKl10Q==", + "node_modules/@algolia/autocomplete-core": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.19.2.tgz", + "integrity": "sha512-mKv7RyuAzXvwmq+0XRK8HqZXt9iZ5Kkm2huLjgn5JoCPtDy+oh9yxUMfDDaVCw0oyzZ1isdJBc7l9nuCyyR7Nw==", + "license": "MIT", "dependencies": { - "@algolia/client-common": "4.20.0", - "@algolia/client-search": "4.20.0", - "@algolia/transporter": "4.20.0" + "@algolia/autocomplete-plugin-algolia-insights": "1.19.2", + "@algolia/autocomplete-shared": "1.19.2" } }, - "node_modules/@algolia/client-analytics": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.20.0.tgz", - "integrity": "sha512-EIr+PdFMOallRdBTHHdKI3CstslgLORQG7844Mq84ib5oVFRVASuuPmG4bXBgiDbcsMLUeOC6zRVJhv1KWI0ug==", + "node_modules/@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.19.2.tgz", + "integrity": "sha512-TjxbcC/r4vwmnZaPwrHtkXNeqvlpdyR+oR9Wi2XyfORkiGkLTVhX2j+O9SaCCINbKoDfc+c2PB8NjfOnz7+oKg==", + "license": "MIT", "dependencies": { - "@algolia/client-common": "4.20.0", - "@algolia/client-search": "4.20.0", - "@algolia/requester-common": "4.20.0", - "@algolia/transporter": "4.20.0" + "@algolia/autocomplete-shared": "1.19.2" + }, + "peerDependencies": { + "search-insights": ">= 1 < 3" } }, - "node_modules/@algolia/client-common": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.20.0.tgz", - "integrity": "sha512-P3WgMdEss915p+knMMSd/fwiHRHKvDu4DYRrCRaBrsfFw7EQHon+EbRSm4QisS9NYdxbS04kcvNoavVGthyfqQ==", - "dependencies": { - "@algolia/requester-common": "4.20.0", - "@algolia/transporter": "4.20.0" + "node_modules/@algolia/autocomplete-shared": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.19.2.tgz", + "integrity": "sha512-jEazxZTVD2nLrC+wYlVHQgpBoBB5KPStrJxLzsIFl6Kqd1AlG9sIAGl39V5tECLpIQzB3Qa2T6ZPJ1ChkwMK/w==", + "license": "MIT", + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" } }, - "node_modules/@algolia/client-insights": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.27.0.tgz", - "integrity": "sha512-y1qgw39qZijjQBXrqZTiwK1cWgWGRiLpJNWBv9w36nVMKfl9kInrfsYmdBAfmlhVgF/+Woe0y1jQ7pa4HyShAw==", + "node_modules/@algolia/client-abtesting": { + "version": "5.40.1", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.40.1.tgz", + "integrity": "sha512-cxKNATPY5t+Mv8XAVTI57altkaPH+DZi4uMrnexPxPHODMljhGYY+GDZyHwv9a+8CbZHcY372OkxXrDMZA4Lnw==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" + "@algolia/client-common": "5.40.1", + "@algolia/requester-browser-xhr": "5.40.1", + "@algolia/requester-fetch": "5.40.1", + "@algolia/requester-node-http": "5.40.1" }, "engines": { "node": ">= 14.0.0" } }, - "node_modules/@algolia/client-insights/node_modules/@algolia/client-common": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.27.0.tgz", - "integrity": "sha512-tnFOzdNuMzsz93kOClj3fKfuYoF3oYaEB5bggULSj075GJ7HUNedBEm7a6ScrjtnOaOtipbnT7veUpHA4o4wEQ==", + "node_modules/@algolia/client-analytics": { + "version": "5.40.1", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.40.1.tgz", + "integrity": "sha512-XP008aMffJCRGAY8/70t+hyEyvqqV7YKm502VPu0+Ji30oefrTn2al7LXkITz7CK6I4eYXWRhN6NaIUi65F1OA==", "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.40.1", + "@algolia/requester-browser-xhr": "5.40.1", + "@algolia/requester-fetch": "5.40.1", + "@algolia/requester-node-http": "5.40.1" + }, "engines": { "node": ">= 14.0.0" } }, - "node_modules/@algolia/client-insights/node_modules/@algolia/requester-browser-xhr": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.27.0.tgz", - "integrity": "sha512-ErenYTcXl16wYXtf0pxLl9KLVxIztuehqXHfW9nNsD8mz9OX42HbXuPzT7y6JcPiWJpc/UU/LY5wBTB65vsEUg==", + "node_modules/@algolia/client-common": { + "version": "5.40.1", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.40.1.tgz", + "integrity": "sha512-gWfQuQUBtzUboJv/apVGZMoxSaB0M4Imwl1c9Ap+HpCW7V0KhjBddqF2QQt5tJZCOFsfNIgBbZDGsEPaeKUosw==", "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0" - }, "engines": { "node": ">= 14.0.0" } }, - "node_modules/@algolia/client-insights/node_modules/@algolia/requester-node-http": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.27.0.tgz", - "integrity": "sha512-Nx9EdLYZDsaYFTthqmc0XcVvsx6jqeEX8fNiYOB5i2HboQwl8pJPj1jFhGqoGd0KG7KFR+sdPO5/e0EDDAru2Q==", + "node_modules/@algolia/client-insights": { + "version": "5.40.1", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.40.1.tgz", + "integrity": "sha512-RTLjST/t+lsLMouQ4zeLJq2Ss+UNkLGyNVu+yWHanx6kQ3LT5jv8UvPwyht9s7R6jCPnlSI77WnL80J32ZuyJg==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.27.0" + "@algolia/client-common": "5.40.1", + "@algolia/requester-browser-xhr": "5.40.1", + "@algolia/requester-fetch": "5.40.1", + "@algolia/requester-node-http": "5.40.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-personalization": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.20.0.tgz", - "integrity": "sha512-N9+zx0tWOQsLc3K4PVRDV8GUeOLAY0i445En79Pr3zWB+m67V+n/8w4Kw1C5LlbHDDJcyhMMIlqezh6BEk7xAQ==", - "dependencies": { - "@algolia/client-common": "4.20.0", - "@algolia/requester-common": "4.20.0", - "@algolia/transporter": "4.20.0" - } - }, - "node_modules/@algolia/client-query-suggestions": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.27.0.tgz", - "integrity": "sha512-V8/To+SsAl2sdw2AAjeLJuCW1L+xpz+LAGerJK7HKqHzE5yQhWmIWZTzqYQcojkii4iBMYn0y3+uReWqT8XVSQ==", + "version": "5.40.1", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.40.1.tgz", + "integrity": "sha512-2FEK6bUomBzEYkTKzD0iRs7Ljtjb45rKK/VSkyHqeJnG+77qx557IeSO0qVFE3SfzapNcoytTofnZum0BQ6r3Q==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" + "@algolia/client-common": "5.40.1", + "@algolia/requester-browser-xhr": "5.40.1", + "@algolia/requester-fetch": "5.40.1", + "@algolia/requester-node-http": "5.40.1" }, "engines": { "node": ">= 14.0.0" } }, - "node_modules/@algolia/client-query-suggestions/node_modules/@algolia/client-common": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.27.0.tgz", - "integrity": "sha512-tnFOzdNuMzsz93kOClj3fKfuYoF3oYaEB5bggULSj075GJ7HUNedBEm7a6ScrjtnOaOtipbnT7veUpHA4o4wEQ==", - "license": "MIT", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-query-suggestions/node_modules/@algolia/requester-browser-xhr": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.27.0.tgz", - "integrity": "sha512-ErenYTcXl16wYXtf0pxLl9KLVxIztuehqXHfW9nNsD8mz9OX42HbXuPzT7y6JcPiWJpc/UU/LY5wBTB65vsEUg==", + "node_modules/@algolia/client-query-suggestions": { + "version": "5.40.1", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.40.1.tgz", + "integrity": "sha512-Nju4NtxAvXjrV2hHZNLKVJLXjOlW6jAXHef/CwNzk1b2qIrCWDO589ELi5ZHH1uiWYoYyBXDQTtHmhaOVVoyXg==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.27.0" + "@algolia/client-common": "5.40.1", + "@algolia/requester-browser-xhr": "5.40.1", + "@algolia/requester-fetch": "5.40.1", + "@algolia/requester-node-http": "5.40.1" }, "engines": { "node": ">= 14.0.0" } }, - "node_modules/@algolia/client-query-suggestions/node_modules/@algolia/requester-node-http": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.27.0.tgz", - "integrity": "sha512-Nx9EdLYZDsaYFTthqmc0XcVvsx6jqeEX8fNiYOB5i2HboQwl8pJPj1jFhGqoGd0KG7KFR+sdPO5/e0EDDAru2Q==", + "node_modules/@algolia/client-search": { + "version": "5.40.1", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.40.1.tgz", + "integrity": "sha512-Mw6pAUF121MfngQtcUb5quZVqMC68pSYYjCRZkSITC085S3zdk+h/g7i6FxnVdbSU6OztxikSDMh1r7Z+4iPlA==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.27.0" + "@algolia/client-common": "5.40.1", + "@algolia/requester-browser-xhr": "5.40.1", + "@algolia/requester-fetch": "5.40.1", + "@algolia/requester-node-http": "5.40.1" }, "engines": { "node": ">= 14.0.0" } }, - "node_modules/@algolia/client-search": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.20.0.tgz", - "integrity": "sha512-zgwqnMvhWLdpzKTpd3sGmMlr4c+iS7eyyLGiaO51zDZWGMkpgoNVmltkzdBwxOVXz0RsFMznIxB9zuarUv4TZg==", - "dependencies": { - "@algolia/client-common": "4.20.0", - "@algolia/requester-common": "4.20.0", - "@algolia/transporter": "4.20.0" - } - }, "node_modules/@algolia/events": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", @@ -325,214 +264,86 @@ "license": "MIT" }, "node_modules/@algolia/ingestion": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.27.0.tgz", - "integrity": "sha512-xNCyWeqpmEo4EdmpG57Fs1fJIQcPwt5NnJ6MBdXnUdMVXF4f5PHgza+HQWQQcYpCsune96jfmR0v7us6gRIlCw==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/ingestion/node_modules/@algolia/client-common": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.27.0.tgz", - "integrity": "sha512-tnFOzdNuMzsz93kOClj3fKfuYoF3oYaEB5bggULSj075GJ7HUNedBEm7a6ScrjtnOaOtipbnT7veUpHA4o4wEQ==", - "license": "MIT", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/ingestion/node_modules/@algolia/requester-browser-xhr": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.27.0.tgz", - "integrity": "sha512-ErenYTcXl16wYXtf0pxLl9KLVxIztuehqXHfW9nNsD8mz9OX42HbXuPzT7y6JcPiWJpc/UU/LY5wBTB65vsEUg==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/ingestion/node_modules/@algolia/requester-node-http": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.27.0.tgz", - "integrity": "sha512-Nx9EdLYZDsaYFTthqmc0XcVvsx6jqeEX8fNiYOB5i2HboQwl8pJPj1jFhGqoGd0KG7KFR+sdPO5/e0EDDAru2Q==", + "version": "1.40.1", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.40.1.tgz", + "integrity": "sha512-z+BPlhs45VURKJIxsR99NNBWpUEEqIgwt10v/fATlNxc4UlXvALdOsWzaFfe89/lbP5Bu4+mbO59nqBC87ZM/g==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.27.0" + "@algolia/client-common": "5.40.1", + "@algolia/requester-browser-xhr": "5.40.1", + "@algolia/requester-fetch": "5.40.1", + "@algolia/requester-node-http": "5.40.1" }, "engines": { "node": ">= 14.0.0" } }, - "node_modules/@algolia/logger-common": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.20.0.tgz", - "integrity": "sha512-xouigCMB5WJYEwvoWW5XDv7Z9f0A8VoXJc3VKwlHJw/je+3p2RcDXfksLI4G4lIVncFUYMZx30tP/rsdlvvzHQ==" - }, - "node_modules/@algolia/logger-console": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.20.0.tgz", - "integrity": "sha512-THlIGG1g/FS63z0StQqDhT6bprUczBI8wnLT3JWvfAQDZX5P6fCg7dG+pIrUBpDIHGszgkqYEqECaKKsdNKOUA==", - "dependencies": { - "@algolia/logger-common": "4.20.0" - } - }, "node_modules/@algolia/monitoring": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.27.0.tgz", - "integrity": "sha512-P0NDiEFyt9UYQLBI0IQocIT7xHpjMpoFN3UDeerbztlkH9HdqT0GGh1SHYmNWpbMWIGWhSJTtz6kSIWvFu4+pw==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/monitoring/node_modules/@algolia/client-common": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.27.0.tgz", - "integrity": "sha512-tnFOzdNuMzsz93kOClj3fKfuYoF3oYaEB5bggULSj075GJ7HUNedBEm7a6ScrjtnOaOtipbnT7veUpHA4o4wEQ==", - "license": "MIT", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/monitoring/node_modules/@algolia/requester-browser-xhr": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.27.0.tgz", - "integrity": "sha512-ErenYTcXl16wYXtf0pxLl9KLVxIztuehqXHfW9nNsD8mz9OX42HbXuPzT7y6JcPiWJpc/UU/LY5wBTB65vsEUg==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/monitoring/node_modules/@algolia/requester-node-http": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.27.0.tgz", - "integrity": "sha512-Nx9EdLYZDsaYFTthqmc0XcVvsx6jqeEX8fNiYOB5i2HboQwl8pJPj1jFhGqoGd0KG7KFR+sdPO5/e0EDDAru2Q==", + "version": "1.40.1", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.40.1.tgz", + "integrity": "sha512-VJMUMbO0wD8Rd2VVV/nlFtLJsOAQvjnVNGkMkspFiFhpBA7s/xJOb+fJvvqwKFUjbKTUA7DjiSi1ljSMYBasXg==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.27.0" + "@algolia/client-common": "5.40.1", + "@algolia/requester-browser-xhr": "5.40.1", + "@algolia/requester-fetch": "5.40.1", + "@algolia/requester-node-http": "5.40.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/recommend": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.27.0.tgz", - "integrity": "sha512-cqfTMF1d1cc7hg0vITNAFxJZas7MJ4Obc36WwkKpY23NOtGb+4tH9X7UKlQa2PmTgbXIANoJ/DAQTeiVlD2I4Q==", + "version": "5.40.1", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.40.1.tgz", + "integrity": "sha512-ehvJLadKVwTp9Scg9NfzVSlBKH34KoWOQNTaN8i1Ac64AnO6iH2apJVSP6GOxssaghZ/s8mFQsDH3QIZoluFHA==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" + "@algolia/client-common": "5.40.1", + "@algolia/requester-browser-xhr": "5.40.1", + "@algolia/requester-fetch": "5.40.1", + "@algolia/requester-node-http": "5.40.1" }, "engines": { "node": ">= 14.0.0" } }, - "node_modules/@algolia/recommend/node_modules/@algolia/client-common": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.27.0.tgz", - "integrity": "sha512-tnFOzdNuMzsz93kOClj3fKfuYoF3oYaEB5bggULSj075GJ7HUNedBEm7a6ScrjtnOaOtipbnT7veUpHA4o4wEQ==", - "license": "MIT", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/recommend/node_modules/@algolia/requester-browser-xhr": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.27.0.tgz", - "integrity": "sha512-ErenYTcXl16wYXtf0pxLl9KLVxIztuehqXHfW9nNsD8mz9OX42HbXuPzT7y6JcPiWJpc/UU/LY5wBTB65vsEUg==", + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.40.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.40.1.tgz", + "integrity": "sha512-PbidVsPurUSQIr6X9/7s34mgOMdJnn0i6p+N6Ab+lsNhY5eiu+S33kZEpZwkITYBCIbhzDLOvb7xZD3gDi+USA==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.27.0" + "@algolia/client-common": "5.40.1" }, "engines": { "node": ">= 14.0.0" } }, - "node_modules/@algolia/recommend/node_modules/@algolia/requester-node-http": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.27.0.tgz", - "integrity": "sha512-Nx9EdLYZDsaYFTthqmc0XcVvsx6jqeEX8fNiYOB5i2HboQwl8pJPj1jFhGqoGd0KG7KFR+sdPO5/e0EDDAru2Q==", + "node_modules/@algolia/requester-fetch": { + "version": "5.40.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.40.1.tgz", + "integrity": "sha512-ThZ5j6uOZCF11fMw9IBkhigjOYdXGXQpj6h4k+T9UkZrF2RlKcPynFzDeRgaLdpYk8Yn3/MnFbwUmib7yxj5Lw==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.27.0" + "@algolia/client-common": "5.40.1" }, "engines": { "node": ">= 14.0.0" } }, - "node_modules/@algolia/requester-browser-xhr": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.20.0.tgz", - "integrity": "sha512-HbzoSjcjuUmYOkcHECkVTwAelmvTlgs48N6Owt4FnTOQdwn0b8pdht9eMgishvk8+F8bal354nhx/xOoTfwiAw==", - "dependencies": { - "@algolia/requester-common": "4.20.0" - } - }, - "node_modules/@algolia/requester-common": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.20.0.tgz", - "integrity": "sha512-9h6ye6RY/BkfmeJp7Z8gyyeMrmmWsMOCRBXQDs4mZKKsyVlfIVICpcSibbeYcuUdurLhIlrOUkH3rQEgZzonng==" - }, - "node_modules/@algolia/requester-fetch": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.27.0.tgz", - "integrity": "sha512-CNOvmXsVi+IvT7z1d+6X7FveVkgEQwTNgipjQCHTIbF9KSMfZR7tUsJC+NpELrm10ALdOMauah84ybs9rw1cKQ==", + "node_modules/@algolia/requester-node-http": { + "version": "5.40.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.40.1.tgz", + "integrity": "sha512-H1gYPojO6krWHnUXu/T44DrEun/Wl95PJzMXRcM/szstNQczSbwq6wIFJPI9nyE95tarZfUNU3rgorT+wZ6iCQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.27.0" + "@algolia/client-common": "5.40.1" }, "engines": { "node": ">= 14.0.0" } }, - "node_modules/@algolia/requester-fetch/node_modules/@algolia/client-common": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.27.0.tgz", - "integrity": "sha512-tnFOzdNuMzsz93kOClj3fKfuYoF3oYaEB5bggULSj075GJ7HUNedBEm7a6ScrjtnOaOtipbnT7veUpHA4o4wEQ==", - "license": "MIT", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-node-http": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.20.0.tgz", - "integrity": "sha512-ocJ66L60ABSSTRFnCHIEZpNHv6qTxsBwJEPfYaSBsLQodm0F9ptvalFkHMpvj5DfE22oZrcrLbOYM2bdPJRHng==", - "dependencies": { - "@algolia/requester-common": "4.20.0" - } - }, - "node_modules/@algolia/transporter": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.20.0.tgz", - "integrity": "sha512-Lsii1pGWOAISbzeyuf+r/GPhvHMPHSPrTDWNcIzOE1SG1inlJHICaVe2ikuoRjcpgxZNU54Jl+if15SUCsaTUg==", - "dependencies": { - "@algolia/cache-common": "4.20.0", - "@algolia/logger-common": "4.20.0", - "@algolia/requester-common": "4.20.0" - } - }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -561,9 +372,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", - "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", + "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -650,13 +461,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", - "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.25.9", - "@babel/helper-validator-option": "^7.25.9", + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -731,16 +542,16 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.4.tgz", - "integrity": "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", + "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "debug": "^4.4.1", "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" + "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -889,9 +700,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -1849,16 +1660,16 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.27.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.27.4.tgz", - "integrity": "sha512-D68nR5zxU64EUzV8i7T3R5XP0Xhrou/amNnddsRQssx6GrTLdZl1rLxyjtVZBd+v/NVX4AbTPOB5aU8thAZV1A==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.3.tgz", + "integrity": "sha512-Y6ab1kGqZ0u42Zv/4a7l0l72n9DKP/MKoKWaUSBylrhNZO2prYuqFOLbn5aW5SIFXwSH93yfjbgllL8lxuGKLg==", "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.11.0", - "babel-plugin-polyfill-regenerator": "^0.6.1", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", "semver": "^6.3.1" }, "engines": { @@ -1869,13 +1680,13 @@ } }, "node_modules/@babel/plugin-transform-runtime/node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz", - "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.3", - "core-js-compat": "^3.40.0" + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -2206,12 +2017,12 @@ } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.27.6.tgz", - "integrity": "sha512-vDVrlmRAY8z9Ul/HxT+8ceAru95LQgkSKiXkSYZvqtbkPSfhZJgpRp45Cldbh1GJ1kxzQkI70AqyrTI58KpaWQ==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.28.4.tgz", + "integrity": "sha512-h7iEYiW4HebClDEhtvFObtPmIvrd1SSfpI9EhOeKk4CtIK/ngBWFpuhCzhdmRKtg71ylcue+9I6dv54XYO1epQ==", "license": "MIT", "dependencies": { - "core-js-pure": "^3.30.2" + "core-js-pure": "^3.43.0" }, "engines": { "node": ">=6.9.0" @@ -2262,39 +2073,6 @@ "node": ">=6.9.0" } }, - "node_modules/@cmfcmf/docusaurus-search-local": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@cmfcmf/docusaurus-search-local/-/docusaurus-search-local-1.2.0.tgz", - "integrity": "sha512-Tc0GhRBsfZAiB+f6BoPB8YCQap6JzzcDyJ0dLSCSzWQ6wdWvDlTBrHc1YqR8q8AZ+STRszL5eZpZFi5dbTCdYg==", - "dependencies": { - "@algolia/autocomplete-js": "^1.8.2", - "@algolia/autocomplete-theme-classic": "^1.8.2", - "@algolia/client-search": "^4.12.0", - "algoliasearch": "^4.12.0", - "cheerio": "^1.0.0-rc.9", - "clsx": "^1.1.1", - "lunr-languages": "^1.4.0", - "mark.js": "^8.11.1", - "tslib": "^2.6.3" - }, - "peerDependencies": { - "@docusaurus/core": "^2.0.0", - "nodejieba": "^2.5.0" - }, - "peerDependenciesMeta": { - "nodejieba": { - "optional": true - } - } - }, - "node_modules/@cmfcmf/docusaurus-search-local/node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", - "engines": { - "node": ">=6" - } - }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -2328,9 +2106,9 @@ } }, "node_modules/@csstools/color-helpers": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", - "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", "funding": [ { "type": "github", @@ -2370,9 +2148,9 @@ } }, "node_modules/@csstools/css-color-parser": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.10.tgz", - "integrity": "sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", "funding": [ { "type": "github", @@ -2385,7 +2163,7 @@ ], "license": "MIT", "dependencies": { - "@csstools/color-helpers": "^5.0.2", + "@csstools/color-helpers": "^5.1.0", "@csstools/css-calc": "^2.1.4" }, "engines": { @@ -2460,10 +2238,39 @@ "@csstools/css-tokenizer": "^3.0.4" } }, + "node_modules/@csstools/postcss-alpha-function": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-alpha-function/-/postcss-alpha-function-1.0.1.tgz", + "integrity": "sha512-isfLLwksH3yHkFXfCI2Gcaqg7wGGHZZwunoJzEZk0yKYIokgre6hYVFibKL3SYAoR1kBXova8LB+JoO5vZzi9w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, "node_modules/@csstools/postcss-cascade-layers": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.1.tgz", - "integrity": "sha512-XOfhI7GShVcKiKwmPAnWSqd2tBR0uxt+runAxttbSp/LY2U16yAVPmAf7e9q4JJ0d+xMNmpwNDLBXnmRCl3HMQ==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.2.tgz", + "integrity": "sha512-nWBE08nhO8uWl6kSAeCx4im7QfVko3zLrtgWZY4/bP87zrSPpSyN/3W3TDqz1jJuH+kbKOHXg5rJnK+ZVYcFFg==", "funding": [ { "type": "github", @@ -2522,9 +2329,9 @@ } }, "node_modules/@csstools/postcss-color-function": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-4.0.10.tgz", - "integrity": "sha512-4dY0NBu7NVIpzxZRgh/Q/0GPSz/jLSw0i/u3LTUor0BkQcz/fNhN10mSWBDsL0p9nDb0Ky1PD6/dcGbhACuFTQ==", + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-4.0.12.tgz", + "integrity": "sha512-yx3cljQKRaSBc2hfh8rMZFZzChaFgwmO2JfFgFr1vMcF3C/uyy5I4RFIBOIWGq1D+XbKCG789CGkG6zzkLpagA==", "funding": [ { "type": "github", @@ -2537,10 +2344,10 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/css-color-parser": "^3.0.10", + "@csstools/css-color-parser": "^3.1.0", "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", "@csstools/utilities": "^2.0.0" }, "engines": { @@ -2550,10 +2357,10 @@ "postcss": "^8.4" } }, - "node_modules/@csstools/postcss-color-mix-function": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.10.tgz", - "integrity": "sha512-P0lIbQW9I4ShE7uBgZRib/lMTf9XMjJkFl/d6w4EMNHu2qvQ6zljJGEcBkw/NsBtq/6q3WrmgxSS8kHtPMkK4Q==", + "node_modules/@csstools/postcss-color-function-display-p3-linear": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function-display-p3-linear/-/postcss-color-function-display-p3-linear-1.0.1.tgz", + "integrity": "sha512-E5qusdzhlmO1TztYzDIi8XPdPoYOjoTY6HBYBCYSj+Gn4gQRBlvjgPQXzfzuPQqt8EhkC/SzPKObg4Mbn8/xMg==", "funding": [ { "type": "github", @@ -2566,10 +2373,10 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/css-color-parser": "^3.0.10", + "@csstools/css-color-parser": "^3.1.0", "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", "@csstools/utilities": "^2.0.0" }, "engines": { @@ -2579,10 +2386,10 @@ "postcss": "^8.4" } }, - "node_modules/@csstools/postcss-color-mix-variadic-function-arguments": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-variadic-function-arguments/-/postcss-color-mix-variadic-function-arguments-1.0.0.tgz", - "integrity": "sha512-Z5WhouTyD74dPFPrVE7KydgNS9VvnjB8qcdes9ARpCOItb4jTnm7cHp4FhxCRUoyhabD0WVv43wbkJ4p8hLAlQ==", + "node_modules/@csstools/postcss-color-mix-function": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.12.tgz", + "integrity": "sha512-4STERZfCP5Jcs13P1U5pTvI9SkgLgfMUMhdXW8IlJWkzOOOqhZIjcNhWtNJZes2nkBDsIKJ0CJtFtuaZ00moag==", "funding": [ { "type": "github", @@ -2595,10 +2402,10 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/css-color-parser": "^3.0.10", + "@csstools/css-color-parser": "^3.1.0", "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", "@csstools/utilities": "^2.0.0" }, "engines": { @@ -2608,10 +2415,10 @@ "postcss": "^8.4" } }, - "node_modules/@csstools/postcss-content-alt-text": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-2.0.6.tgz", - "integrity": "sha512-eRjLbOjblXq+byyaedQRSrAejKGNAFued+LcbzT+LCL78fabxHkxYjBbxkroONxHHYu2qxhFK2dBStTLPG3jpQ==", + "node_modules/@csstools/postcss-color-mix-variadic-function-arguments": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-variadic-function-arguments/-/postcss-color-mix-variadic-function-arguments-1.0.2.tgz", + "integrity": "sha512-rM67Gp9lRAkTo+X31DUqMEq+iK+EFqsidfecmhrteErxJZb6tUoJBVQca1Vn1GpDql1s1rD1pKcuYzMsg7Z1KQ==", "funding": [ { "type": "github", @@ -2624,9 +2431,10 @@ ], "license": "MIT-0", "dependencies": { + "@csstools/css-color-parser": "^3.1.0", "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", "@csstools/utilities": "^2.0.0" }, "engines": { @@ -2636,10 +2444,10 @@ "postcss": "^8.4" } }, - "node_modules/@csstools/postcss-exponential-functions": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-2.0.9.tgz", - "integrity": "sha512-abg2W/PI3HXwS/CZshSa79kNWNZHdJPMBXeZNyPQFbbj8sKO3jXxOt/wF7juJVjyDTc6JrvaUZYFcSBZBhaxjw==", + "node_modules/@csstools/postcss-content-alt-text": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-2.0.8.tgz", + "integrity": "sha512-9SfEW9QCxEpTlNMnpSqFaHyzsiRpZ5J5+KqCu1u5/eEJAWsMhzT40qf0FIbeeglEvrGRMdDzAxMIz3wqoGSb+Q==", "funding": [ { "type": "github", @@ -2652,9 +2460,10 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/css-calc": "^2.1.4", "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" }, "engines": { "node": ">=18" @@ -2663,10 +2472,10 @@ "postcss": "^8.4" } }, - "node_modules/@csstools/postcss-font-format-keywords": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-4.0.0.tgz", - "integrity": "sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw==", + "node_modules/@csstools/postcss-contrast-color-function": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-contrast-color-function/-/postcss-contrast-color-function-2.0.12.tgz", + "integrity": "sha512-YbwWckjK3qwKjeYz/CijgcS7WDUCtKTd8ShLztm3/i5dhh4NaqzsbYnhm4bjrpFpnLZ31jVcbK8YL77z3GBPzA==", "funding": [ { "type": "github", @@ -2679,8 +2488,11 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/utilities": "^2.0.0", - "postcss-value-parser": "^4.2.0" + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" }, "engines": { "node": ">=18" @@ -2689,10 +2501,10 @@ "postcss": "^8.4" } }, - "node_modules/@csstools/postcss-gamut-mapping": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.10.tgz", - "integrity": "sha512-QDGqhJlvFnDlaPAfCYPsnwVA6ze+8hhrwevYWlnUeSjkkZfBpcCO42SaUD8jiLlq7niouyLgvup5lh+f1qessg==", + "node_modules/@csstools/postcss-exponential-functions": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-2.0.9.tgz", + "integrity": "sha512-abg2W/PI3HXwS/CZshSa79kNWNZHdJPMBXeZNyPQFbbj8sKO3jXxOt/wF7juJVjyDTc6JrvaUZYFcSBZBhaxjw==", "funding": [ { "type": "github", @@ -2705,7 +2517,60 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/css-color-parser": "^3.0.10", + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-font-format-keywords": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-4.0.0.tgz", + "integrity": "sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-gamut-mapping": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.11.tgz", + "integrity": "sha512-fCpCUgZNE2piVJKC76zFsgVW1apF6dpYsqGyH8SIeCcM4pTEsRTWTLCaJIMKFEundsCKwY1rwfhtrio04RJ4Dw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4" }, @@ -2717,9 +2582,9 @@ } }, "node_modules/@csstools/postcss-gradients-interpolation-method": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.10.tgz", - "integrity": "sha512-HHPauB2k7Oits02tKFUeVFEU2ox/H3OQVrP3fSOKDxvloOikSal+3dzlyTZmYsb9FlY9p5EUpBtz0//XBmy+aw==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.12.tgz", + "integrity": "sha512-jugzjwkUY0wtNrZlFeyXzimUL3hN4xMvoPnIXxoZqxDvjZRiSh+itgHcVUWzJ2VwD/VAMEgCLvtaJHX+4Vj3Ow==", "funding": [ { "type": "github", @@ -2732,10 +2597,10 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/css-color-parser": "^3.0.10", + "@csstools/css-color-parser": "^3.1.0", "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", "@csstools/utilities": "^2.0.0" }, "engines": { @@ -2746,9 +2611,9 @@ } }, "node_modules/@csstools/postcss-hwb-function": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.10.tgz", - "integrity": "sha512-nOKKfp14SWcdEQ++S9/4TgRKchooLZL0TUFdun3nI4KPwCjETmhjta1QT4ICQcGVWQTvrsgMM/aLB5We+kMHhQ==", + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.12.tgz", + "integrity": "sha512-mL/+88Z53KrE4JdePYFJAQWFrcADEqsLprExCM04GDNgHIztwFzj0Mbhd/yxMBngq0NIlz58VVxjt5abNs1VhA==", "funding": [ { "type": "github", @@ -2761,10 +2626,10 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/css-color-parser": "^3.0.10", + "@csstools/css-color-parser": "^3.1.0", "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", "@csstools/utilities": "^2.0.0" }, "engines": { @@ -2775,9 +2640,9 @@ } }, "node_modules/@csstools/postcss-ic-unit": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-4.0.2.tgz", - "integrity": "sha512-lrK2jjyZwh7DbxaNnIUjkeDmU8Y6KyzRBk91ZkI5h8nb1ykEfZrtIVArdIjX4DHMIBGpdHrgP0n4qXDr7OHaKA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-4.0.4.tgz", + "integrity": "sha512-yQ4VmossuOAql65sCPppVO1yfb7hDscf4GseF0VCA/DTDaBc0Wtf8MTqVPfjGYlT5+2buokG0Gp7y0atYZpwjg==", "funding": [ { "type": "github", @@ -2790,7 +2655,7 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^4.1.0", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", "@csstools/utilities": "^2.0.0", "postcss-value-parser": "^4.2.0" }, @@ -2824,9 +2689,9 @@ } }, "node_modules/@csstools/postcss-is-pseudo-class": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-5.0.1.tgz", - "integrity": "sha512-JLp3POui4S1auhDR0n8wHd/zTOWmMsmK3nQd3hhL6FhWPaox5W7j1se6zXOG/aP07wV2ww0lxbKYGwbBszOtfQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-5.0.3.tgz", + "integrity": "sha512-jS/TY4SpG4gszAtIg7Qnf3AS2pjcUM5SzxpApOrlndMeGhIbaTzWBzzP/IApXoNWEW7OhcjkRT48jnAUIFXhAQ==", "funding": [ { "type": "github", @@ -2885,9 +2750,9 @@ } }, "node_modules/@csstools/postcss-light-dark-function": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.9.tgz", - "integrity": "sha512-1tCZH5bla0EAkFAI2r0H33CDnIBeLUaJh1p+hvvsylJ4svsv2wOmJjJn+OXwUZLXef37GYbRIVKX+X+g6m+3CQ==", + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.11.tgz", + "integrity": "sha512-fNJcKXJdPM3Lyrbmgw2OBbaioU7yuKZtiXClf4sGdQttitijYlZMD5K7HrC/eF83VRWRrYq6OZ0Lx92leV2LFA==", "funding": [ { "type": "github", @@ -2902,7 +2767,7 @@ "dependencies": { "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", "@csstools/utilities": "^2.0.0" }, "engines": { @@ -3136,9 +3001,9 @@ } }, "node_modules/@csstools/postcss-oklab-function": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.10.tgz", - "integrity": "sha512-ZzZUTDd0fgNdhv8UUjGCtObPD8LYxMH+MJsW9xlZaWTV8Ppr4PtxlHYNMmF4vVWGl0T6f8tyWAKjoI6vePSgAg==", + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.12.tgz", + "integrity": "sha512-HhlSmnE1NKBhXsTnNGjxvhryKtO7tJd1w42DKOGFD6jSHtYOrsJTQDKPMwvOfrzUAk8t7GcpIfRyM7ssqHpFjg==", "funding": [ { "type": "github", @@ -3151,10 +3016,10 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/css-color-parser": "^3.0.10", + "@csstools/css-color-parser": "^3.1.0", "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", "@csstools/utilities": "^2.0.0" }, "engines": { @@ -3165,9 +3030,9 @@ } }, "node_modules/@csstools/postcss-progressive-custom-properties": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.1.0.tgz", - "integrity": "sha512-YrkI9dx8U4R8Sz2EJaoeD9fI7s7kmeEBfmO+UURNeL6lQI7VxF6sBE+rSqdCBn4onwqmxFdBU3lTwyYb/lCmxA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.2.1.tgz", + "integrity": "sha512-uPiiXf7IEKtUQXsxu6uWtOlRMXd2QWWy5fhxHDnPdXKCQckPP3E34ZgDoZ62r2iT+UOgWsSbM4NvHE5m3mAEdw==", "funding": [ { "type": "github", @@ -3217,9 +3082,9 @@ } }, "node_modules/@csstools/postcss-relative-color-syntax": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.10.tgz", - "integrity": "sha512-8+0kQbQGg9yYG8hv0dtEpOMLwB9M+P7PhacgIzVzJpixxV4Eq9AUQtQw8adMmAJU1RBBmIlpmtmm3XTRd/T00g==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.12.tgz", + "integrity": "sha512-0RLIeONxu/mtxRtf3o41Lq2ghLimw0w9ByLWnnEVuy89exmEEq8bynveBxNW3nyHqLAFEeNtVEmC1QK9MZ8Huw==", "funding": [ { "type": "github", @@ -3232,10 +3097,10 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/css-color-parser": "^3.0.10", + "@csstools/css-color-parser": "^3.1.0", "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", "@csstools/utilities": "^2.0.0" }, "engines": { @@ -3338,9 +3203,9 @@ } }, "node_modules/@csstools/postcss-text-decoration-shorthand": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-4.0.2.tgz", - "integrity": "sha512-8XvCRrFNseBSAGxeaVTaNijAu+FzUvjwFXtcrynmazGb/9WUdsPCpBX+mHEHShVRq47Gy4peYAoxYs8ltUnmzA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-4.0.3.tgz", + "integrity": "sha512-KSkGgZfx0kQjRIYnpsD7X2Om9BUXX/Kii77VBifQW9Ih929hK0KNjVngHDH0bFB9GmfWcR9vJYJJRvw/NQjkrA==", "funding": [ { "type": "github", @@ -3353,7 +3218,7 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/color-helpers": "^5.0.2", + "@csstools/color-helpers": "^5.1.0", "postcss-value-parser": "^4.2.0" }, "engines": { @@ -3443,21 +3308,24 @@ } }, "node_modules/@docsearch/css": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.9.0.tgz", - "integrity": "sha512-cQbnVbq0rrBwNAKegIac/t6a8nWoUAn8frnkLFW6YARaRmAQr5/Eoe6Ln2fqkUCZ40KpdrKbpSAmgrkviOxuWA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-4.2.0.tgz", + "integrity": "sha512-65KU9Fw5fGsPPPlgIghonMcndyx1bszzrDQYLfierN+Ha29yotMHzVS94bPkZS6On9LS8dE4qmW4P/fGjtCf/g==", "license": "MIT" }, "node_modules/@docsearch/react": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.9.0.tgz", - "integrity": "sha512-mb5FOZYZIkRQ6s/NWnM98k879vu5pscWqTLubLFBO87igYYT4VzVazh4h5o/zCvTIZgEt3PvsCOMOswOUo9yHQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-4.2.0.tgz", + "integrity": "sha512-zSN/KblmtBcerf7Z87yuKIHZQmxuXvYc6/m0+qnjyNu+Ir67AVOagTa1zBqcxkVUVkmBqUExdcyrdo9hbGbqTw==", "license": "MIT", "dependencies": { - "@algolia/autocomplete-core": "1.17.9", - "@algolia/autocomplete-preset-algolia": "1.17.9", - "@docsearch/css": "3.9.0", - "algoliasearch": "^5.14.2" + "@ai-sdk/react": "^2.0.30", + "@algolia/autocomplete-core": "1.19.2", + "@docsearch/css": "4.2.0", + "ai": "^5.0.30", + "algoliasearch": "^5.28.0", + "marked": "^16.3.0", + "zod": "^4.1.8" }, "peerDependencies": { "@types/react": ">= 16.8.0 < 20.0.0", @@ -3480,157 +3348,10 @@ } } }, - "node_modules/@docsearch/react/node_modules/@algolia/autocomplete-core": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.9.tgz", - "integrity": "sha512-O7BxrpLDPJWWHv/DLA9DRFWs+iY1uOJZkqUwjS5HSZAGcl0hIVCQ97LTLewiZmZ402JYUrun+8NqFP+hCknlbQ==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.17.9", - "@algolia/autocomplete-shared": "1.17.9" - } - }, - "node_modules/@docsearch/react/node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.9.tgz", - "integrity": "sha512-u1fEHkCbWF92DBeB/KHeMacsjsoI0wFhjZtlCq2ddZbAehshbZST6Hs0Avkc0s+4UyBGbMDnSuXHLuvRWK5iDQ==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-shared": "1.17.9" - }, - "peerDependencies": { - "search-insights": ">= 1 < 3" - } - }, - "node_modules/@docsearch/react/node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.9.tgz", - "integrity": "sha512-Na1OuceSJeg8j7ZWn5ssMu/Ax3amtOwk76u4h5J4eK2Nx2KB5qt0Z4cOapCsxot9VcEN11ADV5aUSlQF4RhGjQ==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-shared": "1.17.9" - }, - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@docsearch/react/node_modules/@algolia/autocomplete-shared": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.9.tgz", - "integrity": "sha512-iDf05JDQ7I0b7JEA/9IektxN/80a2MZ1ToohfmNS3rfeuQnIKI3IJlIafD0xu4StbtQTghx9T3Maa97ytkXenQ==", - "license": "MIT", - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@docsearch/react/node_modules/@algolia/client-analytics": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.27.0.tgz", - "integrity": "sha512-go1b9qIZK5vYEQ7jD2bsfhhhVsoh9cFxQ5xF8TzTsg2WOCZR3O92oXCkq15SOK0ngJfqDU6a/k0oZ4KuEnih1Q==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@docsearch/react/node_modules/@algolia/client-common": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.27.0.tgz", - "integrity": "sha512-tnFOzdNuMzsz93kOClj3fKfuYoF3oYaEB5bggULSj075GJ7HUNedBEm7a6ScrjtnOaOtipbnT7veUpHA4o4wEQ==", - "license": "MIT", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@docsearch/react/node_modules/@algolia/client-personalization": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.27.0.tgz", - "integrity": "sha512-XluG9qPZKEbiLoIfXTKbABsWDNOMPx0t6T2ImJTTeuX+U/zBdmfcqqgcgkqXp+vbXof/XX/4of9Eqo1JaqEmKw==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@docsearch/react/node_modules/@algolia/client-search": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.27.0.tgz", - "integrity": "sha512-EJJ7WmvmUXZdchueKFCK8UZFyLqy4Hz64snNp0cTc7c0MKaSeDGYEDxVsIJKp15r7ORaoGxSyS4y6BGZMXYuCg==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@docsearch/react/node_modules/@algolia/requester-browser-xhr": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.27.0.tgz", - "integrity": "sha512-ErenYTcXl16wYXtf0pxLl9KLVxIztuehqXHfW9nNsD8mz9OX42HbXuPzT7y6JcPiWJpc/UU/LY5wBTB65vsEUg==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@docsearch/react/node_modules/@algolia/requester-node-http": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.27.0.tgz", - "integrity": "sha512-Nx9EdLYZDsaYFTthqmc0XcVvsx6jqeEX8fNiYOB5i2HboQwl8pJPj1jFhGqoGd0KG7KFR+sdPO5/e0EDDAru2Q==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@docsearch/react/node_modules/algoliasearch": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.27.0.tgz", - "integrity": "sha512-2PvAgvxxJzA3+dB+ERfS2JPdvUsxNf89Cc2GF5iCcFupTULOwmbfinvqrC4Qj9nHJJDNf494NqEN/1f9177ZTQ==", - "license": "MIT", - "dependencies": { - "@algolia/client-abtesting": "5.27.0", - "@algolia/client-analytics": "5.27.0", - "@algolia/client-common": "5.27.0", - "@algolia/client-insights": "5.27.0", - "@algolia/client-personalization": "5.27.0", - "@algolia/client-query-suggestions": "5.27.0", - "@algolia/client-search": "5.27.0", - "@algolia/ingestion": "1.27.0", - "@algolia/monitoring": "1.27.0", - "@algolia/recommend": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, "node_modules/@docusaurus/babel": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.8.1.tgz", - "integrity": "sha512-3brkJrml8vUbn9aeoZUlJfsI/GqyFcDgQJwQkmBtclJgWDEQBKKeagZfOgx0WfUQhagL1sQLNW0iBdxnI863Uw==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.9.2.tgz", + "integrity": "sha512-GEANdi/SgER+L7Japs25YiGil/AUDnFFHaCGPBbundxoWtCkA2lmy7/tFmgED4y1htAy6Oi4wkJEQdGssnw9MA==", "license": "MIT", "dependencies": { "@babel/core": "^7.25.9", @@ -3643,28 +3364,28 @@ "@babel/runtime": "^7.25.9", "@babel/runtime-corejs3": "^7.25.9", "@babel/traverse": "^7.25.9", - "@docusaurus/logger": "3.8.1", - "@docusaurus/utils": "3.8.1", + "@docusaurus/logger": "3.9.2", + "@docusaurus/utils": "3.9.2", "babel-plugin-dynamic-import-node": "^2.3.3", "fs-extra": "^11.1.1", "tslib": "^2.6.0" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" } }, "node_modules/@docusaurus/bundler": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.8.1.tgz", - "integrity": "sha512-/z4V0FRoQ0GuSLToNjOSGsk6m2lQUG4FRn8goOVoZSRsTrU8YR2aJacX5K3RG18EaX9b+52pN4m1sL3MQZVsQA==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.9.2.tgz", + "integrity": "sha512-ZOVi6GYgTcsZcUzjblpzk3wH1Fya2VNpd5jtHoCCFcJlMQ1EYXZetfAnRHLcyiFeBABaI1ltTYbOBtH/gahGVA==", "license": "MIT", "dependencies": { "@babel/core": "^7.25.9", - "@docusaurus/babel": "3.8.1", - "@docusaurus/cssnano-preset": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", + "@docusaurus/babel": "3.9.2", + "@docusaurus/cssnano-preset": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", "babel-loader": "^9.2.1", "clean-css": "^5.3.3", "copy-webpack-plugin": "^11.0.0", @@ -3685,7 +3406,7 @@ "webpackbar": "^6.0.1" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { "@docusaurus/faster": "*" @@ -3697,18 +3418,18 @@ } }, "node_modules/@docusaurus/core": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.8.1.tgz", - "integrity": "sha512-ENB01IyQSqI2FLtOzqSI3qxG2B/jP4gQPahl2C3XReiLebcVh5B5cB9KYFvdoOqOWPyr5gXK4sjgTKv7peXCrA==", - "license": "MIT", - "dependencies": { - "@docusaurus/babel": "3.8.1", - "@docusaurus/bundler": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.9.2.tgz", + "integrity": "sha512-HbjwKeC+pHUFBfLMNzuSjqFE/58+rLVKmOU3lxQrpsxLBOGosYco/Q0GduBb0/jEMRiyEqjNT/01rRdOMWq5pw==", + "license": "MIT", + "dependencies": { + "@docusaurus/babel": "3.9.2", + "@docusaurus/bundler": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", "boxen": "^6.2.1", "chalk": "^4.1.2", "chokidar": "^3.5.3", @@ -3742,14 +3463,14 @@ "update-notifier": "^6.0.2", "webpack": "^5.95.0", "webpack-bundle-analyzer": "^4.10.2", - "webpack-dev-server": "^4.15.2", + "webpack-dev-server": "^5.2.2", "webpack-merge": "^6.0.1" }, "bin": { "docusaurus": "bin/docusaurus.mjs" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { "@mdx-js/react": "^3.0.0", @@ -3758,9 +3479,9 @@ } }, "node_modules/@docusaurus/cssnano-preset": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.8.1.tgz", - "integrity": "sha512-G7WyR2N6SpyUotqhGznERBK+x84uyhfMQM2MmDLs88bw4Flom6TY46HzkRkSEzaP9j80MbTN8naiL1fR17WQug==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.9.2.tgz", + "integrity": "sha512-8gBKup94aGttRduABsj7bpPFTX7kbwu+xh3K9NMCF5K4bWBqTFYW+REKHF6iBVDHRJ4grZdIPbvkiHd/XNKRMQ==", "license": "MIT", "dependencies": { "cssnano-preset-advanced": "^6.1.2", @@ -3769,31 +3490,31 @@ "tslib": "^2.6.0" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" } }, "node_modules/@docusaurus/logger": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.8.1.tgz", - "integrity": "sha512-2wjeGDhKcExEmjX8k1N/MRDiPKXGF2Pg+df/bDDPnnJWHXnVEZxXj80d6jcxp1Gpnksl0hF8t/ZQw9elqj2+ww==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.9.2.tgz", + "integrity": "sha512-/SVCc57ByARzGSU60c50rMyQlBuMIJCjcsJlkphxY6B0GV4UH3tcA1994N8fFfbJ9kX3jIBe/xg3XP5qBtGDbA==", "license": "MIT", "dependencies": { "chalk": "^4.1.2", "tslib": "^2.6.0" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" } }, "node_modules/@docusaurus/mdx-loader": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.8.1.tgz", - "integrity": "sha512-DZRhagSFRcEq1cUtBMo4TKxSNo/W6/s44yhr8X+eoXqCLycFQUylebOMPseHi5tc4fkGJqwqpWJLz6JStU9L4w==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.9.2.tgz", + "integrity": "sha512-wiYoGwF9gdd6rev62xDU8AAM8JuLI/hlwOtCzMmYcspEkzecKrP8J8X+KpYnTlACBUUtXNJpSoCwFWJhLRevzQ==", "license": "MIT", "dependencies": { - "@docusaurus/logger": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", + "@docusaurus/logger": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", "@mdx-js/mdx": "^3.0.0", "@slorber/remark-comment": "^1.0.0", "escape-html": "^1.0.3", @@ -3817,7 +3538,7 @@ "webpack": "^5.88.1" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", @@ -3825,12 +3546,12 @@ } }, "node_modules/@docusaurus/module-type-aliases": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.8.1.tgz", - "integrity": "sha512-6xhvAJiXzsaq3JdosS7wbRt/PwEPWHr9eM4YNYqVlbgG1hSK3uQDXTVvQktasp3VO6BmfYWPozueLWuj4gB+vg==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.9.2.tgz", + "integrity": "sha512-8qVe2QA9hVLzvnxP46ysuofJUIc/yYQ82tvA/rBTrnpXtCjNSFLxEZfd5U8cYZuJIVlkPxamsIgwd5tGZXfvew==", "license": "MIT", "dependencies": { - "@docusaurus/types": "3.8.1", + "@docusaurus/types": "3.9.2", "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router-config": "*", @@ -3844,19 +3565,19 @@ } }, "node_modules/@docusaurus/plugin-content-blog": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.8.1.tgz", - "integrity": "sha512-vNTpMmlvNP9n3hGEcgPaXyvTljanAKIUkuG9URQ1DeuDup0OR7Ltvoc8yrmH+iMZJbcQGhUJF+WjHLwuk8HSdw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/theme-common": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.9.2.tgz", + "integrity": "sha512-3I2HXy3L1QcjLJLGAoTvoBnpOwa6DPUa3Q0dMK19UTY9mhPkKQg/DYhAGTiBUKcTR0f08iw7kLPqOhIgdV3eVQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", "cheerio": "1.0.0-rc.12", "feed": "^4.2.2", "fs-extra": "^11.1.1", @@ -3869,7 +3590,7 @@ "webpack": "^5.88.1" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { "@docusaurus/plugin-content-docs": "*", @@ -3878,20 +3599,20 @@ } }, "node_modules/@docusaurus/plugin-content-docs": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.8.1.tgz", - "integrity": "sha512-oByRkSZzeGNQByCMaX+kif5Nl2vmtj2IHQI2fWjCfCootsdKZDPFLonhIp5s3IGJO7PLUfe0POyw0Xh/RrGXJA==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/module-type-aliases": "3.8.1", - "@docusaurus/theme-common": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.9.2.tgz", + "integrity": "sha512-C5wZsGuKTY8jEYsqdxhhFOe1ZDjH0uIYJ9T/jebHwkyxqnr4wW0jTkB72OMqNjsoQRcb0JN3PcSeTwFlVgzCZg==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", "@types/react-router-config": "^5.0.7", "combine-promises": "^1.1.0", "fs-extra": "^11.1.1", @@ -3903,7 +3624,7 @@ "webpack": "^5.88.1" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", @@ -3911,22 +3632,22 @@ } }, "node_modules/@docusaurus/plugin-content-pages": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.8.1.tgz", - "integrity": "sha512-a+V6MS2cIu37E/m7nDJn3dcxpvXb6TvgdNI22vJX8iUTp8eoMoPa0VArEbWvCxMY/xdC26WzNv4wZ6y0iIni/w==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.9.2.tgz", + "integrity": "sha512-s4849w/p4noXUrGpPUF0BPqIAfdAe76BLaRGAGKZ1gTDNiGxGcpsLcwJ9OTi1/V8A+AzvsmI9pkjie2zjIQZKA==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", + "@docusaurus/core": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", "fs-extra": "^11.1.1", "tslib": "^2.6.0", "webpack": "^5.88.1" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", @@ -3934,36 +3655,36 @@ } }, "node_modules/@docusaurus/plugin-css-cascade-layers": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.8.1.tgz", - "integrity": "sha512-VQ47xRxfNKjHS5ItzaVXpxeTm7/wJLFMOPo1BkmoMG4Cuz4nuI+Hs62+RMk1OqVog68Swz66xVPK8g9XTrBKRw==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.9.2.tgz", + "integrity": "sha512-w1s3+Ss+eOQbscGM4cfIFBlVg/QKxyYgj26k5AnakuHkKxH6004ZtuLe5awMBotIYF2bbGDoDhpgQ4r/kcj4rQ==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", "tslib": "^2.6.0" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" } }, "node_modules/@docusaurus/plugin-debug": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.8.1.tgz", - "integrity": "sha512-nT3lN7TV5bi5hKMB7FK8gCffFTBSsBsAfV84/v293qAmnHOyg1nr9okEw8AiwcO3bl9vije5nsUvP0aRl2lpaw==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.9.2.tgz", + "integrity": "sha512-j7a5hWuAFxyQAkilZwhsQ/b3T7FfHZ+0dub6j/GxKNFJp2h9qk/P1Bp7vrGASnvA9KNQBBL1ZXTe7jlh4VdPdA==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", "fs-extra": "^11.1.1", "react-json-view-lite": "^2.3.0", "tslib": "^2.6.0" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", @@ -3971,18 +3692,18 @@ } }, "node_modules/@docusaurus/plugin-google-analytics": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.8.1.tgz", - "integrity": "sha512-Hrb/PurOJsmwHAsfMDH6oVpahkEGsx7F8CWMjyP/dw1qjqmdS9rcV1nYCGlM8nOtD3Wk/eaThzUB5TSZsGz+7Q==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.9.2.tgz", + "integrity": "sha512-mAwwQJ1Us9jL/lVjXtErXto4p4/iaLlweC54yDUK1a97WfkC6Z2k5/769JsFgwOwOP+n5mUQGACXOEQ0XDuVUw==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", "tslib": "^2.6.0" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", @@ -3990,19 +3711,19 @@ } }, "node_modules/@docusaurus/plugin-google-gtag": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.8.1.tgz", - "integrity": "sha512-tKE8j1cEZCh8KZa4aa80zpSTxsC2/ZYqjx6AAfd8uA8VHZVw79+7OTEP2PoWi0uL5/1Is0LF5Vwxd+1fz5HlKg==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.9.2.tgz", + "integrity": "sha512-YJ4lDCphabBtw19ooSlc1MnxtYGpjFV9rEdzjLsUnBCeis2djUyCozZaFhCg6NGEwOn7HDDyMh0yzcdRpnuIvA==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", "@types/gtag.js": "^0.0.12", "tslib": "^2.6.0" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", @@ -4010,18 +3731,18 @@ } }, "node_modules/@docusaurus/plugin-google-tag-manager": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.8.1.tgz", - "integrity": "sha512-iqe3XKITBquZq+6UAXdb1vI0fPY5iIOitVjPQ581R1ZKpHr0qe+V6gVOrrcOHixPDD/BUKdYwkxFjpNiEN+vBw==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.9.2.tgz", + "integrity": "sha512-LJtIrkZN/tuHD8NqDAW1Tnw0ekOwRTfobWPsdO15YxcicBo2ykKF0/D6n0vVBfd3srwr9Z6rzrIWYrMzBGrvNw==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", "tslib": "^2.6.0" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", @@ -4029,23 +3750,23 @@ } }, "node_modules/@docusaurus/plugin-sitemap": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.8.1.tgz", - "integrity": "sha512-+9YV/7VLbGTq8qNkjiugIelmfUEVkTyLe6X8bWq7K5qPvGXAjno27QAfFq63mYfFFbJc7z+pudL63acprbqGzw==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.9.2.tgz", + "integrity": "sha512-WLh7ymgDXjG8oPoM/T4/zUP7KcSuFYRZAUTl8vR6VzYkfc18GBM4xLhcT+AKOwun6kBivYKUJf+vlqYJkm+RHw==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", "fs-extra": "^11.1.1", "sitemap": "^7.1.1", "tslib": "^2.6.0" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", @@ -4053,22 +3774,22 @@ } }, "node_modules/@docusaurus/plugin-svgr": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-svgr/-/plugin-svgr-3.8.1.tgz", - "integrity": "sha512-rW0LWMDsdlsgowVwqiMb/7tANDodpy1wWPwCcamvhY7OECReN3feoFwLjd/U4tKjNY3encj0AJSTxJA+Fpe+Gw==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-svgr/-/plugin-svgr-3.9.2.tgz", + "integrity": "sha512-n+1DE+5b3Lnf27TgVU5jM1d4x5tUh2oW5LTsBxJX4PsAPV0JGcmI6p3yLYtEY0LRVEIJh+8RsdQmRE66wSV8mw==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", "@svgr/core": "8.1.0", "@svgr/webpack": "^8.1.0", "tslib": "^2.6.0", "webpack": "^5.88.1" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", @@ -4076,29 +3797,29 @@ } }, "node_modules/@docusaurus/preset-classic": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.8.1.tgz", - "integrity": "sha512-yJSjYNHXD8POMGc2mKQuj3ApPrN+eG0rO1UPgSx7jySpYU+n4WjBikbrA2ue5ad9A7aouEtMWUoiSRXTH/g7KQ==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/plugin-content-blog": "3.8.1", - "@docusaurus/plugin-content-docs": "3.8.1", - "@docusaurus/plugin-content-pages": "3.8.1", - "@docusaurus/plugin-css-cascade-layers": "3.8.1", - "@docusaurus/plugin-debug": "3.8.1", - "@docusaurus/plugin-google-analytics": "3.8.1", - "@docusaurus/plugin-google-gtag": "3.8.1", - "@docusaurus/plugin-google-tag-manager": "3.8.1", - "@docusaurus/plugin-sitemap": "3.8.1", - "@docusaurus/plugin-svgr": "3.8.1", - "@docusaurus/theme-classic": "3.8.1", - "@docusaurus/theme-common": "3.8.1", - "@docusaurus/theme-search-algolia": "3.8.1", - "@docusaurus/types": "3.8.1" + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.9.2.tgz", + "integrity": "sha512-IgyYO2Gvaigi21LuDIe+nvmN/dfGXAiMcV/murFqcpjnZc7jxFAxW+9LEjdPt61uZLxG4ByW/oUmX/DDK9t/8w==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/plugin-content-blog": "3.9.2", + "@docusaurus/plugin-content-docs": "3.9.2", + "@docusaurus/plugin-content-pages": "3.9.2", + "@docusaurus/plugin-css-cascade-layers": "3.9.2", + "@docusaurus/plugin-debug": "3.9.2", + "@docusaurus/plugin-google-analytics": "3.9.2", + "@docusaurus/plugin-google-gtag": "3.9.2", + "@docusaurus/plugin-google-tag-manager": "3.9.2", + "@docusaurus/plugin-sitemap": "3.9.2", + "@docusaurus/plugin-svgr": "3.9.2", + "@docusaurus/theme-classic": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/theme-search-algolia": "3.9.2", + "@docusaurus/types": "3.9.2" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", @@ -4106,27 +3827,26 @@ } }, "node_modules/@docusaurus/theme-classic": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.8.1.tgz", - "integrity": "sha512-bqDUCNqXeYypMCsE1VcTXSI1QuO4KXfx8Cvl6rYfY0bhhqN6d2WZlRkyLg/p6pm+DzvanqHOyYlqdPyP0iz+iw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/module-type-aliases": "3.8.1", - "@docusaurus/plugin-content-blog": "3.8.1", - "@docusaurus/plugin-content-docs": "3.8.1", - "@docusaurus/plugin-content-pages": "3.8.1", - "@docusaurus/theme-common": "3.8.1", - "@docusaurus/theme-translations": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.9.2.tgz", + "integrity": "sha512-IGUsArG5hhekXd7RDb11v94ycpJpFdJPkLnt10fFQWOVxAtq5/D7hT6lzc2fhyQKaaCE62qVajOMKL7OiAFAIA==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/plugin-content-blog": "3.9.2", + "@docusaurus/plugin-content-docs": "3.9.2", + "@docusaurus/plugin-content-pages": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/theme-translations": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", - "copy-text-to-clipboard": "^3.2.0", "infima": "0.2.0-alpha.45", "lodash": "^4.17.21", "nprogress": "^0.2.0", @@ -4139,7 +3859,7 @@ "utility-types": "^3.10.0" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", @@ -4147,15 +3867,15 @@ } }, "node_modules/@docusaurus/theme-common": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.8.1.tgz", - "integrity": "sha512-UswMOyTnPEVRvN5Qzbo+l8k4xrd5fTFu2VPPfD6FcW/6qUtVLmJTQCktbAL3KJ0BVXGm5aJXz/ZrzqFuZERGPw==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.9.2.tgz", + "integrity": "sha512-6c4DAbR6n6nPbnZhY2V3tzpnKnGL+6aOsLvFL26VRqhlczli9eWG0VDUNoCQEPnGwDMhPS42UhSAnz5pThm5Ag==", "license": "MIT", "dependencies": { - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/module-type-aliases": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router-config": "*", @@ -4166,7 +3886,7 @@ "utility-types": "^3.10.0" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { "@docusaurus/plugin-content-docs": "*", @@ -4175,15 +3895,15 @@ } }, "node_modules/@docusaurus/theme-live-codeblock": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-live-codeblock/-/theme-live-codeblock-3.8.1.tgz", - "integrity": "sha512-TuCdnbJdTCAR4xv/dEU9m299/+hr+DrxQnQyK1mAmxnvWM/KrfaWdKMfjJ9h4hHa54ctPGm6ykdTvZic0GWdIw==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-live-codeblock/-/theme-live-codeblock-3.9.2.tgz", + "integrity": "sha512-cgxxZh18dI5Q4iV0GLmwqXtgZbTLOnb0TYgZRiUh0mnIGbuNWFUhUYXXl5owKbDfIXFdFAiI/owJKM83howEAw==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/theme-common": "3.8.1", - "@docusaurus/theme-translations": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", + "@docusaurus/core": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/theme-translations": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", "@philpl/buble": "^0.19.7", "clsx": "^2.0.0", "fs-extra": "^11.1.1", @@ -4191,7 +3911,7 @@ "tslib": "^2.6.0" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", @@ -4199,21 +3919,21 @@ } }, "node_modules/@docusaurus/theme-search-algolia": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.8.1.tgz", - "integrity": "sha512-NBFH5rZVQRAQM087aYSRKQ9yGEK9eHd+xOxQjqNpxMiV85OhJDD4ZGz6YJIod26Fbooy54UWVdzNU0TFeUUUzQ==", - "license": "MIT", - "dependencies": { - "@docsearch/react": "^3.9.0", - "@docusaurus/core": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/plugin-content-docs": "3.8.1", - "@docusaurus/theme-common": "3.8.1", - "@docusaurus/theme-translations": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "algoliasearch": "^5.17.1", - "algoliasearch-helper": "^3.22.6", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.9.2.tgz", + "integrity": "sha512-GBDSFNwjnh5/LdkxCKQHkgO2pIMX1447BxYUBG2wBiajS21uj64a+gH/qlbQjDLxmGrbrllBrtJkUHxIsiwRnw==", + "license": "MIT", + "dependencies": { + "@docsearch/react": "^3.9.0 || ^4.1.0", + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/plugin-content-docs": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/theme-translations": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "algoliasearch": "^5.37.0", + "algoliasearch-helper": "^3.26.0", "clsx": "^2.0.0", "eta": "^2.2.0", "fs-extra": "^11.1.1", @@ -4222,143 +3942,42 @@ "utility-types": "^3.10.0" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" } }, - "node_modules/@docusaurus/theme-search-algolia/node_modules/@algolia/client-analytics": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.27.0.tgz", - "integrity": "sha512-go1b9qIZK5vYEQ7jD2bsfhhhVsoh9cFxQ5xF8TzTsg2WOCZR3O92oXCkq15SOK0ngJfqDU6a/k0oZ4KuEnih1Q==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@docusaurus/theme-search-algolia/node_modules/@algolia/client-common": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.27.0.tgz", - "integrity": "sha512-tnFOzdNuMzsz93kOClj3fKfuYoF3oYaEB5bggULSj075GJ7HUNedBEm7a6ScrjtnOaOtipbnT7veUpHA4o4wEQ==", - "license": "MIT", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@docusaurus/theme-search-algolia/node_modules/@algolia/client-personalization": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.27.0.tgz", - "integrity": "sha512-XluG9qPZKEbiLoIfXTKbABsWDNOMPx0t6T2ImJTTeuX+U/zBdmfcqqgcgkqXp+vbXof/XX/4of9Eqo1JaqEmKw==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@docusaurus/theme-search-algolia/node_modules/@algolia/client-search": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.27.0.tgz", - "integrity": "sha512-EJJ7WmvmUXZdchueKFCK8UZFyLqy4Hz64snNp0cTc7c0MKaSeDGYEDxVsIJKp15r7ORaoGxSyS4y6BGZMXYuCg==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@docusaurus/theme-search-algolia/node_modules/@algolia/requester-browser-xhr": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.27.0.tgz", - "integrity": "sha512-ErenYTcXl16wYXtf0pxLl9KLVxIztuehqXHfW9nNsD8mz9OX42HbXuPzT7y6JcPiWJpc/UU/LY5wBTB65vsEUg==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@docusaurus/theme-search-algolia/node_modules/@algolia/requester-node-http": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.27.0.tgz", - "integrity": "sha512-Nx9EdLYZDsaYFTthqmc0XcVvsx6jqeEX8fNiYOB5i2HboQwl8pJPj1jFhGqoGd0KG7KFR+sdPO5/e0EDDAru2Q==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@docusaurus/theme-search-algolia/node_modules/algoliasearch": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.27.0.tgz", - "integrity": "sha512-2PvAgvxxJzA3+dB+ERfS2JPdvUsxNf89Cc2GF5iCcFupTULOwmbfinvqrC4Qj9nHJJDNf494NqEN/1f9177ZTQ==", - "license": "MIT", - "dependencies": { - "@algolia/client-abtesting": "5.27.0", - "@algolia/client-analytics": "5.27.0", - "@algolia/client-common": "5.27.0", - "@algolia/client-insights": "5.27.0", - "@algolia/client-personalization": "5.27.0", - "@algolia/client-query-suggestions": "5.27.0", - "@algolia/client-search": "5.27.0", - "@algolia/ingestion": "1.27.0", - "@algolia/monitoring": "1.27.0", - "@algolia/recommend": "5.27.0", - "@algolia/requester-browser-xhr": "5.27.0", - "@algolia/requester-fetch": "5.27.0", - "@algolia/requester-node-http": "5.27.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, "node_modules/@docusaurus/theme-translations": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.8.1.tgz", - "integrity": "sha512-OTp6eebuMcf2rJt4bqnvuwmm3NVXfzfYejL+u/Y1qwKhZPrjPoKWfk1CbOP5xH5ZOPkiAsx4dHdQBRJszK3z2g==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.9.2.tgz", + "integrity": "sha512-vIryvpP18ON9T9rjgMRFLr2xJVDpw1rtagEGf8Ccce4CkTrvM/fRB8N2nyWYOW5u3DdjkwKw5fBa+3tbn9P4PA==", "license": "MIT", "dependencies": { "fs-extra": "^11.1.1", "tslib": "^2.6.0" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" } }, "node_modules/@docusaurus/tsconfig": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.8.1.tgz", - "integrity": "sha512-XBWCcqhRHhkhfolnSolNL+N7gj3HVE3CoZVqnVjfsMzCoOsuQw2iCLxVVHtO+rePUUfouVZHURDgmqIySsF66A==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.9.2.tgz", + "integrity": "sha512-j6/Fp4Rlpxsc632cnRnl5HpOWeb6ZKssDj6/XzzAzVGXXfm9Eptx3rxCC+fDzySn9fHTS+CWJjPineCR1bB5WQ==", "dev": true, "license": "MIT" }, "node_modules/@docusaurus/types": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.8.1.tgz", - "integrity": "sha512-ZPdW5AB+pBjiVrcLuw3dOS6BFlrG0XkS2lDGsj8TizcnREQg3J8cjsgfDviszOk4CweNfwo1AEELJkYaMUuOPg==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.9.2.tgz", + "integrity": "sha512-Ux1JUNswg+EfUEmajJjyhIohKceitY/yzjRUpu04WXgvVz+fbhVC0p+R0JhvEu4ytw8zIAys2hrdpQPBHRIa8Q==", "license": "MIT", "dependencies": { "@mdx-js/mdx": "^3.0.0", "@types/history": "^4.7.11", + "@types/mdast": "^4.0.2", "@types/react": "*", "commander": "^5.1.0", "joi": "^17.9.2", @@ -4386,14 +4005,14 @@ } }, "node_modules/@docusaurus/utils": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.8.1.tgz", - "integrity": "sha512-P1ml0nvOmEFdmu0smSXOqTS1sxU5tqvnc0dA4MTKV39kye+bhQnjkIKEE18fNOvxjyB86k8esoCIFM3x4RykOQ==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.9.2.tgz", + "integrity": "sha512-lBSBiRruFurFKXr5Hbsl2thmGweAPmddhF3jb99U4EMDA5L+e5Y1rAkOS07Nvrup7HUMBDrCV45meaxZnt28nQ==", "license": "MIT", "dependencies": { - "@docusaurus/logger": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils-common": "3.8.1", + "@docusaurus/logger": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils-common": "3.9.2", "escape-string-regexp": "^4.0.0", "execa": "5.1.1", "file-loader": "^6.2.0", @@ -4414,31 +4033,31 @@ "webpack": "^5.88.1" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" } }, "node_modules/@docusaurus/utils-common": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.8.1.tgz", - "integrity": "sha512-zTZiDlvpvoJIrQEEd71c154DkcriBecm4z94OzEE9kz7ikS3J+iSlABhFXM45mZ0eN5pVqqr7cs60+ZlYLewtg==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.9.2.tgz", + "integrity": "sha512-I53UC1QctruA6SWLvbjbhCpAw7+X7PePoe5pYcwTOEXD/PxeP8LnECAhTHHwWCblyUX5bMi4QLRkxvyZ+IT8Aw==", "license": "MIT", "dependencies": { - "@docusaurus/types": "3.8.1", + "@docusaurus/types": "3.9.2", "tslib": "^2.6.0" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" } }, "node_modules/@docusaurus/utils-validation": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.8.1.tgz", - "integrity": "sha512-gs5bXIccxzEbyVecvxg6upTwaUbfa0KMmTj7HhHzc016AGyxH2o73k1/aOD0IFrdCsfJNt37MqNI47s2MgRZMA==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.9.2.tgz", + "integrity": "sha512-l7yk3X5VnNmATbwijJkexdhulNsQaNDwoagiwujXoxFbWLcxHQqNQ+c/IAlzrfMMOfa/8xSBZ7KEKDesE/2J7A==", "license": "MIT", "dependencies": { - "@docusaurus/logger": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", + "@docusaurus/logger": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", "fs-extra": "^11.2.0", "joi": "^17.9.2", "js-yaml": "^4.1.0", @@ -4446,7 +4065,7 @@ "tslib": "^2.6.0" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" } }, "node_modules/@hapi/hoek": { @@ -4464,6 +4083,27 @@ "@hapi/hoek": "^9.0.0" } }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz", + "integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==", + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -4589,10 +4229,124 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/buffers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.0.0.tgz", + "integrity": "sha512-NDigYR3PHqCnQLXYyoLbnEdzMMvzeiCWo1KOut7Q0CoIqg9tUAPKJ1iq/2nFhc5kZtexzutNY0LFjdwWL3Dw3Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/codegen": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz", + "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.14.0.tgz", + "integrity": "sha512-LpWbYgVnKzphN5S6uss4M25jJ/9+m6q6UJoeN6zTkK4xAGhKsiBRPVeF7OYMWonn5repMQbE5vieRXcMUrKDKw==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "^1.1.2", + "@jsonjoy.com/buffers": "^1.0.0", + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/json-pointer": "^1.0.1", + "@jsonjoy.com/util": "^1.9.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pointer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", + "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/util": "^1.9.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz", + "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^1.0.0", + "@jsonjoy.com/codegen": "^1.0.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==" + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "license": "MIT" }, "node_modules/@mdx-js/mdx": { "version": "3.1.0", @@ -4631,9 +4385,10 @@ } }, "node_modules/@mdx-js/react": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz", - "integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", + "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", + "license": "MIT", "dependencies": { "@types/mdx": "^2.0.0" }, @@ -4678,6 +4433,15 @@ "node": ">= 8" } }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/@parcel/watcher": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.0.tgz", @@ -5188,6 +4952,12 @@ "micromark-util-symbol": "^1.0.1" } }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "license": "MIT" + }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", @@ -5475,9 +5245,10 @@ } }, "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "license": "MIT", "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -5487,6 +5258,7 @@ "version": "3.5.13", "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -5495,6 +5267,7 @@ "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -5503,6 +5276,7 @@ "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "license": "MIT", "dependencies": { "@types/express-serve-static-core": "*", "@types/node": "*" @@ -5551,9 +5325,10 @@ } }, "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", + "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", + "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -5562,20 +5337,10 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.4.tgz", - "integrity": "sha512-5kz9ScmzBdzTgB/3susoCgfqNDzBjvLL4taparufgSvlwjdLy6UyUy9T/tCpYd2GIdIilCatC4iSQS0QSYHt0w==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/express/node_modules/@types/express-serve-static-core": { "version": "4.19.6", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -5614,14 +5379,16 @@ "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" }, "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "license": "MIT" }, "node_modules/@types/http-proxy": { - "version": "1.17.15", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", - "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", + "version": "1.17.16", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.16.tgz", + "integrity": "sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==", + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -5672,7 +5439,8 @@ "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" }, "node_modules/@types/ms": { "version": "0.7.34", @@ -5681,44 +5449,53 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.0.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.13.tgz", - "integrity": "sha512-Qm9OYVOFHFYg3wJoTSrz80hoec5Lia/dPp84do3X7dZvLikQvM1YpmvTBEdIr/e+U8HTkFjLHLnl78K/qjf+jQ==", + "version": "25.0.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.10.tgz", + "integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==", "license": "MIT", "dependencies": { - "undici-types": "~7.8.0" + "undici-types": "~7.16.0" } }, "node_modules/@types/node-forge": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", - "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "version": "1.3.14", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.14.tgz", + "integrity": "sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, + "node_modules/@types/parse5": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", + "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==", + "license": "MIT" + }, "node_modules/@types/prismjs": { "version": "1.26.3", "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.3.tgz", "integrity": "sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==" }, "node_modules/@types/qs": { - "version": "6.9.17", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", - "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==" + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "license": "MIT" }, "node_modules/@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" }, "node_modules/@types/react": { - "version": "19.1.8", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", - "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", + "version": "19.2.9", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.9.tgz", + "integrity": "sha512-Lpo8kgb/igvMIPeNV2rsYKTgaORYdO1XGVZ4Qz3akwOj0ySGYMPlQWa8BaLn0G63D1aSaAQ5ldR06wCpChQCjA==", "license": "MIT", "dependencies": { - "csstype": "^3.0.2" + "csstype": "^3.2.2" } }, "node_modules/@types/react-helmet": { @@ -5760,9 +5537,10 @@ } }, "node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "license": "MIT" }, "node_modules/@types/sax": { "version": "1.2.7", @@ -5774,9 +5552,10 @@ } }, "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "license": "MIT", "dependencies": { "@types/mime": "^1", "@types/node": "*" @@ -5786,14 +5565,16 @@ "version": "1.9.4", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "license": "MIT", "dependencies": { "@types/express": "*" } }, "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", + "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", + "license": "MIT", "dependencies": { "@types/http-errors": "*", "@types/node": "*", @@ -5804,6 +5585,7 @@ "version": "0.3.36", "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -5815,9 +5597,10 @@ "license": "MIT" }, "node_modules/@types/ws": { - "version": "8.5.13", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", - "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -5842,6 +5625,15 @@ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" }, + "node_modules/@vercel/oidc": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.0.3.tgz", + "integrity": "sha512-yNEQvPcVrK9sIe637+I0jD6leluPxzwJKx/Haw6F4H77CdDsszUn5V3o96LPziXkSNE2B83+Z3mjqGKBK/R6Gg==", + "license": "Apache-2.0", + "engines": { + "node": ">= 20" + } + }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", @@ -6000,10 +5792,17 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "license": "Apache-2.0" }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "license": "ISC" + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -6016,6 +5815,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -6024,6 +5824,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -6035,6 +5836,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -6121,6 +5923,24 @@ "node": ">=8" } }, + "node_modules/ai": { + "version": "5.0.76", + "resolved": "https://registry.npmjs.org/ai/-/ai-5.0.76.tgz", + "integrity": "sha512-ZCxi1vrpyCUnDbtYrO/W8GLvyacV9689f00yshTIQ3mFFphbD7eIv40a2AOZBv3GGRA7SSRYIDnr56wcS/gyQg==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/gateway": "2.0.0", + "@ai-sdk/provider": "2.0.0", + "@ai-sdk/provider-utils": "3.0.12", + "@opentelemetry/api": "1.9.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -6140,6 +5960,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", "dependencies": { "ajv": "^8.0.0" }, @@ -6156,6 +5977,7 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -6170,7 +5992,8 @@ "node_modules/ajv-formats/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/ajv-keywords": { "version": "3.5.2", @@ -6181,30 +6004,34 @@ } }, "node_modules/algoliasearch": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.20.0.tgz", - "integrity": "sha512-y+UHEjnOItoNy0bYO+WWmLWBlPwDjKHW6mNHrPi0NkuhpQOOEbrkwQH/wgKFDLh7qlKjzoKeiRtlpewDPDG23g==", - "dependencies": { - "@algolia/cache-browser-local-storage": "4.20.0", - "@algolia/cache-common": "4.20.0", - "@algolia/cache-in-memory": "4.20.0", - "@algolia/client-account": "4.20.0", - "@algolia/client-analytics": "4.20.0", - "@algolia/client-common": "4.20.0", - "@algolia/client-personalization": "4.20.0", - "@algolia/client-search": "4.20.0", - "@algolia/logger-common": "4.20.0", - "@algolia/logger-console": "4.20.0", - "@algolia/requester-browser-xhr": "4.20.0", - "@algolia/requester-common": "4.20.0", - "@algolia/requester-node-http": "4.20.0", - "@algolia/transporter": "4.20.0" + "version": "5.40.1", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.40.1.tgz", + "integrity": "sha512-iUNxcXUNg9085TJx0HJLjqtDE0r1RZ0GOGrt8KNQqQT5ugu8lZsHuMUYW/e0lHhq6xBvmktU9Bw4CXP9VQeKrg==", + "license": "MIT", + "dependencies": { + "@algolia/abtesting": "1.6.1", + "@algolia/client-abtesting": "5.40.1", + "@algolia/client-analytics": "5.40.1", + "@algolia/client-common": "5.40.1", + "@algolia/client-insights": "5.40.1", + "@algolia/client-personalization": "5.40.1", + "@algolia/client-query-suggestions": "5.40.1", + "@algolia/client-search": "5.40.1", + "@algolia/ingestion": "1.40.1", + "@algolia/monitoring": "1.40.1", + "@algolia/recommend": "5.40.1", + "@algolia/requester-browser-xhr": "5.40.1", + "@algolia/requester-fetch": "5.40.1", + "@algolia/requester-node-http": "5.40.1" + }, + "engines": { + "node": ">= 14.0.0" } }, "node_modules/algoliasearch-helper": { - "version": "3.25.0", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.25.0.tgz", - "integrity": "sha512-vQoK43U6HXA9/euCqLjvyNdM4G2Fiu/VFp4ae0Gau9sZeIKBPvUPnXfLYAe65Bg7PFuw03coeu5K6lTPSXRObw==", + "version": "3.26.0", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.26.0.tgz", + "integrity": "sha512-Rv2x3GXleQ3ygwhkhJubhhYGsICmShLAiqtUuJTUkr9uOCOXyF2E71LVT4XDnVffbknv8XgScP4U0Oxtgm+hIw==", "license": "MIT", "dependencies": { "@algolia/events": "^4.0.1" @@ -6273,6 +6100,7 @@ "engines": [ "node >= 0.8.0" ], + "license": "Apache-2.0", "bin": { "ansi-html": "bin/ansi-html" } @@ -6308,6 +6136,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -6316,6 +6145,12 @@ "node": ">= 8" } }, + "node_modules/aproba": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz", + "integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==", + "license": "ISC" + }, "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", @@ -6330,7 +6165,8 @@ "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" }, "node_modules/array-union": { "version": "2.1.0", @@ -6349,6 +6185,15 @@ "astring": "bin/astring" } }, + "node_modules/autocomplete.js": { + "version": "0.37.1", + "resolved": "https://registry.npmjs.org/autocomplete.js/-/autocomplete.js-0.37.1.tgz", + "integrity": "sha512-PgSe9fHYhZEsm/9jggbjtVsGXJkPLvd+9mC7gZJ662vVL5CRWEtm/mIrrzCx0MrNxHVwxD5d00UOn6NsmL2LUQ==", + "license": "MIT", + "dependencies": { + "immediate": "^3.2.3" + } + }, "node_modules/autoprefixer": { "version": "10.4.21", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", @@ -6413,13 +6258,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", - "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", + "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", + "@babel/compat-data": "^7.27.7", + "@babel/helper-define-polyfill-provider": "^0.6.5", "semver": "^6.3.1" }, "peerDependencies": { @@ -6449,12 +6294,12 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", - "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", + "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2" + "@babel/helper-define-polyfill-provider": "^0.6.5" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -6475,10 +6320,30 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.9.tgz", + "integrity": "sha512-hY/u2lxLrbecMEWSB0IpGzGyDyeoMFQhCvZd2jGFSE5I17Fh01sYUBPCJtkWERw7zrac9+cIghxm/ytJa2X8iA==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "license": "MIT" + }, + "node_modules/bcp-47-match": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-1.0.3.tgz", + "integrity": "sha512-LggQ4YTdjWQSKELZF5JwchnBa1u0pIQSZf5lSdOHEdbVP55h0qICA/FUp3+W99q0xqxYa1ZQizTUH87gecII5w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, "node_modules/big.js": { "version": "5.2.2", @@ -6492,6 +6357,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", "engines": { "node": ">=8" }, @@ -6500,22 +6366,23 @@ } }, "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "license": "MIT", "dependencies": { - "bytes": "3.1.2", + "bytes": "~3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", "type-is": "~1.6.18", - "unpipe": "1.0.0" + "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.8", @@ -6526,6 +6393,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -6534,19 +6402,51 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, + "node_modules/body-parser/node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/body-parser/node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } }, "node_modules/bonjour-service": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" @@ -6579,9 +6479,10 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6599,9 +6500,9 @@ } }, "node_modules/browserslist": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz", - "integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==", + "version": "4.26.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.2.tgz", + "integrity": "sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==", "funding": [ { "type": "opencollective", @@ -6618,9 +6519,10 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001718", - "electron-to-chromium": "^1.5.160", - "node-releases": "^2.0.19", + "baseline-browser-mapping": "^2.8.3", + "caniuse-lite": "^1.0.30001741", + "electron-to-chromium": "^1.5.218", + "node-releases": "^2.0.21", "update-browserslist-db": "^1.1.3" }, "bin": { @@ -6635,6 +6537,21 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -6687,9 +6604,10 @@ } }, "node_modules/call-bind-apply-helpers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", - "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" @@ -6699,12 +6617,13 @@ } }, "node_modules/call-bound": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", - "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "get-intrinsic": "^1.2.6" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -6754,9 +6673,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001720", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001720.tgz", - "integrity": "sha512-Ec/2yV2nNPwb4DnTANEV99ZWwm3ZWfdlfkQbWSDDt+PsXEVYwlhPH8tdMaPunYTKKmz7AnHi2oNEi1GcmKCD8g==", + "version": "1.0.30001745", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001745.tgz", + "integrity": "sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ==", "funding": [ { "type": "opencollective", @@ -6850,6 +6769,7 @@ "version": "1.0.0-rc.12", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "license": "MIT", "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", @@ -6870,6 +6790,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", @@ -6886,6 +6807,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -7046,6 +6968,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", @@ -7055,7 +6986,8 @@ "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "license": "MIT" }, "node_modules/colors": { "version": "1.4.0", @@ -7101,6 +7033,7 @@ "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "license": "MIT", "dependencies": { "mime-db": ">= 1.43.0 < 2" }, @@ -7109,23 +7042,25 @@ } }, "node_modules/compressible/node_modules/mime-db": { - "version": "1.53.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", - "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/compression": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", - "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "compressible": "~2.0.18", "debug": "2.6.9", "negotiator": "~0.6.4", - "on-headers": "~1.0.2", + "on-headers": "~1.1.0", "safe-buffer": "5.2.1", "vary": "~1.1.2" }, @@ -7137,6 +7072,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -7145,6 +7081,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -7152,7 +7089,8 @@ "node_modules/compression/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", @@ -7190,6 +7128,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "license": "MIT", "engines": { "node": ">=0.8" } @@ -7203,6 +7142,12 @@ "node": "^14.18.0 || >=16.10.0" } }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "license": "ISC" + }, "node_modules/content-disposition": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", @@ -7215,6 +7160,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -7229,6 +7175,7 @@ "version": "0.7.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -7236,19 +7183,8 @@ "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/copy-text-to-clipboard": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", - "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" }, "node_modules/copy-webpack-plugin": { "version": "11.0.0", @@ -7328,12 +7264,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.42.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.42.0.tgz", - "integrity": "sha512-bQasjMfyDGyaeWKBIu33lHh9qlSR0MFE/Nmc6nMjf/iU9b3rSMdAYz1Baxrv4lPdGUsTqZudHA4jIGSJy0SWZQ==", + "version": "3.45.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.45.1.tgz", + "integrity": "sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA==", "license": "MIT", "dependencies": { - "browserslist": "^4.24.4" + "browserslist": "^4.25.3" }, "funding": { "type": "opencollective", @@ -7341,9 +7277,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.43.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.43.0.tgz", - "integrity": "sha512-i/AgxU2+A+BbJdMxh3v7/vxi2SbFqxiFmg6VsDwYB4jkucrd1BZNA9a9gphC0fYMG5IBSgQcbQnk865VCLe7xA==", + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.46.0.tgz", + "integrity": "sha512-NMCW30bHNofuhwLhYPt66OLOKTMbOhgTTatKVbaQC3KRHpTCiRIBYvtshr+NBYSnBxwAFhjW/RfJ0XbIjS16rw==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -7354,7 +7290,8 @@ "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" }, "node_modules/cosmiconfig": { "version": "8.3.6", @@ -7459,9 +7396,9 @@ } }, "node_modules/css-declaration-sorter": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", - "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.3.0.tgz", + "integrity": "sha512-LQF6N/3vkAMYF4xoHLJfG718HRJh34Z8BnNhd6bosOMIVjMlhuZK5++oZa3uYAgrI5+7x2o27gUqTR2U/KjUOQ==", "license": "ISC", "engines": { "node": "^14 || ^16 || >=18" @@ -7471,9 +7408,9 @@ } }, "node_modules/css-has-pseudo": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-7.0.2.tgz", - "integrity": "sha512-nzol/h+E0bId46Kn2dQH5VElaknX2Sr0hFuB/1EomdC7j+OISt2ZzK7EHX9DZDY53WbIVAR7FYKSO2XnSf07MQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-7.0.3.tgz", + "integrity": "sha512-oG+vKuGyqe/xvEMoxAQrhi7uY16deJR3i7wwhBerVrGQKSqUC5GiOVxTpM9F9B9hw0J+eKeOWLH7E9gZ1Dr5rA==", "funding": [ { "type": "github", @@ -7648,6 +7585,12 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css-selector-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz", + "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==", + "license": "MIT" + }, "node_modules/css-tree": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", @@ -7673,9 +7616,9 @@ } }, "node_modules/cssdb": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-8.3.0.tgz", - "integrity": "sha512-c7bmItIg38DgGjSwDPZOYF/2o0QU/sSgkWOMyl8votOfgFuyiFKWPesmCGEsrGLxEA9uL540cp8LdaGEjUGsZQ==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-8.4.2.tgz", + "integrity": "sha512-PzjkRkRUS+IHDJohtxkIczlxPPZqRo0nXplsYXOMBRPjcVRjj1W4DfvRgshUYTVuUigU7ptVYkFJQ7abUB0nyg==", "funding": [ { "type": "opencollective", @@ -7831,9 +7774,10 @@ "license": "CC0-1.0" }, "node_modules/csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" }, "node_modules/data-uri-to-buffer": { "version": "4.0.1", @@ -7849,11 +7793,12 @@ "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -7919,15 +7864,32 @@ "node": ">=0.10.0" } }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "license": "MIT", "dependencies": { - "execa": "^5.0.0" + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" }, "engines": { - "node": ">= 10" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/defer-to-connect": { @@ -7959,6 +7921,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "license": "MIT", "engines": { "node": ">=8" } @@ -7984,6 +7947,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -8001,6 +7965,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -8021,7 +7986,8 @@ "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "license": "MIT" }, "node_modules/detect-port": { "version": "1.6.1", @@ -8063,10 +8029,24 @@ "node": ">=8" } }, + "node_modules/direction": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/direction/-/direction-1.0.4.tgz", + "integrity": "sha512-GYqKi1aH7PJXxdhTeZBFrg8vUBeKXi+cNprXsC1kpJcbcVnV9wBsrOu1cQEdG0WeQwlfHiy3XvnKfIrJ2R0NzQ==", + "license": "MIT", + "bin": { + "direction": "cli.js" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/dns-packet": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "license": "MIT", "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" }, @@ -8074,6 +8054,142 @@ "node": ">=6" } }, + "node_modules/docusaurus-lunr-search": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/docusaurus-lunr-search/-/docusaurus-lunr-search-3.6.0.tgz", + "integrity": "sha512-CCEAnj5e67sUZmIb2hOl4xb4nDN07fb0fvRDDmdWlYpUvyS1CSKbw4lsGInLyUFEEEBzxQmT6zaVQdF/8Zretg==", + "license": "MIT", + "dependencies": { + "autocomplete.js": "^0.37.1", + "clsx": "^2.1.1", + "gauge": "^3.0.2", + "hast-util-select": "^4.0.2", + "hast-util-to-text": "^2.0.1", + "hogan.js": "^3.0.2", + "lunr": "^2.3.9", + "lunr-languages": "^1.4.0", + "mark.js": "^8.11.1", + "minimatch": "^3.1.2", + "rehype-parse": "^7.0.1", + "to-vfile": "^6.1.0", + "unified": "^9.2.2", + "unist-util-is": "^4.1.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "peerDependencies": { + "@docusaurus/core": "^2.0.0-alpha.60 || ^2.0.0 || ^3.0.0", + "react": "^16.8.4 || ^17 || ^18 || ^19", + "react-dom": "^16.8.4 || ^17 || ^18 || ^19" + } + }, + "node_modules/docusaurus-lunr-search/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/docusaurus-lunr-search/node_modules/bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/docusaurus-lunr-search/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/docusaurus-lunr-search/node_modules/trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/docusaurus-lunr-search/node_modules/unified": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", + "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", + "license": "MIT", + "dependencies": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^2.0.0", + "trough": "^1.0.0", + "vfile": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/docusaurus-lunr-search/node_modules/unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/docusaurus-lunr-search/node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/docusaurus-lunr-search/node_modules/vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/docusaurus-lunr-search/node_modules/vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/docusaurus-plugin-sass": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/docusaurus-plugin-sass/-/docusaurus-plugin-sass-0.2.6.tgz", @@ -8181,6 +8297,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", @@ -8203,12 +8320,13 @@ "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.161", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.161.tgz", - "integrity": "sha512-hwtetwfKNZo/UlwHIVBlKZVdy7o8bIZxxKs0Mv/ROPiQQQmDgdm5a+KvKtBsxM8ZjFzTaCeLoodZ8jiBE3o9rA==", + "version": "1.5.227", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.227.tgz", + "integrity": "sha512-ITxuoPfJu3lsNWUi2lBM2PaBPYgH3uqmxut5vmBxgYvyI4AlJ6P3Cai1O76mOrkJCBzq0IxWg/NtqOrpu/0gKA==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -8242,6 +8360,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -8282,6 +8401,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -8290,6 +8410,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -8300,9 +8421,10 @@ "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" }, "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, @@ -8547,6 +8669,7 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -8576,6 +8699,15 @@ "node": ">=0.8.x" } }, + "node_modules/eventsource-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -8599,38 +8731,39 @@ } }, "node_modules/express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", + "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", + "body-parser": "~1.20.3", + "content-disposition": "~0.5.4", "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", - "on-finished": "2.4.1", + "on-finished": "~2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", + "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", - "qs": "6.13.0", + "qs": "~6.14.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", + "send": "~0.19.0", + "serve-static": "~1.16.2", "setprototypeof": "1.2.0", - "statuses": "2.0.1", + "statuses": "~2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" @@ -8647,6 +8780,7 @@ "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" }, @@ -8658,6 +8792,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -8665,17 +8800,20 @@ "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/express/node_modules/path-to-regexp": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" }, "node_modules/express/node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -8723,9 +8861,9 @@ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "node_modules/fast-uri": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.5.tgz", - "integrity": "sha512-5JnBCWpFlMo0a3ciDy/JckMzzv1U9coZrIhedq+HXxxUfDTAiS0LA8OKVao4G9BxmCVck/jtA5r3KAtRWEyD8Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "funding": [ { "type": "github", @@ -8735,7 +8873,8 @@ "type": "opencollective", "url": "https://opencollective.com/fastify" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/fastq": { "version": "1.15.0", @@ -8761,6 +8900,7 @@ "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" }, @@ -8879,6 +9019,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", @@ -8896,6 +9037,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -8903,7 +9045,8 @@ "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/find-cache-dir": { "version": "4.0.0", @@ -8947,15 +9090,16 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -8966,11 +9110,12 @@ } }, "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.0", + "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { @@ -9022,6 +9167,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -9043,6 +9189,7 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -9061,21 +9208,12 @@ "node": ">=14.14" } }, - "node_modules/fs-monkey": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", - "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -9088,10 +9226,52 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gauge/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/gauge/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -9102,16 +9282,17 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", - "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", + "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "get-proto": "^1.0.0", + "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", @@ -9133,6 +9314,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" @@ -9159,19 +9341,17 @@ "license": "ISC" }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "license": "BlueOak-1.0.0", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" }, "engines": { - "node": "*" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -9188,12 +9368,68 @@ "node": ">= 6" } }, + "node_modules/glob-to-regex.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.0.1.tgz", + "integrity": "sha512-CG/iEvgQqfzoVsMUbxSJcwbG2JwyZ3naEqPkeltwl0BSS8Bp83k3xlGms+0QdWFUAwV+uvo80wNswKF6FWEkKg==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "license": "BSD-2-Clause" }, + "node_modules/glob/node_modules/lru-cache": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz", + "integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==", + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/global-dirs": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", @@ -9248,6 +9484,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -9318,9 +9555,10 @@ } }, "node_modules/gray-matter/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -9346,7 +9584,8 @@ "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "license": "MIT" }, "node_modules/has-flag": { "version": "4.0.0", @@ -9372,6 +9611,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -9379,6 +9619,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "license": "ISC" + }, "node_modules/has-yarn": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", @@ -9394,6 +9640,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -9420,6 +9667,26 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-has-property": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-1.0.4.tgz", + "integrity": "sha512-ghHup2voGfgFoHMGnaLHOjbYFACKrRh9KFttdCzMCbFoBMJXiNi2+XTrPP8+q6cDJM/RSqlCfVWrjp1H201rZg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz", + "integrity": "sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-parse-selector": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", @@ -9456,6 +9723,130 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-select": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-4.0.2.tgz", + "integrity": "sha512-8EEG2//bN5rrzboPWD2HdS3ugLijNioS1pqOTIolXNf67xxShYw4SQEmVXd3imiBG+U2bC2nVTySr/iRAA7Cjg==", + "license": "MIT", + "dependencies": { + "bcp-47-match": "^1.0.0", + "comma-separated-tokens": "^1.0.0", + "css-selector-parser": "^1.0.0", + "direction": "^1.0.0", + "hast-util-has-property": "^1.0.0", + "hast-util-is-element": "^1.0.0", + "hast-util-to-string": "^1.0.0", + "hast-util-whitespace": "^1.0.0", + "not": "^0.1.0", + "nth-check": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0", + "unist-util-visit": "^2.0.0", + "zwitch": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/hast-util-select/node_modules/comma-separated-tokens": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-select/node_modules/hast-util-whitespace": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz", + "integrity": "sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select/node_modules/property-information": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-select/node_modules/space-separated-tokens": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-select/node_modules/unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select/node_modules/unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select/node_modules/unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select/node_modules/zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/hast-util-to-estree": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", @@ -9544,6 +9935,31 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-to-string": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-1.0.4.tgz", + "integrity": "sha512-eK0MxRX47AV2eZ+Lyr18DCpQgodvaS3fAQO2+b9Two9F5HEoRPhiUMNzoXArMJfZi2yieFzUBMRl3HNJ3Jus3w==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-2.0.1.tgz", + "integrity": "sha512-8nsgCARfs6VkwH2jJU9b8LNTuR4700na+0h3PqCaEk4MAnMDeu5P0tP8mjk9LLNGxIeQRLbiDbZVw6rku+pYsQ==", + "license": "MIT", + "dependencies": { + "hast-util-is-element": "^1.0.0", + "repeat-string": "^1.0.0", + "unist-util-find-after": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-whitespace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", @@ -9594,6 +10010,18 @@ "value-equal": "^1.0.1" } }, + "node_modules/hogan.js": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz", + "integrity": "sha512-RqGs4wavGYJWE07t35JQccByczmNUXQT0E12ZYV1VKYu5UiAU9lsos/yBAcf840+zrUQQxgVduCR5/B8nNtibg==", + "dependencies": { + "mkdirp": "0.3.0", + "nopt": "1.0.10" + }, + "bin": { + "hulk": "bin/hulk" + } + }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -9606,6 +10034,7 @@ "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "license": "MIT", "dependencies": { "inherits": "^2.0.1", "obuf": "^1.0.0", @@ -9616,12 +10045,14 @@ "node_modules/hpack.js/node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" }, "node_modules/hpack.js/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -9635,36 +10066,18 @@ "node_modules/hpack.js/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" }, "node_modules/hpack.js/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } }, - "node_modules/htm": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/htm/-/htm-3.1.1.tgz", - "integrity": "sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==" - }, - "node_modules/html-entities": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", - "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ] - }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -9790,6 +10203,7 @@ "url": "https://github.com/sponsors/fb55" } ], + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", @@ -9805,12 +10219,14 @@ "node_modules/http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "license": "MIT" }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -9823,14 +10239,16 @@ } }, "node_modules/http-parser-js": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.9.tgz", - "integrity": "sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw==" + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "license": "MIT" }, "node_modules/http-proxy": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "license": "MIT", "dependencies": { "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", @@ -9868,6 +10286,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -9895,10 +10314,20 @@ "node": ">=10.17.0" } }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "license": "MIT", + "engines": { + "node": ">=10.18" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -9938,6 +10367,12 @@ "node": ">=16.x" } }, + "node_modules/immediate": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", + "license": "MIT" + }, "node_modules/immutable": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", @@ -9992,19 +10427,11 @@ "node": ">=12" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" }, "node_modules/ini": { "version": "1.3.8", @@ -10029,6 +10456,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "license": "MIT", "engines": { "node": ">= 10" } @@ -10066,6 +10494,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -10073,6 +10502,29 @@ "node": ">=8" } }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/is-ci": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", @@ -10085,11 +10537,15 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -10109,6 +10565,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", "bin": { "is-docker": "cli.js" }, @@ -10164,6 +10621,39 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container/node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-installed-globally": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", @@ -10179,6 +10669,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-network-error": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.0.tgz", + "integrity": "sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-npm": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", @@ -10266,6 +10768,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", "dependencies": { "is-docker": "^2.0.0" }, @@ -10300,20 +10803,6 @@ "node": ">=0.10.0" } }, - "node_modules/jackspeak": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", - "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/jest-util": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", @@ -10389,9 +10878,10 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -10421,6 +10911,12 @@ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -10487,12 +10983,13 @@ } }, "node_modules/launch-editor": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", - "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.11.1.tgz", + "integrity": "sha512-SEET7oNfgSaB6Ym0jufAdCeo3meJVeCaaDyzRygy0xsp2BFKCprcfHljTq4QkzTLUxEKkFK6OK4811YM2oSrRg==", + "license": "MIT", "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" + "picocolors": "^1.1.1", + "shell-quote": "^1.8.3" } }, "node_modules/leven": { @@ -10557,9 +11054,10 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "license": "MIT" }, "node_modules/lodash.debounce": { "version": "4.0.8", @@ -10629,6 +11127,12 @@ "yallist": "^3.0.2" } }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "license": "MIT" + }, "node_modules/lunr-languages": { "version": "1.14.0", "resolved": "https://registry.npmjs.org/lunr-languages/-/lunr-languages-1.14.0.tgz", @@ -10668,10 +11172,23 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/marked": { + "version": "16.4.1", + "resolved": "https://registry.npmjs.org/marked/-/marked-16.4.1.tgz", + "integrity": "sha512-ntROs7RaN3EvWfy3EZi14H4YxmT6A5YvywfhO+0pm+cH/dnSQRmdAmoFIc3B9aiwTehyk7pESH4ofyBY+V5hZg==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -11010,9 +11527,9 @@ } }, "node_modules/mdast-util-to-hast": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -11074,25 +11591,34 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "version": "4.47.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.47.0.tgz", + "integrity": "sha512-Xey8IZA57tfotV/TN4d6BmccQuhFP+CqRiI7TTNdipZdZBzF2WnzUcH//Cudw6X4zJiUbo/LTuU/HPA/iC/pNg==", + "license": "Apache-2.0", "dependencies": { - "fs-monkey": "^1.0.4" + "@jsonjoy.com/json-pack": "^1.11.0", + "@jsonjoy.com/util": "^1.9.0", + "glob-to-regex.js": "^1.0.1", + "thingies": "^2.5.0", + "tree-dump": "^1.0.3", + "tslib": "^2.0.0" }, - "engines": { - "node": ">= 4.0.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" } }, "node_modules/merge-descriptors": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" } @@ -11114,6 +11640,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -12902,6 +13429,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -12948,9 +13476,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", - "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz", + "integrity": "sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ==", "license": "MIT", "dependencies": { "schema-utils": "^4.0.0", @@ -12970,7 +13498,8 @@ "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" }, "node_modules/minimatch": { "version": "3.1.2", @@ -13000,6 +13529,16 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mkdirp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha512-OHsdUcVAQ6pOtg5JYWpCBo9W/GySVuwvP9hueRMW7UqshC0tbfzLv8wjySTPm3tfUZ/21CE9E1pJagOA91Pxew==", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "license": "MIT/X11", + "engines": { + "node": "*" + } + }, "node_modules/mrmime": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", @@ -13009,14 +13548,16 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/multicast-dns": { "version": "7.2.5", "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "license": "MIT", "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" @@ -13065,6 +13606,7 @@ "version": "0.6.4", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -13140,23 +13682,40 @@ } }, "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.2.tgz", + "integrity": "sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw==", + "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" } }, "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.21.tgz", + "integrity": "sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==", "license": "MIT" }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "license": "MIT", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -13181,6 +13740,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/not": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/not/-/not-0.1.0.tgz", + "integrity": "sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA==" + }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -13256,9 +13820,10 @@ } }, "node_modules/object-inspect": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", - "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -13298,12 +13863,14 @@ "node_modules/obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "license": "MIT" }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -13312,21 +13879,14 @@ } }, "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -13345,6 +13905,7 @@ "version": "8.4.2", "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "license": "MIT", "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -13452,15 +14013,20 @@ } }, "node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "license": "MIT", "dependencies": { - "@types/retry": "0.12.0", + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", "retry": "^0.13.1" }, "engines": { - "node": ">=8" + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-timeout": { @@ -13578,11 +14144,12 @@ } }, "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", "dependencies": { - "domhandler": "^5.0.2", + "domhandler": "^5.0.3", "parse5": "^7.0.0" }, "funding": { @@ -13593,6 +14160,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -13615,14 +14183,6 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", @@ -13639,7 +14199,8 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" }, "node_modules/path-scurry": { "version": "1.11.1", @@ -13816,9 +14377,9 @@ } }, "node_modules/postcss-color-functional-notation": { - "version": "7.0.10", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.10.tgz", - "integrity": "sha512-k9qX+aXHBiLTRrWoCJuUFI6F1iF6QJQUXNVWJVSbqZgj57jDhBlOvD8gNUGl35tgqDivbGLhZeW3Ongz4feuKA==", + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.12.tgz", + "integrity": "sha512-TLCW9fN5kvO/u38/uesdpbx3e8AkTYhMvDZYa9JpmImWuTE99bDQ7GU7hdOADIZsiI9/zuxfAJxny/khknp1Zw==", "funding": [ { "type": "github", @@ -13831,10 +14392,10 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/css-color-parser": "^3.0.10", + "@csstools/css-color-parser": "^3.1.0", "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", "@csstools/utilities": "^2.0.0" }, "engines": { @@ -14130,9 +14691,9 @@ } }, "node_modules/postcss-double-position-gradients": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-6.0.2.tgz", - "integrity": "sha512-7qTqnL7nfLRyJK/AHSVrrXOuvDDzettC+wGoienURV8v2svNbu6zJC52ruZtHaO6mfcagFmuTGFdzRsJKB3k5Q==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-6.0.4.tgz", + "integrity": "sha512-m6IKmxo7FxSP5nF2l63QbCC3r+bWpFUWmZXZf096WxG0m7Vl1Q1+ruFOhpdDRmKrRS+S3Jtk+TVk/7z0+BVK6g==", "funding": [ { "type": "github", @@ -14145,7 +14706,7 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^4.1.0", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", "@csstools/utilities": "^2.0.0", "postcss-value-parser": "^4.2.0" }, @@ -14290,9 +14851,9 @@ } }, "node_modules/postcss-lab-function": { - "version": "7.0.10", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-7.0.10.tgz", - "integrity": "sha512-tqs6TCEv9tC1Riq6fOzHuHcZyhg4k3gIAMB8GGY/zA1ssGdm6puHMVE7t75aOSoFg7UD2wyrFFhbldiCMyyFTQ==", + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-7.0.12.tgz", + "integrity": "sha512-tUcyRk1ZTPec3OuKFsqtRzW2Go5lehW29XA21lZ65XmzQkz43VY2tyWEC202F7W3mILOjw0voOiuxRGTsN+J9w==", "funding": [ { "type": "github", @@ -14305,10 +14866,10 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/css-color-parser": "^3.0.10", + "@csstools/css-color-parser": "^3.1.0", "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", "@csstools/utilities": "^2.0.0" }, "engines": { @@ -14565,9 +15126,9 @@ } }, "node_modules/postcss-nesting": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.1.tgz", - "integrity": "sha512-VbqqHkOBOt4Uu3G8Dm8n6lU5+9cJFxiuty9+4rcoyRPO9zZS1JIs6td49VIoix3qYqELHlJIn46Oih9SAKo+yQ==", + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.2.tgz", + "integrity": "sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ==", "funding": [ { "type": "github", @@ -14580,7 +15141,7 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/selector-resolve-nested": "^3.0.0", + "@csstools/selector-resolve-nested": "^3.1.0", "@csstools/selector-specificity": "^5.0.0", "postcss-selector-parser": "^7.0.0" }, @@ -14879,9 +15440,9 @@ } }, "node_modules/postcss-preset-env": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.2.1.tgz", - "integrity": "sha512-mDInnlm4mYhmR0S79hNLzseW9nx4Ihd8s15K99iu6u6QhoSQgqWX9Oj6nTd/8Dz3b0T7v2JSrfnXsDfv9TFvDg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.4.0.tgz", + "integrity": "sha512-2kqpOthQ6JhxqQq1FSAAZGe9COQv75Aw8WbsOvQVNJ2nSevc9Yx/IKZGuZ7XJ+iOTtVon7LfO7ELRzg8AZ+sdw==", "funding": [ { "type": "github", @@ -14894,20 +15455,23 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/postcss-cascade-layers": "^5.0.1", - "@csstools/postcss-color-function": "^4.0.10", - "@csstools/postcss-color-mix-function": "^3.0.10", - "@csstools/postcss-color-mix-variadic-function-arguments": "^1.0.0", - "@csstools/postcss-content-alt-text": "^2.0.6", + "@csstools/postcss-alpha-function": "^1.0.1", + "@csstools/postcss-cascade-layers": "^5.0.2", + "@csstools/postcss-color-function": "^4.0.12", + "@csstools/postcss-color-function-display-p3-linear": "^1.0.1", + "@csstools/postcss-color-mix-function": "^3.0.12", + "@csstools/postcss-color-mix-variadic-function-arguments": "^1.0.2", + "@csstools/postcss-content-alt-text": "^2.0.8", + "@csstools/postcss-contrast-color-function": "^2.0.12", "@csstools/postcss-exponential-functions": "^2.0.9", "@csstools/postcss-font-format-keywords": "^4.0.0", - "@csstools/postcss-gamut-mapping": "^2.0.10", - "@csstools/postcss-gradients-interpolation-method": "^5.0.10", - "@csstools/postcss-hwb-function": "^4.0.10", - "@csstools/postcss-ic-unit": "^4.0.2", + "@csstools/postcss-gamut-mapping": "^2.0.11", + "@csstools/postcss-gradients-interpolation-method": "^5.0.12", + "@csstools/postcss-hwb-function": "^4.0.12", + "@csstools/postcss-ic-unit": "^4.0.4", "@csstools/postcss-initial": "^2.0.1", - "@csstools/postcss-is-pseudo-class": "^5.0.1", - "@csstools/postcss-light-dark-function": "^2.0.9", + "@csstools/postcss-is-pseudo-class": "^5.0.3", + "@csstools/postcss-light-dark-function": "^2.0.11", "@csstools/postcss-logical-float-and-clear": "^3.0.0", "@csstools/postcss-logical-overflow": "^2.0.0", "@csstools/postcss-logical-overscroll-behavior": "^2.0.0", @@ -14917,40 +15481,40 @@ "@csstools/postcss-media-queries-aspect-ratio-number-values": "^3.0.5", "@csstools/postcss-nested-calc": "^4.0.0", "@csstools/postcss-normalize-display-values": "^4.0.0", - "@csstools/postcss-oklab-function": "^4.0.10", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", + "@csstools/postcss-oklab-function": "^4.0.12", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", "@csstools/postcss-random-function": "^2.0.1", - "@csstools/postcss-relative-color-syntax": "^3.0.10", + "@csstools/postcss-relative-color-syntax": "^3.0.12", "@csstools/postcss-scope-pseudo-class": "^4.0.1", "@csstools/postcss-sign-functions": "^1.1.4", "@csstools/postcss-stepped-value-functions": "^4.0.9", - "@csstools/postcss-text-decoration-shorthand": "^4.0.2", + "@csstools/postcss-text-decoration-shorthand": "^4.0.3", "@csstools/postcss-trigonometric-functions": "^4.0.9", "@csstools/postcss-unset-value": "^4.0.0", "autoprefixer": "^10.4.21", - "browserslist": "^4.25.0", + "browserslist": "^4.26.0", "css-blank-pseudo": "^7.0.1", - "css-has-pseudo": "^7.0.2", + "css-has-pseudo": "^7.0.3", "css-prefers-color-scheme": "^10.0.0", - "cssdb": "^8.3.0", + "cssdb": "^8.4.2", "postcss-attribute-case-insensitive": "^7.0.1", "postcss-clamp": "^4.1.0", - "postcss-color-functional-notation": "^7.0.10", + "postcss-color-functional-notation": "^7.0.12", "postcss-color-hex-alpha": "^10.0.0", "postcss-color-rebeccapurple": "^10.0.0", "postcss-custom-media": "^11.0.6", "postcss-custom-properties": "^14.0.6", "postcss-custom-selectors": "^8.0.5", "postcss-dir-pseudo-class": "^9.0.1", - "postcss-double-position-gradients": "^6.0.2", + "postcss-double-position-gradients": "^6.0.4", "postcss-focus-visible": "^10.0.1", "postcss-focus-within": "^9.0.1", "postcss-font-variant": "^5.0.0", "postcss-gap-properties": "^6.0.0", "postcss-image-set-function": "^7.0.0", - "postcss-lab-function": "^7.0.10", + "postcss-lab-function": "^7.0.12", "postcss-logical": "^8.1.0", - "postcss-nesting": "^13.0.1", + "postcss-nesting": "^13.0.2", "postcss-opacity-percentage": "^3.0.0", "postcss-overflow-shorthand": "^6.0.0", "postcss-page-break": "^3.0.4", @@ -15174,15 +15738,6 @@ "postcss": "^8.4.31" } }, - "node_modules/preact": { - "version": "10.19.2", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.2.tgz", - "integrity": "sha512-UA9DX/OJwv6YwP9Vn7Ti/vF80XL+YA5H2l7BpCtUr3ya8LWHFzpiO5R+N7dN16ujpIxhekRFuOOF82bXX7K/lg==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/preact" - } - }, "node_modules/pretty-error": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", @@ -15225,7 +15780,8 @@ "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" }, "node_modules/prompts": { "version": "2.4.2", @@ -15268,6 +15824,7 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -15280,6 +15837,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -15299,11 +15857,12 @@ } }, "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.6" + "side-channel": "^1.1.0" }, "engines": { "node": ">=0.6" @@ -15359,14 +15918,15 @@ } }, "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "license": "MIT", "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.8" @@ -15376,6 +15936,36 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/raw-body/node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -15403,24 +15993,24 @@ } }, "node_modules/react": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", - "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", - "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", "dependencies": { - "scheduler": "^0.26.0" + "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.1.0" + "react": "^19.2.4" } }, "node_modules/react-fast-compare": { @@ -15451,9 +16041,9 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-json-view-lite": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-2.4.1.tgz", - "integrity": "sha512-fwFYknRIBxjbFm0kBDrzgBy1xa5tDg2LyXXBepC5f1b+MY3BUClMCsvanMPn089JbV1Eg3nZcrp0VCuH43aXnA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-2.5.0.tgz", + "integrity": "sha512-tk7o7QG9oYyELWHL8xiMQ8x4WzjCzbWNyig3uexmkLb54r8jO0yH3WCWx8UZS0c49eSA4QUmG5caiRJ8fAn58g==", "license": "MIT", "engines": { "node": ">=18" @@ -15560,6 +16150,7 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -15573,6 +16164,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -15740,6 +16332,182 @@ "regjsparser": "bin/parser" } }, + "node_modules/rehype-parse": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-7.0.1.tgz", + "integrity": "sha512-fOiR9a9xH+Le19i4fGzIEowAbwG7idy2Jzs4mOrFWBSJ0sNUgy0ev871dwWnbOo371SjgjG4pwzrbgSVrKxecw==", + "license": "MIT", + "dependencies": { + "hast-util-from-parse5": "^6.0.0", + "parse5": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse/node_modules/@types/hast": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/rehype-parse/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/rehype-parse/node_modules/comma-separated-tokens": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/rehype-parse/node_modules/hast-util-from-parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz", + "integrity": "sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==", + "license": "MIT", + "dependencies": { + "@types/parse5": "^5.0.0", + "hastscript": "^6.0.0", + "property-information": "^5.0.0", + "vfile": "^4.0.0", + "vfile-location": "^3.2.0", + "web-namespaces": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse/node_modules/hast-util-parse-selector": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse/node_modules/hastscript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "license": "MIT" + }, + "node_modules/rehype-parse/node_modules/property-information": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/rehype-parse/node_modules/space-separated-tokens": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/rehype-parse/node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse/node_modules/vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse/node_modules/vfile-location": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", + "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse/node_modules/vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse/node_modules/web-namespaces": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", + "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/rehype-raw": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", @@ -16006,6 +16774,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -16021,20 +16790,25 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -16075,6 +16849,7 @@ "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", "engines": { "node": ">= 4" } @@ -16089,12 +16864,13 @@ } }, "node_modules/rimraf": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", - "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", + "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", + "license": "BlueOak-1.0.0", "dependencies": { - "glob": "^11.0.0", - "package-json-from-dist": "^1.0.0" + "glob": "^13.0.0", + "package-json-from-dist": "^1.0.1" }, "bin": { "rimraf": "dist/esm/bin.mjs" @@ -16106,73 +16882,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", - "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^4.0.1", - "minimatch": "^10.0.0", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/lru-cache": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", - "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", - "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/path-scurry": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", - "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/rtlcss": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", @@ -16191,6 +16900,18 @@ "node": ">=12.0.0" } }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -16235,12 +16956,13 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" }, "node_modules/sass": { - "version": "1.89.2", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.89.2.tgz", - "integrity": "sha512-xCmtksBKd/jdJ9Bt9p7nPKiuqrlBMBuuGkQlkhZjjQk3Ty48lv93k5Dq6OPkKt4XwxDJ7tvlfrTa1MPA9bf+QA==", + "version": "1.97.3", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.3.tgz", + "integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==", "license": "MIT", "dependencies": { "chokidar": "^4.0.0", @@ -16258,9 +16980,9 @@ } }, "node_modules/sass-loader": { - "version": "16.0.5", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.5.tgz", - "integrity": "sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==", + "version": "16.0.6", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.6.tgz", + "integrity": "sha512-sglGzId5gmlfxNs4gK2U3h7HlVRfx278YK6Ono5lwzuvi1jxig80YiuHkaDBVsYIKFhx8wN7XSCI0M2IDS/3qA==", "license": "MIT", "dependencies": { "neo-async": "^2.6.2" @@ -16330,9 +17052,9 @@ "license": "ISC" }, "node_modules/scheduler": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, "node_modules/schema-dts": { @@ -16342,9 +17064,10 @@ "license": "Apache-2.0" }, "node_modules/schema-utils": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", - "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -16363,6 +17086,7 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -16378,6 +17102,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -16388,12 +17113,14 @@ "node_modules/schema-utils/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/search-insights": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.10.0.tgz", - "integrity": "sha512-pQGrOE56QuTRmq4NzliRZe9rv914hBMBjOviuDliDHoIhmBGoyZRlFsPd4RprGGNC4PKdD2Jz54YN4Cmkb44mA==", + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", + "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", + "license": "MIT", "peer": true }, "node_modules/section-matter": { @@ -16411,12 +17138,14 @@ "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "license": "MIT" }, "node_modules/selfsigned": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "license": "MIT", "dependencies": { "@types/node-forge": "^1.3.0", "node-forge": "^1" @@ -16454,6 +17183,7 @@ "version": "0.19.0", "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -16477,6 +17207,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -16484,25 +17215,23 @@ "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/send/node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, "node_modules/send/node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -16539,6 +17268,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "license": "MIT", "dependencies": { "accepts": "~1.3.4", "batch": "0.6.1", @@ -16556,6 +17286,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -16564,6 +17295,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -16572,6 +17304,7 @@ "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "license": "MIT", "dependencies": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -16585,22 +17318,26 @@ "node_modules/serve-index/node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "license": "ISC" }, "node_modules/serve-index/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/serve-index/node_modules/setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "license": "ISC" }, "node_modules/serve-index/node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -16609,6 +17346,7 @@ "version": "1.16.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", @@ -16639,7 +17377,8 @@ "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" }, "node_modules/shallow-clone": { "version": "3.0.1", @@ -16678,9 +17417,10 @@ } }, "node_modules/shell-quote": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", - "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -16692,6 +17432,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", @@ -16710,6 +17451,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" @@ -16725,6 +17467,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -16742,6 +17485,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -16837,6 +17581,7 @@ "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "license": "MIT", "dependencies": { "faye-websocket": "^0.11.3", "uuid": "^8.3.2", @@ -16907,6 +17652,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "license": "MIT", "dependencies": { "debug": "^4.1.0", "handle-thing": "^2.0.0", @@ -16922,6 +17668,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "license": "MIT", "dependencies": { "debug": "^4.1.0", "detect-node": "^2.0.4", @@ -16952,20 +17699,22 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/std-env": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", - "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", "license": "MIT" }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } @@ -17155,9 +17904,10 @@ } }, "node_modules/sucrase/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -17171,9 +17921,10 @@ } }, "node_modules/sucrase/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -17232,6 +17983,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -17279,6 +18031,19 @@ "node": ">= 10" } }, + "node_modules/swr": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.6.tgz", + "integrity": "sha512-wfHRmHWk/isGNMwlLGlZX5Gzz/uTgo0o2IRuTMcf4CPuPFJZlq0rDaKUx+ozB5nBOReNV1kiOyzMfj+MBMikLw==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -17418,10 +18183,39 @@ "node": ">=0.8" } }, + "node_modules/thingies": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.5.0.tgz", + "integrity": "sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw==", + "license": "MIT", + "engines": { + "node": ">=10.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/throttleit": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-2.1.0.tgz", + "integrity": "sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "license": "MIT" }, "node_modules/tiny-invariant": { "version": "1.3.1", @@ -17453,10 +18247,74 @@ "node": ">=8.0" } }, + "node_modules/to-vfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/to-vfile/-/to-vfile-6.1.0.tgz", + "integrity": "sha512-BxX8EkCxOAZe+D/ToHdDsJcVI4HqQfmw0tCkp31zf3dNP/XWIAjU4CmeuSwsSoOzOTqHPOL0KUzyZqJplkD0Qw==", + "license": "MIT", + "dependencies": { + "is-buffer": "^2.0.0", + "vfile": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/to-vfile/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/to-vfile/node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/to-vfile/node_modules/vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/to-vfile/node_modules/vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", "engines": { "node": ">=0.6" } @@ -17469,6 +18327,22 @@ "node": ">=6" } }, + "node_modules/tree-dump": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz", + "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, "node_modules/trim-lines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", @@ -17514,6 +18388,7 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -17526,6 +18401,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -17534,6 +18410,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -17550,9 +18427,9 @@ } }, "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", "bin": { @@ -17564,9 +18441,9 @@ } }, "node_modules/undici-types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", - "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -17646,6 +18523,29 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/unist-util-find-after": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-3.0.0.tgz", + "integrity": "sha512-ojlBqfsBftYXExNu3+hHLfJQ/X1jYY/9vdm4yZWjIbf0VuWF6CRufci1ZyoD/wV2TYMKxXUoNuoqwy+CkgzAiQ==", + "license": "MIT", + "dependencies": { + "unist-util-is": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-find-after/node_modules/unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unist-util-is": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", @@ -17739,6 +18639,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -17933,10 +18834,20 @@ "react": ">= 16.8.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" }, "node_modules/utila": { "version": "0.4.0", @@ -17956,6 +18867,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", "engines": { "node": ">= 0.4.0" } @@ -17964,6 +18876,7 @@ "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -17977,6 +18890,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -18039,6 +18953,7 @@ "version": "1.7.3", "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "license": "MIT", "dependencies": { "minimalistic-assert": "^1.0.0" } @@ -18151,41 +19066,50 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.5.tgz", + "integrity": "sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==", + "license": "MIT", "dependencies": { "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", + "memfs": "^4.43.1", + "mime-types": "^3.0.1", + "on-finished": "^2.4.1", "range-parser": "^1.2.1", "schema-utils": "^4.0.0" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } } }, "node_modules/webpack-dev-middleware/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/webpack-dev-middleware/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "license": "MIT", "dependencies": { - "mime-db": "1.52.0" + "mime-db": "^1.54.0" }, "engines": { "node": ">= 0.6" @@ -18195,58 +19119,58 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/webpack-dev-server": { - "version": "4.15.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", - "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.2.tgz", + "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==", + "license": "MIT", + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/express-serve-static-core": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", "colorette": "^2.0.10", "compression": "^1.7.4", "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", + "express": "^4.21.2", "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", + "http-proxy-middleware": "^2.0.9", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.4", - "ws": "^8.13.0" + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" }, "bin": { "webpack-dev-server": "bin/webpack-dev-server.js" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" + "webpack": "^5.0.0" }, "peerDependenciesMeta": { "webpack": { @@ -18257,25 +19181,41 @@ } } }, - "node_modules/webpack-dev-server/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", + "node_modules/webpack-dev-server/node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/webpack-dev-server/node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "license": "MIT", "dependencies": { - "glob": "^7.1.3" + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" }, - "bin": { - "rimraf": "bin.js" + "engines": { + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -18457,6 +19397,7 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -18470,6 +19411,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", "engines": { "node": ">=0.8.0" } @@ -18488,6 +19430,35 @@ "node": ">= 8" } }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wide-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/widest-line": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", @@ -18595,11 +19566,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, "node_modules/write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", @@ -18631,6 +19597,36 @@ } } }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wsl-utils/node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/xdg-basedir": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", @@ -18654,6 +19650,15 @@ "xml-js": "bin/cli.js" } }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -18672,6 +19677,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zod": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz", + "integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/documentation/package.json b/documentation/package.json index 9e417f8345..632fd3082e 100644 --- a/documentation/package.json +++ b/documentation/package.json @@ -19,11 +19,11 @@ "serve": "docusaurus serve" }, "dependencies": { - "@cmfcmf/docusaurus-search-local": "^1.2.0", - "@docusaurus/core": "^3.8.1", - "@docusaurus/preset-classic": "^3.8.1", - "@docusaurus/theme-live-codeblock": "^3.8.1", - "@mdx-js/react": "^3.1.0", + "@docusaurus/core": "^3.9.2", + "docusaurus-lunr-search": "^3.6.0", + "@docusaurus/preset-classic": "^3.9.2", + "@docusaurus/theme-live-codeblock": "^3.9.2", + "@mdx-js/react": "^3.1.1", "clsx": "^2.1.1", "colors": "^1.4.0", "docusaurus-plugin-sass": "^0.2.6", @@ -31,10 +31,10 @@ "mustache": "^4.2.0", "node-fetch": "^3.1.1", "prism-react-renderer": "^2.4.1", - "react": "^19.1.0", - "react-dom": "^19.1.0", - "rimraf": "^6.0.1", - "sass": "1.89" + "react": "^19.2.4", + "react-dom": "^19.2.4", + "rimraf": "^6.1.2", + "sass": "1.97" }, "browserslist": { "production": [ @@ -50,21 +50,16 @@ }, "devDependencies": { "@docusaurus/module-type-aliases": "^3.6.0", - "@docusaurus/tsconfig": "^3.8.1", + "@docusaurus/tsconfig": "^3.9.2", "@docusaurus/types": "^3.6.0", - "@types/node": "^24.0.13", - "@types/react": "^19.1.8", + "@types/node": "^25.0.10", + "@types/react": "^19.2.9", "@types/react-helmet": "^6.1.11", "@types/react-router-dom": "^5.1.8", - "sass-loader": "^16.0.5", - "typescript": "^5.8.3" + "sass-loader": "^16.0.6", + "typescript": "^5.9.3" }, "engines": { "node": ">=18.0" - }, - "overrides": { - "@cmfcmf/docusaurus-search-local": { - "@docusaurus/core": "^3.0.0" - } } } diff --git a/documentation/src/css/_mixins.scss b/documentation/src/css/_mixins.scss index 6dddb376dc..170f303271 100644 --- a/documentation/src/css/_mixins.scss +++ b/documentation/src/css/_mixins.scss @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -@import './breakpoints'; +@use './breakpoints' as *; // Small devices @mixin sm { diff --git a/documentation/src/css/accordion.module.scss b/documentation/src/css/accordion.module.scss index 0d8d18a5f0..54080fbb80 100644 --- a/documentation/src/css/accordion.module.scss +++ b/documentation/src/css/accordion.module.scss @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -@import "./mixins"; +@use "./mixins" as *; .accordion { margin: 20px auto; diff --git a/documentation/src/css/custom.css b/documentation/src/css/custom.css index f4f02df2ad..994539dca1 100644 --- a/documentation/src/css/custom.css +++ b/documentation/src/css/custom.css @@ -47,8 +47,8 @@ body { padding-right: 0px !important; } -/* -Github Logo as CSS class by using a SVG in a Data-URL. +/* +Github Logo as CSS class by using a SVG in a Data-URL. The SVG content must be URL escaped for this to work. See also: https://stackoverflow.com/questions/10768451/inline-svg-in-css */ @@ -94,12 +94,18 @@ html[data-theme="dark"] .header-owasp-link::before { .flex-container { display: flex; + flex-wrap: wrap; } .flex-child { flex: 1; } +.button-group { + flex-wrap: wrap; + gap: 1rem; +} + th.default-column, td.default-column { word-wrap: anywhere; diff --git a/documentation/src/css/flipcard.module.scss b/documentation/src/css/flipcard.module.scss index 60ee4c388a..e77a0daad5 100644 --- a/documentation/src/css/flipcard.module.scss +++ b/documentation/src/css/flipcard.module.scss @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -@import "./mixins"; +@use "./mixins" as *; /* Flipcard container */ .flipcard { diff --git a/documentation/src/css/integration.module.scss b/documentation/src/css/integration.module.scss index 1c5d03398a..8416c8f367 100644 --- a/documentation/src/css/integration.module.scss +++ b/documentation/src/css/integration.module.scss @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -@import '../css/_mixins.scss'; +@use '../css/_mixins.scss' as *; .integrationImage { height: 40px; diff --git a/documentation/src/css/styles.module.scss b/documentation/src/css/styles.module.scss index d41c655538..2b6008704d 100644 --- a/documentation/src/css/styles.module.scss +++ b/documentation/src/css/styles.module.scss @@ -11,7 +11,7 @@ * and scoped locally. */ -@import "../css/_mixins.scss"; +@use "../css/_mixins.scss" as *; @import "../css/custom.css"; .heroBanner { diff --git a/documentation/src/integrations.js b/documentation/src/integrations.js deleted file mode 100644 index 02dbd6c67f..0000000000 --- a/documentation/src/integrations.js +++ /dev/null @@ -1,215 +0,0 @@ -// SPDX-FileCopyrightText: the secureCodeBox authors -// -// SPDX-License-Identifier: Apache-2.0 - -export const Hooks = [ - { - title: "Azure Monitor", - type: "persistenceProvider", - usecase: "Publishes all Scan Findings to Azure Monitor.", - path: "docs/hooks/azure-monitor", - imageUrl: "img/integrationIcons/Default.svg", - }, - { - title: "Cascading Scans", - type: "processing", - usecase: "Cascading Scans based declarative Rules.", - path: "docs/hooks/cascading-scans", - imageUrl: "img/integrationIcons/Default.svg", - }, - { - title: "DefectDojo", - type: "persistenceProvider", - usecase: "Publishes all Scan Reports to OWASP DefectDojo.", - path: "docs/hooks/defectdojo", - imageUrl: "img/integrationIcons/DefectDojo.svg", - }, - { - title: "Dependency-Track", - type: "persistenceProvider", - usecase: "Publishes all CycloneDX SBOMs to Dependency-Track.", - path: "docs/hooks/dependency-track", - imageUrl: "img/integrationIcons/Default.svg", - }, - { - title: "Elasticsearch", - type: "persistenceProvider", - usecase: "Publishes all Scan Findings to Elasticsearch.", - path: "docs/hooks/elasticsearch", - imageUrl: "img/integrationIcons/Elasticsearch.svg", - }, - { - title: "Finding Post Processing", - type: "dataProcessing", - usecase: "Updates fields for findings meeting specified conditions.", - path: "docs/hooks/finding-post-processing", - imageUrl: "img/integrationIcons/Default.svg", - }, - { - title: "Generic WebHook", - type: "integration", - usecase: "Publishes Scan Findings as WebHook.", - path: "docs/hooks/generic-webhook", - imageUrl: "img/integrationIcons/Default.svg", - }, - { - title: "Notification WebHook", - type: "integration", - usecase: "Publishes Scan Summary to MS Teams, Slack and others.", - path: "docs/hooks/notification-webhook", - imageUrl: "img/integrationIcons/Default.svg", - }, - { - title: "Static Report", - type: "persistenceProvider", - usecase: "Publishes all Scan Findings as HTML Report.", - path: "docs/hooks/static-report", - imageUrl: "img/integrationIcons/Default.svg", - }, - { - title: "Update Field", - type: "dataProcessing", - usecase: "Updates fields in finding results.", - path: "docs/hooks/update-field", - imageUrl: "img/integrationIcons/Default.svg", - }, -]; - -export const Scanners = [ - { - title: "Amass", - type: "Network", - usecase: "Subdomain Enumeration Scanner", - path: "docs/scanners/amass", - imageUrl: "img/integrationIcons/Amass.svg", - }, - { - title: "CMSeeK", - type: "CMS", - usecase: - "Automation of the process of detecting the Joomla CMS and its core vulnerabilities", - path: "docs/scanners/cmseek", - imageUrl: "img/integrationIcons/Default.svg", - }, - { - title: "ffuf", - type: "Webserver", - usecase: "Webserver and WebApplication Elements and Content Discovery", - path: "docs/scanners/ffuf", - imageUrl: "img/integrationIcons/ffuf.svg", - }, - { - title: "Git Repo Scanner", - type: "Repository", - usecase: "Discover Git repositories", - path: "docs/scanners/git-repo-scanner", - imageUrl: "img/integrationIcons/Default.svg", - }, - { - title: "Gitleaks", - type: "Repository", - usecase: "Find potential secrets in repositories", - path: "docs/scanners/gitleaks", - imageUrl: "img/integrationIcons/Gitleaks.svg", - }, - { - title: "Kube Hunter", - type: "Kubernetes", - usecase: "Kubernetes Vulnerability Scanner", - path: "docs/scanners/kube-hunter", - imageUrl: "img/integrationIcons/Default.svg", - }, - { - title: "Ncrack", - type: "Authentication", - usecase: "Network authentication bruteforcing", - path: "docs/scanners/ncrack", - imageUrl: "img/integrationIcons/Ncrack.svg", - }, - { - title: "Nikto", - type: "Webserver", - usecase: "Webserver Vulnerability Scanner", - path: "docs/scanners/nikto", - imageUrl: "img/integrationIcons/Nikto.svg", - }, - { - title: "Nmap", - type: "Network", - usecase: "Network discovery and security auditing", - path: "docs/scanners/nmap", - imageUrl: "img/integrationIcons/Nmap.svg", - }, - { - title: "Nuclei", - type: "Website", - usecase: "Nuclei is a fast, template based vulnerability scanner.", - path: "docs/scanners/nuclei", - imageUrl: "img/integrationIcons/Nuclei.svg", - }, - { - title: "Screenshooter", - type: "WebApplication", - usecase: "Takes Screenshots of websites", - path: "docs/scanners/screenshooter", - imageUrl: "img/integrationIcons/Screenshooter.svg", - }, - { - title: "Semgrep", - type: "Repository", - usecase: "Static Code Analysis", - path: "docs/scanners/semgrep", - imageUrl: "img/integrationIcons/Semgrep.svg", - }, - { - title: "SSH-audit", - type: "SSH", - usecase: "SSH Configuration and Policy Scanner", - path: "docs/scanners/ssh-audit", - imageUrl: "img/integrationIcons/Default.svg", - }, - { - title: "SSLyze", - type: "SSL", - usecase: "SSL/TLS Configuration Scanner", - path: "docs/scanners/sslyze", - imageUrl: "img/integrationIcons/SSLyze.svg", - }, - { - title: "Trivy SBOM", - type: "Container", - usecase: "Container Dependency Scanner", - path: "docs/scanners/trivy-sbom", - imageUrl: "img/integrationIcons/Default.svg", - }, - { - title: "Trivy", - type: "Container", - usecase: "Container Vulnerability Scanner", - path: "docs/scanners/trivy", - imageUrl: "img/integrationIcons/Trivy.svg", - }, - { - title: "Whatweb", - type: "Network", - usecase: "Website identification", - path: "docs/scanners/whatweb", - imageUrl: "img/integrationIcons/Whatweb.svg", - }, - { - title: "WPScan", - type: "CMS", - usecase: "Wordpress Vulnerability Scanner", - path: "docs/scanners/wpscan", - imageUrl: "img/integrationIcons/WPScan.svg", - }, - - { - title: "ZAP Automation Framework", - type: "WebApplication", - usecase: "WebApp & OpenAPI Vulnerability Scanner", - path: "docs/scanners/zap-automation-framework", - imageUrl: "img/integrationIcons/Default.svg", - }, -]; -export default { Hooks, Scanners }; diff --git a/documentation/src/pages/index.tsx b/documentation/src/pages/index.tsx index 80798dd485..0af8d853ad 100644 --- a/documentation/src/pages/index.tsx +++ b/documentation/src/pages/index.tsx @@ -5,7 +5,7 @@ import Link from "@docusaurus/Link"; import useBaseUrl from "@docusaurus/useBaseUrl"; import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; -import {useColorMode} from '@docusaurus/theme-common'; +import { useColorMode } from "@docusaurus/theme-common"; import Layout from "@theme/Layout"; import clsx from "clsx"; import React from "react"; @@ -55,23 +55,48 @@ function HomePage() {

Automated Security Testing Tool

- secureCodeBox is an OWASP project providing an automated - and scalable open source solution that integrates multiple security scanners with a simple and lightweight interface – - for continuous and automated security testing. + secureCodeBox is an{" "} + + OWASP project + {" "} + providing an automated and scalable open source solution that + integrates multiple security scanners with a simple and lightweight + interface – for continuous and automated security testing.

-
- +
+
+ Get Started - + +
+ +
+ + Try as service + +
@@ -143,10 +168,12 @@ function HomePage() { iteratec.

- OWASP is an open community dedicated to enabling organizations to conceive, - develop, acquire, operate, and maintain applications that can be trusted. - All of the OWASP tools, documents, forums, and chapters are free and open - to anyone interested in improving application security. + OWASP is an open community + dedicated to enabling organizations to conceive, develop, + acquire, operate, and maintain applications that can be + trusted. All of the OWASP tools, documents, forums, and + chapters are free and open to anyone interested in improving + application security.

} @@ -162,7 +189,7 @@ function HomePage() { href={`mailto:${ content.about.mail.recipient }?subject=${encodeURI( - content.about.mail.subject + content.about.mail.subject, )}&body=${encodeURI(content.about.mail.message)}`} > {content.about.button} @@ -186,7 +213,7 @@ function HomePage() { className={clsx( "col", styles.sponsor, - styles.defaultMarginBottom + styles.defaultMarginBottom, )} key={`sponsor nr${i}`} > diff --git a/documentation/static/img/cascades.drawio.svg b/documentation/static/img/cascades.drawio.svg index c1c1f07dc8..a2909e5e29 100644 --- a/documentation/static/img/cascades.drawio.svg +++ b/documentation/static/img/cascades.drawio.svg @@ -1,4 +1,4 @@ -
Subdomain Scan (amass)
*.example.com
Subdomain Scan (amass)...
Subdomain Finding
www.example.com
Subdomain Finding...
Subdomain Finding
mail.example.com
Subdomain Finding...
...
...
Portscan (nmap)
www.example.com
Portscan (nmap)...
Portscan (nmap)
www.example.com
Portscan (nmap)...
Open Port Finding
www.example.com:22
Open Port Finding...
Open Port Finding
www.example.com:443
Open Port Finding...
...
...
SSH Scan (ssh-audit)
www.example.com:22
SSH Scan (ssh-audit)...
Weak Credentials Scan (ncrack)
www.example.com:22
Weak Credentials Scan (ncrack)...
...
...
TLS Scan (sslyze)
www.example.com:443
TLS Scan (sslyze)...
Known Vulnerability Scan (nuclei)
www.example.com:443
Known Vulnerability Scan (nucle...
Text is not SVG - cannot display
\ No newline at end of file +
Subdomain Scan (subfinder)
*.example.com
Subdomain Scan (subfinder)...
Subdomain Finding
www.example.com
Subdomain Finding...
Subdomain Finding
mail.example.com
Subdomain Finding...
...
...
Portscan (nmap)
www.example.com
Portscan (nmap)...
Portscan (nmap)
www.example.com
Portscan (nmap)...
Open Port Finding
www.example.com:22
Open Port Finding...
Open Port Finding
www.example.com:443
Open Port Finding...
...
...
SSH Scan (ssh-audit)
www.example.com:22
SSH Scan (ssh-audit)...
Weak Credentials Scan (ncrack)
www.example.com:22
Weak Credentials Scan (ncrack)...
...
...
TLS Scan (sslyze)
www.example.com:443
TLS Scan (sslyze)...
Known Vulnerability Scan (nuclei)
www.example.com:443
Known Vulnerability Scan (nucle...
Text is not SVG - cannot display
\ No newline at end of file diff --git a/documentation/static/img/integrationIcons/ZAP-Advanced.svg b/documentation/static/img/integrationIcons/ZAP Automation Framework.svg similarity index 92% rename from documentation/static/img/integrationIcons/ZAP-Advanced.svg rename to documentation/static/img/integrationIcons/ZAP Automation Framework.svg index 84d1079d97..e09331d80d 100644 --- a/documentation/static/img/integrationIcons/ZAP-Advanced.svg +++ b/documentation/static/img/integrationIcons/ZAP Automation Framework.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/documentation/static/img/integrationIcons/ZAP-Advanced.svg.license b/documentation/static/img/integrationIcons/ZAP Automation Framework.svg.license similarity index 100% rename from documentation/static/img/integrationIcons/ZAP-Advanced.svg.license rename to documentation/static/img/integrationIcons/ZAP Automation Framework.svg.license diff --git a/documentation/static/img/integrationIcons/ZAP.svg b/documentation/static/img/integrationIcons/ZAP.svg deleted file mode 100644 index 84d1079d97..0000000000 --- a/documentation/static/img/integrationIcons/ZAP.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/documentation/static/img/integrationIcons/ZAP.svg.license b/documentation/static/img/integrationIcons/ZAP.svg.license deleted file mode 100644 index 04a5ed2863..0000000000 --- a/documentation/static/img/integrationIcons/ZAP.svg.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: the secureCodeBox authors - -SPDX-License-Identifier: LicenseRef-Proprietary-No-License diff --git a/hook-sdk/nodejs/.dockerignore b/hook-sdk/nodejs/.dockerignore index 2d2da7ae86..dbb6e76bfb 100644 --- a/hook-sdk/nodejs/.dockerignore +++ b/hook-sdk/nodejs/.dockerignore @@ -3,3 +3,4 @@ # SPDX-License-Identifier: Apache-2.0 node_modules/ +build/ diff --git a/hook-sdk/nodejs/.gitignore b/hook-sdk/nodejs/.gitignore index 2d2da7ae86..0ac983cff2 100644 --- a/hook-sdk/nodejs/.gitignore +++ b/hook-sdk/nodejs/.gitignore @@ -3,3 +3,4 @@ # SPDX-License-Identifier: Apache-2.0 node_modules/ +build/ \ No newline at end of file diff --git a/hook-sdk/nodejs/Dockerfile b/hook-sdk/nodejs/Dockerfile index 8bdfe87495..28ea961d48 100644 --- a/hook-sdk/nodejs/Dockerfile +++ b/hook-sdk/nodejs/Dockerfile @@ -2,17 +2,19 @@ # # SPDX-License-Identifier: Apache-2.0 -FROM node:22-alpine AS build -WORKDIR /home/app +FROM oven/bun:1.3 AS build +WORKDIR /home/app/ COPY package.json package-lock.json ./ -RUN npm ci --omit=dev +RUN bun install --ignore-scripts +COPY *.js ./ +RUN bun run build -FROM node:22-alpine +FROM node:24-alpine ARG NODE_ENV RUN addgroup --system --gid 1001 app && adduser app --system --uid 1001 --ingroup app WORKDIR /home/app/hook-wrapper/ -COPY --from=build --chown=root:root --chmod=755 /home/app/node_modules/ ./node_modules/ -COPY --chown=root:root --chmod=755 ./hook-wrapper.js ./package.json ./package-lock.json ./ +COPY --chown=root:root --chmod=755 ./package.json ./package-lock.json ./ +COPY --from=build --chown=root:root --chmod=755 /home/app/build/ ./ USER 1001 ENV NODE_ENV=${NODE_ENV:-production} -ENTRYPOINT ["node", "/home/app/hook-wrapper/hook-wrapper.js"] +ENTRYPOINT ["node", "--enable-source-maps", "/home/app/hook-wrapper/hook-wrapper.js"] diff --git a/hook-sdk/nodejs/package-lock.json b/hook-sdk/nodejs/package-lock.json index 1dcba7c7f5..7983d822fb 100644 --- a/hook-sdk/nodejs/package-lock.json +++ b/hook-sdk/nodejs/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "Apache-2.0", "dependencies": { - "@kubernetes/client-node": "^1.3.0" + "@kubernetes/client-node": "^1.4.0" } }, "node_modules/@jsep-plugin/assignment": { @@ -37,26 +37,25 @@ } }, "node_modules/@kubernetes/client-node": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-1.3.0.tgz", - "integrity": "sha512-IE0yrIpOT97YS5fg2QpzmPzm8Wmcdf4ueWMn+FiJSI3jgTTQT1u+LUhoYpdfhdHAVxdrNsaBg2C0UXSnOgMoCQ==", - "license": "Apache-2.0", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-1.4.0.tgz", + "integrity": "sha512-Zge3YvF7DJi264dU1b3wb/GmzR99JhUpqTvp+VGHfwZT+g7EOOYNScDJNZwXy9cszyIGPIs0VHr+kk8e95qqrA==", "dependencies": { "@types/js-yaml": "^4.0.1", - "@types/node": "^22.0.0", - "@types/node-fetch": "^2.6.9", + "@types/node": "^24.0.0", + "@types/node-fetch": "^2.6.13", "@types/stream-buffers": "^3.0.3", "form-data": "^4.0.0", "hpagent": "^1.2.0", "isomorphic-ws": "^5.0.0", "js-yaml": "^4.1.0", "jsonpath-plus": "^10.3.0", - "node-fetch": "^2.6.9", + "node-fetch": "^2.7.0", "openid-client": "^6.1.3", "rfc4648": "^1.3.0", "socks-proxy-agent": "^8.0.4", "stream-buffers": "^3.0.2", - "tar-fs": "^3.0.8", + "tar-fs": "^3.0.9", "ws": "^8.18.2" } }, @@ -67,22 +66,20 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.16.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.16.0.tgz", - "integrity": "sha512-B2egV9wALML1JCpv3VQoQ+yesQKAmNMBIAY7OteVrikcOcAkWm+dGL6qpeCktPjAv6N1JLnhbNiqS35UpFyBsQ==", - "license": "MIT", + "version": "24.10.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.9.tgz", + "integrity": "sha512-ne4A0IpG3+2ETuREInjPNhUGis1SFjv1d5asp8MzEAGtOZeTeHVDOYqOgqfhvseqg/iXty2hjBf1zAOb7RNiNw==", "dependencies": { - "undici-types": "~6.21.0" + "undici-types": "~7.16.0" } }, "node_modules/@types/node-fetch": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", - "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", - "license": "MIT", + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", "dependencies": { "@types/node": "*", - "form-data": "^4.0.0" + "form-data": "^4.0.4" } }, "node_modules/@types/stream-buffers": { @@ -111,7 +108,7 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/b4a": { "version": "1.6.7", @@ -195,7 +192,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" @@ -235,7 +231,7 @@ "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { "node": ">=0.4.0" } @@ -244,7 +240,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", @@ -267,7 +262,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", "engines": { "node": ">= 0.4" } @@ -276,7 +270,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", "engines": { "node": ">= 0.4" } @@ -285,7 +278,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, @@ -297,7 +289,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", @@ -315,10 +306,9 @@ "license": "MIT" }, "node_modules/form-data": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", - "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", - "license": "MIT", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -334,7 +324,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -343,7 +332,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", @@ -367,7 +355,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" @@ -380,7 +367,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -392,7 +378,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -404,7 +389,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, @@ -419,7 +403,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -466,9 +449,9 @@ } }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dependencies": { "argparse": "^2.0.1" }, @@ -513,25 +496,24 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/mime-db": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", - "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.32", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", - "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { - "mime-db": "1.49.0" + "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" @@ -673,9 +655,9 @@ } }, "node_modules/tar-fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", - "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "license": "MIT", "dependencies": { "pump": "^3.0.0", @@ -713,10 +695,9 @@ "license": "MIT" }, "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "license": "MIT" + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==" }, "node_modules/webidl-conversions": { "version": "3.0.1", diff --git a/hook-sdk/nodejs/package.json b/hook-sdk/nodejs/package.json index c25304386e..4e65f5a75f 100644 --- a/hook-sdk/nodejs/package.json +++ b/hook-sdk/nodejs/package.json @@ -4,11 +4,13 @@ "type": "module", "description": "Handles external communication required for all secureCodeBox Hooks", "main": "hook-wrapper.js", - "scripts": {}, + "scripts": { + "build": "bun build --production --target=node --outdir=build/ --external=./hook/hook.js --sourcemap=external --minify ./hook-wrapper.js" + }, "keywords": [], "author": "iteratec GmbH", "license": "Apache-2.0", "dependencies": { - "@kubernetes/client-node": "^1.3.0" + "@kubernetes/client-node": "^1.4.0" } } \ No newline at end of file diff --git a/hooks/cascading-scans/.helm-docs.gotmpl b/hooks/cascading-scans/.helm-docs.gotmpl index 4218a58b00..f1afadb0d5 100644 --- a/hooks/cascading-scans/.helm-docs.gotmpl +++ b/hooks/cascading-scans/.helm-docs.gotmpl @@ -26,7 +26,7 @@ usecase: "Cascading Scans based declarative Rules." The Cascading Scans Hook can be used to start additional scans based on the results of other scans. This allows you to create powerful setups to automatically discover targets, and then trigger more specialized scans for the type of target that was discovered. -![Diagram of CascadingScans showing one amass scans for example.com finding two subdomains. These then trigger a port scan each. An identified ssh port then gets a SSH Scan and a Ncrack scan triggered. A https port gets a sslyze and a nuclei scan triggered.](https://www.securecodebox.io/img/cascades.drawio.svg) +![Diagram of CascadingScans showing one subfinder scan for example.com finding two subdomains. These then trigger a port scan each. An identified ssh port then gets a SSH Scan and a Ncrack scan triggered. A https port gets a sslyze and a nuclei scan triggered.](https://www.securecodebox.io/img/cascades.drawio.svg) The so called `CascadingRules` consist of a `matches` section which contains one or multiple rules which are compared against `findings`. When a `finding` matches a `rule` the `scanSpec` section will then be used to create a new scan. diff --git a/hooks/cascading-scans/Chart.yaml b/hooks/cascading-scans/Chart.yaml index 97909a164f..6a90cb2d5d 100644 --- a/hooks/cascading-scans/Chart.yaml +++ b/hooks/cascading-scans/Chart.yaml @@ -4,7 +4,7 @@ apiVersion: v2 name: cascading-scans -description: Starts possible subsequent security scans based on findings (e.g. open ports found by NMAP or subdomains found by AMASS). +description: Starts possible subsequent security scans based on findings (e.g. open ports found by Nmap or subdomains found by Subfinder). type: application diff --git a/hooks/cascading-scans/README.md b/hooks/cascading-scans/README.md index a5bf528f73..ea06300ac7 100644 --- a/hooks/cascading-scans/README.md +++ b/hooks/cascading-scans/README.md @@ -37,7 +37,7 @@ Otherwise your changes will be reverted/overwritten automatically due to the bui The Cascading Scans Hook can be used to start additional scans based on the results of other scans. This allows you to create powerful setups to automatically discover targets, and then trigger more specialized scans for the type of target that was discovered. -![Diagram of CascadingScans showing one amass scans for example.com finding two subdomains. These then trigger a port scan each. An identified ssh port then gets a SSH Scan and a Ncrack scan triggered. A https port gets a sslyze and a nuclei scan triggered.](https://www.securecodebox.io/img/cascades.drawio.svg) +![Diagram of CascadingScans showing one subfinder scan for example.com finding two subdomains. These then trigger a port scan each. An identified ssh port then gets a SSH Scan and a Ncrack scan triggered. A https port gets a sslyze and a nuclei scan triggered.](https://www.securecodebox.io/img/cascades.drawio.svg) The so called `CascadingRules` consist of a `matches` section which contains one or multiple rules which are compared against `findings`. When a `finding` matches a `rule` the `scanSpec` section will then be used to create a new scan. diff --git a/hooks/cascading-scans/docs/README.ArtifactHub.md b/hooks/cascading-scans/docs/README.ArtifactHub.md index 9f136e53d6..87bb5a5bde 100644 --- a/hooks/cascading-scans/docs/README.ArtifactHub.md +++ b/hooks/cascading-scans/docs/README.ArtifactHub.md @@ -45,7 +45,7 @@ You can find resources to help you get started on our [documentation website](ht The Cascading Scans Hook can be used to start additional scans based on the results of other scans. This allows you to create powerful setups to automatically discover targets, and then trigger more specialized scans for the type of target that was discovered. -![Diagram of CascadingScans showing one amass scans for example.com finding two subdomains. These then trigger a port scan each. An identified ssh port then gets a SSH Scan and a Ncrack scan triggered. A https port gets a sslyze and a nuclei scan triggered.](https://www.securecodebox.io/img/cascades.drawio.svg) +![Diagram of CascadingScans showing one subfinder scan for example.com finding two subdomains. These then trigger a port scan each. An identified ssh port then gets a SSH Scan and a Ncrack scan triggered. A https port gets a sslyze and a nuclei scan triggered.](https://www.securecodebox.io/img/cascades.drawio.svg) The so called `CascadingRules` consist of a `matches` section which contains one or multiple rules which are compared against `findings`. When a `finding` matches a `rule` the `scanSpec` section will then be used to create a new scan. diff --git a/hooks/cascading-scans/docs/README.DockerHub-Hook.md b/hooks/cascading-scans/docs/README.DockerHub-Hook.md index 50f9b607df..b41dfd009c 100644 --- a/hooks/cascading-scans/docs/README.DockerHub-Hook.md +++ b/hooks/cascading-scans/docs/README.DockerHub-Hook.md @@ -56,7 +56,7 @@ docker pull securecodebox/hook-cascading-scans The Cascading Scans Hook can be used to start additional scans based on the results of other scans. This allows you to create powerful setups to automatically discover targets, and then trigger more specialized scans for the type of target that was discovered. -![Diagram of CascadingScans showing one amass scans for example.com finding two subdomains. These then trigger a port scan each. An identified ssh port then gets a SSH Scan and a Ncrack scan triggered. A https port gets a sslyze and a nuclei scan triggered.](https://www.securecodebox.io/img/cascades.drawio.svg) +![Diagram of CascadingScans showing one subfinder scan for example.com finding two subdomains. These then trigger a port scan each. An identified ssh port then gets a SSH Scan and a Ncrack scan triggered. A https port gets a sslyze and a nuclei scan triggered.](https://www.securecodebox.io/img/cascades.drawio.svg) The so called `CascadingRules` consist of a `matches` section which contains one or multiple rules which are compared against `findings`. When a `finding` matches a `rule` the `scanSpec` section will then be used to create a new scan. diff --git a/hooks/cascading-scans/hook/Dockerfile b/hooks/cascading-scans/hook/Dockerfile index a941c67eed..2fee30f3f3 100644 --- a/hooks/cascading-scans/hook/Dockerfile +++ b/hooks/cascading-scans/hook/Dockerfile @@ -4,13 +4,13 @@ ARG namespace ARG baseImageTag -FROM node:22-alpine AS install +FROM node:24-alpine AS install RUN mkdir -p /home/app WORKDIR /home/app COPY package.json package-lock.json ./ -RUN npm ci --omit=dev +RUN npm ci --omit=dev --ignore-scripts -FROM node:22-alpine AS build +FROM node:24-alpine AS build RUN mkdir -p /home/app WORKDIR /home/app COPY package.json package-lock.json ./ diff --git a/hooks/cascading-scans/hook/hook.test.js b/hooks/cascading-scans/hook/hook.test.js index 66dbd6da95..fcd4a54ad3 100644 --- a/hooks/cascading-scans/hook/hook.test.js +++ b/hooks/cascading-scans/hook/hook.test.js @@ -1033,7 +1033,7 @@ test("should merge initContainers into cascaded scan", () => { parentScan.spec.initContainers = [ { name: "test-init", - image: "bitnami/git", + image: "alpine/git", command: ["whoami"], }, ]; @@ -1062,7 +1062,7 @@ test("should merge initContainers into cascaded scan", () => { "command": [ "whoami", ], - "image": "bitnami/git", + "image": "alpine/git", "name": "test-init", }, { @@ -1094,7 +1094,7 @@ test("should not merge initContainers into cascaded scan if not instructed", () parentScan.spec.initContainers = [ { name: "test-init", - image: "bitnami/git", + image: "alpine/git", command: ["whoami"], }, ]; diff --git a/hooks/cascading-scans/hook/package-lock.json b/hooks/cascading-scans/hook/package-lock.json index 07e2def7e5..0458f10414 100644 --- a/hooks/cascading-scans/hook/package-lock.json +++ b/hooks/cascading-scans/hook/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@kubernetes/client-node": "^1.3.0", "ip-address": "^10.0.1", - "lodash-es": "^4.17.21", + "lodash-es": "^4.17.23", "matcher": "^5.0.0", "mustache": "^4.2.0", "parse-domain": "^8.2.2" @@ -874,10 +874,9 @@ "license": "MIT" }, "node_modules/form-data": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", - "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", - "license": "MIT", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -1075,10 +1074,9 @@ } }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dependencies": { "argparse": "^2.0.1" }, @@ -1120,10 +1118,9 @@ } }, "node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "license": "MIT" + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz", + "integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==" }, "node_modules/matcher": { "version": "5.0.0", @@ -1360,10 +1357,9 @@ } }, "node_modules/tar-fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", - "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", - "license": "MIT", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5" diff --git a/hooks/cascading-scans/hook/package.json b/hooks/cascading-scans/hook/package.json index be0ccea304..3ca579273c 100644 --- a/hooks/cascading-scans/hook/package.json +++ b/hooks/cascading-scans/hook/package.json @@ -40,7 +40,7 @@ "dependencies": { "@kubernetes/client-node": "^1.3.0", "ip-address": "^10.0.1", - "lodash-es": "^4.17.21", + "lodash-es": "^4.17.23", "matcher": "^5.0.0", "mustache": "^4.2.0", "parse-domain": "^8.2.2" diff --git a/hooks/cascading-scans/tests/__snapshot__/cascading-scans_test.yaml.snap b/hooks/cascading-scans/tests/__snapshot__/cascading-scans_test.yaml.snap index 59c1494779..a91282dfb7 100644 --- a/hooks/cascading-scans/tests/__snapshot__/cascading-scans_test.yaml.snap +++ b/hooks/cascading-scans/tests/__snapshot__/cascading-scans_test.yaml.snap @@ -1,6 +1,6 @@ matches the snapshot: 1: | - raw: |2 + raw: | Cascading Scan Hook deployed. This will allow you to start Scans based on previous findings. diff --git a/hooks/finding-post-processing/hook/Dockerfile b/hooks/finding-post-processing/hook/Dockerfile index dc64c7bf24..83625a615a 100644 --- a/hooks/finding-post-processing/hook/Dockerfile +++ b/hooks/finding-post-processing/hook/Dockerfile @@ -4,11 +4,11 @@ ARG namespace ARG baseImageTag -FROM node:22-alpine AS build +FROM node:24-alpine AS build RUN mkdir -p /home/app WORKDIR /home/app COPY package.json package-lock.json ./ -RUN npm ci --omit=dev +RUN npm ci --omit=dev --ignore-scripts FROM ${namespace:-securecodebox}/hook-sdk-nodejs:${baseImageTag:-latest} WORKDIR /home/app/hook-wrapper/hook/ diff --git a/hooks/finding-post-processing/tests/__snapshot__/finding-post-processing_test.yaml.snap b/hooks/finding-post-processing/tests/__snapshot__/finding-post-processing_test.yaml.snap index 6491d79a3f..0d76f02841 100644 --- a/hooks/finding-post-processing/tests/__snapshot__/finding-post-processing_test.yaml.snap +++ b/hooks/finding-post-processing/tests/__snapshot__/finding-post-processing_test.yaml.snap @@ -1,7 +1,6 @@ matches the snapshot: 1: | - raw: |2 - + raw: | FindingPostProcessing Hook deployed. This will add postprocessing on every finding in this namespace matching these rules: [{"matches":[{"anyOf":[{"attributes":{"port":21,"state":"open"},"category":"Open Port"},{"attributes":{"port":389,"state":"open"},"category":"Open Port"}]}],"override":{"description":"Telnet is bad","severity":"high"}}]. 2: | diff --git a/hooks/generic-webhook/tests/__snapshot__/generic-webhook_test.yaml.snap b/hooks/generic-webhook/tests/__snapshot__/generic-webhook_test.yaml.snap index f6b7db66df..51b945b48c 100644 --- a/hooks/generic-webhook/tests/__snapshot__/generic-webhook_test.yaml.snap +++ b/hooks/generic-webhook/tests/__snapshot__/generic-webhook_test.yaml.snap @@ -1,6 +1,6 @@ matches the snapshot: 1: | - raw: |2 + raw: | GenericWebhook deployed. Will send requests to: POST http://example.com diff --git a/hooks/notification/hook/Dockerfile b/hooks/notification/hook/Dockerfile index 28186832f2..a74d036bbd 100644 --- a/hooks/notification/hook/Dockerfile +++ b/hooks/notification/hook/Dockerfile @@ -4,13 +4,13 @@ ARG namespace ARG baseImageTag -FROM node:22-alpine AS install +FROM node:24-alpine AS install RUN mkdir -p /home/app WORKDIR /home/app COPY package.json package-lock.json ./ -RUN npm ci --omit=dev +RUN npm ci --omit=dev --ignore-scripts -FROM node:22-alpine AS build +FROM node:24-alpine AS build RUN mkdir -p /home/app WORKDIR /home/app COPY package.json package-lock.json ./ diff --git a/hooks/notification/hook/package-lock.json b/hooks/notification/hook/package-lock.json index dacbc845ce..f41944635a 100644 --- a/hooks/notification/hook/package-lock.json +++ b/hooks/notification/hook/package-lock.json @@ -10,9 +10,9 @@ "license": "Apache-2.0", "dependencies": { "@types/js-yaml": "^4.0.2", - "js-yaml": "^4.1.0", + "js-yaml": "^4.1.1", "lodash-es": "^4.17.21", - "nodemailer": "^6.10.1", + "nodemailer": "^7.0.11", "nunjucks": "^3.2.4" }, "devDependencies": { @@ -1291,11 +1291,10 @@ } }, "node_modules/form-data": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", - "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "dev": true, - "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -1568,9 +1567,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dependencies": { "argparse": "^2.0.1" }, @@ -1707,10 +1706,9 @@ } }, "node_modules/nodemailer": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.10.1.tgz", - "integrity": "sha512-Z+iLaBGVaSjbIzQ4pX6XV41HrooLsQ10ZWPUehGmuantvzWoDVBnmsdUcOIDM1t+yPor5pDhVlDESgOMEGxhHA==", - "license": "MIT-0", + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.11.tgz", + "integrity": "sha512-gnXhNRE0FNhD7wPSCGhdNh46Hs6nm+uTyg+Kq0cZukNQiYdnCsoQjodNP9BQVG9XrcK/v6/MgpAPBUFyzh9pvw==", "engines": { "node": ">=6.0.0" } @@ -1901,9 +1899,9 @@ } }, "node_modules/tar-fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", - "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "dev": true, "license": "MIT", "dependencies": { @@ -2816,9 +2814,9 @@ } }, "form-data": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", - "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "dev": true, "requires": { "asynckit": "^0.4.0", @@ -3006,9 +3004,9 @@ "dev": true }, "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "requires": { "argparse": "^2.0.1" } @@ -3096,9 +3094,9 @@ } }, "nodemailer": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.10.1.tgz", - "integrity": "sha512-Z+iLaBGVaSjbIzQ4pX6XV41HrooLsQ10ZWPUehGmuantvzWoDVBnmsdUcOIDM1t+yPor5pDhVlDESgOMEGxhHA==" + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.11.tgz", + "integrity": "sha512-gnXhNRE0FNhD7wPSCGhdNh46Hs6nm+uTyg+Kq0cZukNQiYdnCsoQjodNP9BQVG9XrcK/v6/MgpAPBUFyzh9pvw==" }, "nunjucks": { "version": "3.2.4", @@ -3232,9 +3230,9 @@ } }, "tar-fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", - "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "dev": true, "requires": { "bare-fs": "^4.0.1", diff --git a/hooks/notification/hook/package.json b/hooks/notification/hook/package.json index cd76149803..ff8998029c 100644 --- a/hooks/notification/hook/package.json +++ b/hooks/notification/hook/package.json @@ -35,9 +35,9 @@ }, "dependencies": { "@types/js-yaml": "^4.0.2", - "js-yaml": "^4.1.0", + "js-yaml": "^4.1.1", "lodash-es": "^4.17.21", - "nodemailer": "^6.10.1", + "nodemailer": "^7.0.11", "nunjucks": "^3.2.4" } } diff --git a/hooks/notification/tests/__snapshot__/notification_test.yaml.snap b/hooks/notification/tests/__snapshot__/notification_test.yaml.snap index 4887549b2b..8ff76dc93d 100644 --- a/hooks/notification/tests/__snapshot__/notification_test.yaml.snap +++ b/hooks/notification/tests/__snapshot__/notification_test.yaml.snap @@ -1,6 +1,6 @@ matches the snapshot: 1: | - raw: |2 + raw: | Notification hook deployed. Will send requests to: - slack: SOME_ENV_KEY @@ -11,7 +11,7 @@ matches the snapshot: 2: | apiVersion: v1 data: - notification-channel.yaml: |2 + notification-channel.yaml: | - endPoint: SOME_ENV_KEY name: slack rules: diff --git a/hooks/persistence-azure-monitor/tests/__snapshot__/persistence-azure-monitor_test.yaml.snap b/hooks/persistence-azure-monitor/tests/__snapshot__/persistence-azure-monitor_test.yaml.snap index 75aefdeb7b..0194bfda50 100644 --- a/hooks/persistence-azure-monitor/tests/__snapshot__/persistence-azure-monitor_test.yaml.snap +++ b/hooks/persistence-azure-monitor/tests/__snapshot__/persistence-azure-monitor_test.yaml.snap @@ -1,6 +1,6 @@ matches the snapshot: 1: | - raw: |2 + raw: | Azure Monitor PersistenceProvider deployed. 2: | apiVersion: execution.securecodebox.io/v1 diff --git a/hooks/persistence-defectdojo/hook/.sdkmanrc b/hooks/persistence-defectdojo/hook/.sdkmanrc index 766d119f69..39bc11c1fa 100644 --- a/hooks/persistence-defectdojo/hook/.sdkmanrc +++ b/hooks/persistence-defectdojo/hook/.sdkmanrc @@ -4,4 +4,4 @@ # Enable auto-env through the sdkman_auto_env config # Add key=value pairs of SDKs to use below -java=17.0.13-tem +java=17.0.16-tem diff --git a/hooks/persistence-defectdojo/hook/Dockerfile b/hooks/persistence-defectdojo/hook/Dockerfile index 0693546487..76c812f5a0 100644 --- a/hooks/persistence-defectdojo/hook/Dockerfile +++ b/hooks/persistence-defectdojo/hook/Dockerfile @@ -8,7 +8,7 @@ WORKDIR /home/gradle/src RUN ./gradlew build -x test FROM gcr.io/distroless/java17-debian12:nonroot -COPY --from=build --chown=nonroot:nonroot /home/gradle/src/build/libs/defectdojo-persistenceprovider-*.jar /app/defectdojo-persistenceprovider.jar +COPY --from=build --chown=root:root --chmod=755 /home/gradle/src/build/libs/defectdojo-persistenceprovider-*.jar /app/defectdojo-persistenceprovider.jar WORKDIR /app # TLS Config works around an issue in OpenJDK... See: https://github.com/kubernetes-client/java/issues/854 ENTRYPOINT ["java", "-Djdk.tls.client.protocols=TLSv1.2", "-jar", "/app/defectdojo-persistenceprovider.jar"] diff --git a/hooks/persistence-defectdojo/hook/build.gradle b/hooks/persistence-defectdojo/hook/build.gradle index 88da75664a..306060cc0e 100644 --- a/hooks/persistence-defectdojo/hook/build.gradle +++ b/hooks/persistence-defectdojo/hook/build.gradle @@ -4,11 +4,11 @@ plugins { id "java" - id "io.freefair.lombok" version "8.14" + id "io.freefair.lombok" version "9.2.0" // https://github.com/ben-manes/gradle-versions-plugin // Run: ./gradlew dependencyUpdates -Drevision=release - id "com.github.ben-manes.versions" version "0.52.0" - id "org.sonarqube" version "6.2.0.5505" + id "com.github.ben-manes.versions" version "0.53.0" + id "org.sonarqube" version "7.2.2.6593" } group = "io.securecodebox" @@ -24,20 +24,24 @@ repositories { dependencies { implementation group: "io.securecodebox", name: "defectdojo-client", version: "2.0.1" implementation group: "io.kubernetes", name: "client-java", version: "20.0.1" - implementation group: "org.springframework", name: "spring-web", version: "6.2.8" - implementation group: "com.fasterxml.jackson.core", name: "jackson-core", version: "2.19.1" - implementation group: "com.fasterxml.jackson.core", name: "jackson-annotations", version: "2.19.1" - implementation group: "com.fasterxml.jackson.core", name: "jackson-databind", version: "2.19.1" - implementation group: "com.fasterxml.jackson.datatype", name: "jackson-datatype-jsr310", version: "2.19.1" + // will not be updated to 7.0.0 because it no longer implements a class + // so it causes issues with the version in the defectdojo client + implementation group: "org.springframework", name: "spring-web", version: "6.2.12" + // https://github.com/FasterXML/jackson-bom + implementation platform("com.fasterxml.jackson:jackson-bom:2.21.0") + implementation "com.fasterxml.jackson.core:jackson-core" + implementation "com.fasterxml.jackson.core:jackson-annotations" + implementation "com.fasterxml.jackson.core:jackson-databind" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" implementation group: "org.slf4j", name: "slf4j-api", version: "2.0.17" implementation group: "org.slf4j", name: "slf4j-log4j12", version: "2.0.17" // If I try to notate this like the others (with separate strings) I got errors. No idea why sh... Gradle // want it like this. It is the official documented example: // https://github.com/junit-team/junit5-samples/blob/r5.10.0/junit5-jupiter-starter-gradle/build.gradle - testImplementation(platform("org.junit:junit-bom:5.13.3")) + testImplementation(platform("org.junit:junit-bom:6.0.2")) testImplementation("org.junit.jupiter:junit-jupiter") - testImplementation group: "org.mockito", name: "mockito-core", version: "5.18.0" - testImplementation group: "org.mockito", name: "mockito-junit-jupiter", version: "5.18.0" + testImplementation group: "org.mockito", name: "mockito-core", version: "5.21.0" + testImplementation group: "org.mockito", name: "mockito-junit-jupiter", version: "5.21.0" testImplementation group: 'org.hamcrest', name: 'java-hamcrest', version: '2.0.0.0' testImplementation group: 'uk.org.webcompere', name: 'system-stubs-jupiter', version: '2.1.8' testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") diff --git a/hooks/persistence-defectdojo/tests/__snapshot__/persistence-defectdojo_test.yaml.snap b/hooks/persistence-defectdojo/tests/__snapshot__/persistence-defectdojo_test.yaml.snap index cdef1bfcc5..92d3a37bc8 100644 --- a/hooks/persistence-defectdojo/tests/__snapshot__/persistence-defectdojo_test.yaml.snap +++ b/hooks/persistence-defectdojo/tests/__snapshot__/persistence-defectdojo_test.yaml.snap @@ -1,6 +1,6 @@ matches the snapshot: 1: | - raw: "\nDefectDojo PersistenceProvider succesfully deployed \U0001F389.\n" + raw: "DefectDojo PersistenceProvider succesfully deployed \U0001F389.\n" 2: | apiVersion: execution.securecodebox.io/v1 kind: ScanCompletionHook diff --git a/hooks/persistence-dependencytrack/hook/hook.js b/hooks/persistence-dependencytrack/hook/hook.js index b0974e02f2..de8b4bc5b4 100644 --- a/hooks/persistence-dependencytrack/hook/hook.js +++ b/hooks/persistence-dependencytrack/hook/hook.js @@ -15,7 +15,16 @@ export async function handle({ return; } - const result = await getRawResults(); + const rawResult = await getRawResults(); + + let result; + try { + result = JSON.parse(rawResult); + } catch { + console.log("Response is not a valid json object."); + return; + } + if (result.bomFormat !== "CycloneDX") { // Not a CycloneDX SBOM, cannot be handled by Dependency-Track, ignore console.log( diff --git a/hooks/persistence-dependencytrack/hook/hook.test.js b/hooks/persistence-dependencytrack/hook/hook.test.js index b9a41bf0ae..64018b91b5 100644 --- a/hooks/persistence-dependencytrack/hook/hook.test.js +++ b/hooks/persistence-dependencytrack/hook/hook.test.js @@ -18,7 +18,9 @@ beforeEach(() => { test("should not send a post request if not an SBOM scan", async () => { const result = {}; - const getRawResults = async () => result; + const stringResult = JSON.stringify(result); + + const getRawResults = async () => stringResult; const scan = { metadata: { @@ -53,7 +55,9 @@ test("should not send a post request if not a CycloneDX SBOM", async () => { }, }; - const getRawResults = async () => result; + const stringResult = JSON.stringify(result); + + const getRawResults = async () => stringResult; // technically we're saying here that this scan is a CycloneDX scan even though we're then sending something looking like an SPDX SBOM const scan = { @@ -84,7 +88,9 @@ test("should send a post request to the url when fired", async () => { }, }; - const getRawResults = async () => result; + const stringResult = JSON.stringify(result); + + const getRawResults = async () => stringResult; const scan = { metadata: { @@ -169,7 +175,9 @@ test.each([ }, }; - const getRawResults = async () => result; + const stringResult = JSON.stringify(result); + + const getRawResults = async () => stringResult; const scan = { metadata: { diff --git a/hooks/persistence-elastic/dashboard-importer/Dockerfile b/hooks/persistence-elastic/dashboard-importer/Dockerfile index 6613747434..e7b55f396d 100644 --- a/hooks/persistence-elastic/dashboard-importer/Dockerfile +++ b/hooks/persistence-elastic/dashboard-importer/Dockerfile @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 -FROM alpine:3.21 +FROM alpine:3.23 RUN apk add --no-cache curl bash diff --git a/hooks/persistence-elastic/dashboard-importer/dashboards/subdomain-overview.json b/hooks/persistence-elastic/dashboard-importer/dashboards/subdomain-overview.json index 6a1e7cddc0..d85a5bef0a 100644 --- a/hooks/persistence-elastic/dashboard-importer/dashboards/subdomain-overview.json +++ b/hooks/persistence-elastic/dashboard-importer/dashboards/subdomain-overview.json @@ -7,7 +7,7 @@ "updated_at": "2020-10-07T06:45:26.362Z", "version": "WzcxLDFd", "attributes": { - "title": "Subdomain (Amass) Overview", + "title": "Subdomain (Subfinder) Overview", "hits": 0, "description": "", "panelsJSON": "[{\"version\":\"7.8.0\",\"gridData\":{\"x\":0,\"y\":0,\"w\":10,\"h\":8,\"i\":\"3733ddef-b40f-4217-a0b2-8ba0b33bda55\"},\"panelIndex\":\"3733ddef-b40f-4217-a0b2-8ba0b33bda55\",\"embeddableConfig\":{},\"panelRefName\":\"panel_0\"},{\"version\":\"7.8.0\",\"gridData\":{\"x\":10,\"y\":0,\"w\":7,\"h\":8,\"i\":\"641856dc-33f7-448f-8b1d-d5650e36ee5b\"},\"panelIndex\":\"641856dc-33f7-448f-8b1d-d5650e36ee5b\",\"embeddableConfig\":{},\"panelRefName\":\"panel_1\"},{\"version\":\"7.8.0\",\"gridData\":{\"x\":17,\"y\":0,\"w\":7,\"h\":8,\"i\":\"65a2dafa-4d83-4a82-a8c8-d29f78c5de07\"},\"panelIndex\":\"65a2dafa-4d83-4a82-a8c8-d29f78c5de07\",\"embeddableConfig\":{},\"panelRefName\":\"panel_2\"},{\"version\":\"7.8.0\",\"gridData\":{\"x\":24,\"y\":0,\"w\":24,\"h\":23,\"i\":\"d331a001-f70b-4991-a050-a4347db862f2\"},\"panelIndex\":\"d331a001-f70b-4991-a050-a4347db862f2\",\"embeddableConfig\":{},\"panelRefName\":\"panel_3\"},{\"version\":\"7.8.0\",\"gridData\":{\"x\":0,\"y\":8,\"w\":24,\"h\":15,\"i\":\"dceb4446-16c3-4cb8-b1df-0062d56bac3f\"},\"panelIndex\":\"dceb4446-16c3-4cb8-b1df-0062d56bac3f\",\"embeddableConfig\":{},\"panelRefName\":\"panel_4\"},{\"version\":\"7.8.0\",\"gridData\":{\"x\":0,\"y\":23,\"w\":48,\"h\":16,\"i\":\"2569f9de-cacd-4747-89ae-73bf6d336d9e\"},\"panelIndex\":\"2569f9de-cacd-4747-89ae-73bf6d336d9e\",\"embeddableConfig\":{},\"panelRefName\":\"panel_5\"}]", @@ -201,10 +201,10 @@ "description": "", "hits": 0, "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"highlightAll\":true,\"version\":true,\"query\":{\"query\":\"*\",\"language\":\"kuery\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\",\"filter\":[{\"meta\":{\"alias\":null,\"negate\":false,\"disabled\":false,\"type\":\"phrase\",\"key\":\"scan_type\",\"params\":{\"query\":\"amass\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"query\":{\"match_phrase\":{\"scan_type\":\"amass\"}},\"$state\":{\"store\":\"appState\"}},{\"meta\":{\"alias\":null,\"negate\":false,\"disabled\":false,\"type\":\"phrase\",\"key\":\"type\",\"params\":{\"query\":\"finding\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index\"},\"query\":{\"match_phrase\":{\"type\":\"finding\"}},\"$state\":{\"store\":\"appState\"}}]}" + "searchSourceJSON": "{\"highlightAll\":true,\"version\":true,\"query\":{\"query\":\"*\",\"language\":\"kuery\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\",\"filter\":[{\"meta\":{\"alias\":null,\"negate\":false,\"disabled\":false,\"type\":\"phrase\",\"key\":\"scan_type\",\"params\":{\"query\":\"subfinder\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"query\":{\"match_phrase\":{\"scan_type\":\"subfinder\"}},\"$state\":{\"store\":\"appState\"}},{\"meta\":{\"alias\":null,\"negate\":false,\"disabled\":false,\"type\":\"phrase\",\"key\":\"type\",\"params\":{\"query\":\"finding\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index\"},\"query\":{\"match_phrase\":{\"type\":\"finding\"}},\"$state\":{\"store\":\"appState\"}}]}" }, "sort": [], - "title": "AMASS Findings", + "title": "Subfinder Findings", "version": 1 }, "references": [ diff --git a/hooks/persistence-elastic/hook/Dockerfile b/hooks/persistence-elastic/hook/Dockerfile index dc64c7bf24..83625a615a 100644 --- a/hooks/persistence-elastic/hook/Dockerfile +++ b/hooks/persistence-elastic/hook/Dockerfile @@ -4,11 +4,11 @@ ARG namespace ARG baseImageTag -FROM node:22-alpine AS build +FROM node:24-alpine AS build RUN mkdir -p /home/app WORKDIR /home/app COPY package.json package-lock.json ./ -RUN npm ci --omit=dev +RUN npm ci --omit=dev --ignore-scripts FROM ${namespace:-securecodebox}/hook-sdk-nodejs:${baseImageTag:-latest} WORKDIR /home/app/hook-wrapper/hook/ diff --git a/hooks/persistence-elastic/hook/hook.js b/hooks/persistence-elastic/hook/hook.js index e9ea8077e6..9079005a56 100644 --- a/hooks/persistence-elastic/hook/hook.js +++ b/hooks/persistence-elastic/hook/hook.js @@ -105,9 +105,10 @@ export async function handle({ }, ]); - const { body: bulkResponse } = await client.bulk({ refresh: true, body }); + const bulkResponseRaw = await client.bulk({ refresh: true, body }); + const bulkResponse = bulkResponseRaw?.body ?? bulkResponseRaw; - if (bulkResponse.errors) { + if (bulkResponse?.errors) { console.error("Bulk Request had errors:"); console.log(bulkResponse); } diff --git a/hooks/persistence-elastic/hook/hook.test.js b/hooks/persistence-elastic/hook/hook.test.js index 08b5e7b16e..84c9184f0c 100644 --- a/hooks/persistence-elastic/hook/hook.test.js +++ b/hooks/persistence-elastic/hook/hook.test.js @@ -5,6 +5,7 @@ import { handle } from "./hook"; let elasticClient; +const buildGetFindings = (findings) => async () => findings; beforeEach(() => { elasticClient = { @@ -32,10 +33,36 @@ const scan = { const testDate = new Date("2020-11-11"); +const scanDocumentBody = { + "@timestamp": testDate, + id: scan.metadata.uid, + labels: scan.metadata.labels, + name: scan.metadata.name, + parameters: scan.spec.parameters, + scan_type: scan.spec.scanType, + type: "scan", +}; + +const expectScanIndexCalledWith = (index, client = elasticClient) => { + expect(client.index).toHaveBeenCalledTimes(1); + expect(client.index).toHaveBeenCalledWith({ + body: scanDocumentBody, + index, + }); +}; + +const findingsWithOpenPort = [ + { + id: "4560b3e6-1219-4f5f-9b44-6579f5a32407", + name: "Port 5601 is open", + category: "Open Port", + }, +]; + test("should only send scan summary document if no findings are passing in", async () => { const findings = []; - const getFindings = async () => findings; + const getFindings = buildGetFindings(findings); await handle({ getFindings, @@ -46,34 +73,12 @@ test("should only send scan summary document if no findings are passing in", asy client: elasticClient, }); - expect(elasticClient.index).toHaveBeenCalledTimes(1); - expect(elasticClient.index).toHaveBeenCalledWith({ - body: { - "@timestamp": testDate, - id: "09988cdf-1fc7-4f85-95ee-1b1d65dbc7cc", - labels: { - company: "iteratec", - }, - name: "demo-scan", - parameters: ["-Pn", "localhost"], - scan_type: "Nmap", - type: "scan", - }, - index: `scb_default_2020-11-11`, - }); + expectScanIndexCalledWith(`scb_default_2020-11-11`); expect(elasticClient.bulk).not.toHaveBeenCalled(); }); test("should send findings to elasticsearch with given prefix", async () => { - const findings = [ - { - id: "4560b3e6-1219-4f5f-9b44-6579f5a32407", - name: "Port 5601 is open", - category: "Open Port", - }, - ]; - - const getFindings = async () => findings; + const getFindings = buildGetFindings(findingsWithOpenPort); await handle({ getFindings, @@ -85,21 +90,7 @@ test("should send findings to elasticsearch with given prefix", async () => { client: elasticClient, }); - expect(elasticClient.index).toHaveBeenCalledTimes(1); - expect(elasticClient.index).toHaveBeenCalledWith({ - body: { - "@timestamp": testDate, - id: "09988cdf-1fc7-4f85-95ee-1b1d65dbc7cc", - labels: { - company: "iteratec", - }, - name: "demo-scan", - parameters: ["-Pn", "localhost"], - scan_type: "Nmap", - type: "scan", - }, - index: `myPrefix_default_2020-11-11`, - }); + expectScanIndexCalledWith(`myPrefix_default_2020-11-11`); expect(elasticClient.bulk).toHaveBeenCalledTimes(1); expect(elasticClient.bulk).toHaveBeenCalledWith({ @@ -130,7 +121,7 @@ test("should send findings to elasticsearch with given prefix", async () => { test("should not append namespace if 'appendNamespace' is null", async () => { const findings = []; - const getFindings = async () => findings; + const getFindings = buildGetFindings(findings); await handle({ getFindings, @@ -140,27 +131,13 @@ test("should not append namespace if 'appendNamespace' is null", async () => { client: elasticClient, }); - expect(elasticClient.index).toBeCalledTimes(1); - expect(elasticClient.index).toBeCalledWith({ - body: { - "@timestamp": testDate, - id: "09988cdf-1fc7-4f85-95ee-1b1d65dbc7cc", - labels: { - company: "iteratec", - }, - name: "demo-scan", - parameters: ["-Pn", "localhost"], - scan_type: "Nmap", - type: "scan", - }, - index: `scb_2020-11-11`, - }); + expectScanIndexCalledWith(`scb_2020-11-11`); }); test("should append date format yyyy", async () => { const findings = []; - const getFindings = async () => findings; + const getFindings = buildGetFindings(findings); await handle({ getFindings, @@ -171,27 +148,13 @@ test("should append date format yyyy", async () => { client: elasticClient, }); - expect(elasticClient.index).toBeCalledTimes(1); - expect(elasticClient.index).toBeCalledWith({ - body: { - "@timestamp": testDate, - id: "09988cdf-1fc7-4f85-95ee-1b1d65dbc7cc", - labels: { - company: "iteratec", - }, - name: "demo-scan", - parameters: ["-Pn", "localhost"], - scan_type: "Nmap", - type: "scan", - }, - index: `scb_2020`, - }); + expectScanIndexCalledWith(`scb_2020`); }); test("should append week format like yyyy/'W'W -> 2020/W46", async () => { const findings = []; - const getFindings = async () => findings; + const getFindings = buildGetFindings(findings); await handle({ getFindings, @@ -202,19 +165,41 @@ test("should append week format like yyyy/'W'W -> 2020/W46", async () => { client: elasticClient, }); - expect(elasticClient.index).toBeCalledTimes(1); - expect(elasticClient.index).toBeCalledWith({ - body: { - "@timestamp": testDate, - id: "09988cdf-1fc7-4f85-95ee-1b1d65dbc7cc", - labels: { - company: "iteratec", - }, - name: "demo-scan", - parameters: ["-Pn", "localhost"], - scan_type: "Nmap", - type: "scan", + expectScanIndexCalledWith(`scb_2020/W46`); +}); + +test("should handle elasticsearch v8 bulk response shape", async () => { + const findings = findingsWithOpenPort; + const getFindings = buildGetFindings(findings); + const v8BulkResponse = { errors: true, items: [] }; + + const v8Client = { + indices: { + create: jest.fn(), }, - index: `scb_2020/W46`, - }); + index: jest.fn(), + bulk: jest.fn(() => v8BulkResponse), + }; + + const consoleErrorSpy = jest + .spyOn(console, "error") + .mockImplementation(() => {}); + const consoleLogSpy = jest.spyOn(console, "log").mockImplementation(() => {}); + + try { + await handle({ + getFindings, + scan, + now: testDate, + tenant: "default", + appendNamespace: true, + client: v8Client, + }); + expect(v8Client.bulk).toHaveBeenCalledTimes(1); + expect(consoleErrorSpy).toHaveBeenCalledWith("Bulk Request had errors:"); + expect(consoleLogSpy).toHaveBeenCalledWith(v8BulkResponse); + } finally { + consoleErrorSpy.mockRestore(); + consoleLogSpy.mockRestore(); + } }); diff --git a/hooks/persistence-elastic/hook/package-lock.json b/hooks/persistence-elastic/hook/package-lock.json index e8d449db22..a6720d065f 100644 --- a/hooks/persistence-elastic/hook/package-lock.json +++ b/hooks/persistence-elastic/hook/package-lock.json @@ -837,10 +837,9 @@ } }, "node_modules/undici": { - "version": "6.21.3", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz", - "integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==", - "license": "MIT", + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz", + "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==", "engines": { "node": ">=18.17" } @@ -1431,9 +1430,9 @@ "integrity": "sha512-ya4mg/30vm+DOWfBg4YK3j2WD6TWtRkCbasOJr40CseYENzCUby/7rIvXA99JGsQHeNxLbnXdyLLxKSv3tauFw==" }, "undici": { - "version": "6.21.3", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz", - "integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==" + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz", + "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==" }, "undici-types": { "version": "6.19.8", diff --git a/hooks/persistence-elastic/tests/__snapshot__/persistence-elastic_test.yaml.snap b/hooks/persistence-elastic/tests/__snapshot__/persistence-elastic_test.yaml.snap index 8f851fd788..b4d93791b5 100644 --- a/hooks/persistence-elastic/tests/__snapshot__/persistence-elastic_test.yaml.snap +++ b/hooks/persistence-elastic/tests/__snapshot__/persistence-elastic_test.yaml.snap @@ -1,6 +1,6 @@ matches the snapshot: 1: | - raw: |2 + raw: | Elastic Stack PersistenceProvider deployed. 2: | apiVersion: batch/v1 diff --git a/hooks/update-field-hook/hook/Dockerfile b/hooks/update-field-hook/hook/Dockerfile index dc64c7bf24..83625a615a 100644 --- a/hooks/update-field-hook/hook/Dockerfile +++ b/hooks/update-field-hook/hook/Dockerfile @@ -4,11 +4,11 @@ ARG namespace ARG baseImageTag -FROM node:22-alpine AS build +FROM node:24-alpine AS build RUN mkdir -p /home/app WORKDIR /home/app COPY package.json package-lock.json ./ -RUN npm ci --omit=dev +RUN npm ci --omit=dev --ignore-scripts FROM ${namespace:-securecodebox}/hook-sdk-nodejs:${baseImageTag:-latest} WORKDIR /home/app/hook-wrapper/hook/ diff --git a/hooks/update-field-hook/tests/__snapshot__/update-field-hook_test.yaml.snap b/hooks/update-field-hook/tests/__snapshot__/update-field-hook_test.yaml.snap index 8c46f4d71b..9aeee5375f 100644 --- a/hooks/update-field-hook/tests/__snapshot__/update-field-hook_test.yaml.snap +++ b/hooks/update-field-hook/tests/__snapshot__/update-field-hook_test.yaml.snap @@ -1,6 +1,6 @@ matches the snapshot: 1: | - raw: |2 + raw: | UpdateField Hook deployed. This will add or override "category: my-own-category" on every finding in this namespace. 2: | diff --git a/lurker/Dockerfile b/lurker/Dockerfile index 426f3f69f7..64550ee98c 100644 --- a/lurker/Dockerfile +++ b/lurker/Dockerfile @@ -3,7 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 # Build the manager binary -FROM golang:1.24.2 AS builder +FROM --platform=$BUILDPLATFORM golang:1.25.7 AS builder WORKDIR /workspace # Copy the Go Modules manifests @@ -17,7 +17,8 @@ RUN go mod download COPY main.go main.go # Build -RUN CGO_ENABLED=0 go build -a -o lurker main.go +ARG TARGETOS TARGETARCH +RUN GOOS="$TARGETOS" GOARCH="$TARGETARCH" CGO_ENABLED=0 go build -a -o lurker main.go # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details diff --git a/lurker/go.mod b/lurker/go.mod index 94d24c6fee..c450a8aa4f 100644 --- a/lurker/go.mod +++ b/lurker/go.mod @@ -4,51 +4,48 @@ module github.com/secureCodeBox/secureCodeBox/lurker -go 1.24.2 +go 1.25.0 require ( - k8s.io/api v0.32.3 - k8s.io/apimachinery v0.32.3 - k8s.io/client-go v0.32.3 + k8s.io/api v0.35.0 + k8s.io/apimachinery v0.35.0 + k8s.io/client-go v0.35.0 ) require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.12.2 // indirect - github.com/fxamacker/cbor/v2 v2.8.0 // indirect - github.com/go-logr/logr v1.4.2 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/go-logr/logr v1.4.3 // indirect github.com/go-openapi/jsonpointer v0.21.1 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.1 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.4 // indirect - github.com/google/gnostic-models v0.6.9 // indirect - github.com/google/go-cmp v0.7.0 // indirect - github.com/google/gofuzz v1.2.0 // indirect + github.com/google/gnostic-models v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.9.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/x448/float16 v0.8.4 // indirect - golang.org/x/net v0.39.0 // indirect - golang.org/x/oauth2 v0.29.0 // indirect - golang.org/x/sys v0.32.0 // indirect - golang.org/x/term v0.31.0 // indirect - golang.org/x/text v0.24.0 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/term v0.37.0 // indirect + golang.org/x/text v0.31.0 // indirect golang.org/x/time v0.11.0 // indirect - google.golang.org/protobuf v1.36.6 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect - k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect ) diff --git a/lurker/go.sum b/lurker/go.sum index adbdca6ea4..e993d23caa 100644 --- a/lurker/go.sum +++ b/lurker/go.sum @@ -1,13 +1,15 @@ +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU= -github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic= github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk= github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= @@ -16,28 +18,19 @@ github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZ github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= -github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= +github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -47,99 +40,79 @@ github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUt github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= -github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= -github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= -github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= +github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= +github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= -golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= -golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98= -golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= -golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= -golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= -golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= +golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= -golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= +golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.32.3 h1:Hw7KqxRusq+6QSplE3NYG4MBxZw1BZnq4aP4cJVINls= -k8s.io/api v0.32.3/go.mod h1:2wEDTXADtm/HA7CCMD8D8bK4yuBUptzaRhYcYEEYA3k= -k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U= -k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= -k8s.io/client-go v0.32.3 h1:RKPVltzopkSgHS7aS98QdscAgtgah/+zmpAogooIqVU= -k8s.io/client-go v0.32.3/go.mod h1:3v0+3k4IcT9bXTc4V2rt+d2ZPPG700Xy6Oi0Gdl2PaY= +k8s.io/api v0.35.0 h1:iBAU5LTyBI9vw3L5glmat1njFK34srdLmktWwLTprlY= +k8s.io/api v0.35.0/go.mod h1:AQ0SNTzm4ZAczM03QH42c7l3bih1TbAXYo0DkF8ktnA= +k8s.io/apimachinery v0.35.0 h1:Z2L3IHvPVv/MJ7xRxHEtk6GoJElaAqDCCU0S6ncYok8= +k8s.io/apimachinery v0.35.0/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= +k8s.io/client-go v0.35.0 h1:IAW0ifFbfQQwQmga0UdoH0yvdqrbwMdq9vIFEhRpxBE= +k8s.io/client-go v0.35.0/go.mod h1:q2E5AAyqcbeLGPdoRB+Nxe3KYTfPce1Dnu1myQdqz9o= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= -k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro= -k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= -sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/operator/Chart.lock b/operator/Chart.lock deleted file mode 100644 index df8ac855ce..0000000000 --- a/operator/Chart.lock +++ /dev/null @@ -1,6 +0,0 @@ -dependencies: -- name: minio - repository: https://charts.bitnami.com/bitnami - version: 17.0.12 -digest: sha256:44693c0ab386ac6a7244ea85980fcb87f72e4d06484634e7a78038e596364d9d -generated: "2025-07-14T10:11:54.339584809Z" diff --git a/operator/Chart.yaml b/operator/Chart.yaml index e52f3bce1e..5392176be2 100644 --- a/operator/Chart.yaml +++ b/operator/Chart.yaml @@ -24,11 +24,7 @@ maintainers: - name: iteratec GmbH email: secureCodeBox@iteratec.com -dependencies: - - name: minio - version: 17.0.12 - repository: https://charts.bitnami.com/bitnami - condition: minio.enabled +dependencies: [] # Artifacthub.io specific annotations # https://artifacthub.io/docs/topics/annotations/helm/ @@ -161,5 +157,5 @@ annotations: artifacthub.io/recommendations: | - url: https://artifacthub.io/packages/helm/securecodebox/auto-discovery-kubernetes - url: https://artifacthub.io/packages/helm/securecodebox/zap - - url: https://artifacthub.io/packages/helm/securecodebox/amass + - url: https://artifacthub.io/packages/helm/securecodebox/subfinder - url: https://artifacthub.io/packages/helm/securecodebox/nmap diff --git a/operator/Dockerfile b/operator/Dockerfile index 7855da8997..8631e172d5 100644 --- a/operator/Dockerfile +++ b/operator/Dockerfile @@ -3,7 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 # Build the manager binary -FROM golang:1.24.2 AS builder +FROM --platform=$BUILDPLATFORM golang:1.25.7 AS builder WORKDIR /workspace # Copy the Go Modules manifests @@ -21,7 +21,8 @@ COPY internal/ internal/ COPY utils/ utils/ # Build -RUN CGO_ENABLED=0 go build -a -o manager main.go +ARG TARGETOS TARGETARCH +RUN GOOS="$TARGETOS" GOARCH="$TARGETARCH" CGO_ENABLED=0 go build -a -o manager main.go # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details diff --git a/operator/README.md b/operator/README.md index a9f7cbd547..172c938f96 100644 --- a/operator/README.md +++ b/operator/README.md @@ -52,10 +52,6 @@ helm upgrade --install operator oci://ghcr.io/securecodebox/helm/operator Kubernetes: `>=v1.11.0-0` -| Repository | Name | Version | -|------------|------|---------| -| https://charts.bitnami.com/bitnami | minio | 17.0.12 | - ## Deployment The secureCodeBox Operator can be deployed via helm: @@ -77,6 +73,8 @@ helm install securecodebox-operator oci://ghcr.io/securecodebox/helm/operator | customCACertificate | object | `{"certificate":"public.crt","existingCertificate":null}` | Setup for Custom CA certificates. These are automatically mounted into every secureCodeBox component (lurker, parser & hooks). Requires that every namespace has a configmap with the CA certificate(s) | | customCACertificate.certificate | string | `"public.crt"` | key in the configmap holding the certificate(s) | | customCACertificate.existingCertificate | string | `nil` | name of the configMap holding the ca certificate(s), needs to be the same across all namespaces | +| extraVolumeMounts | list | `[]` | Additional volume mounts to be mounted to the operator deployment | +| extraVolumes | list | `[]` | Additional volumes to be mounted to the operator deployment | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images | | image.repository | string | `"docker.io/securecodebox/operator"` | The operator image repository | | image.tag | string | defaults to the charts version | Parser image tag | @@ -86,14 +84,30 @@ helm install securecodebox-operator oci://ghcr.io/securecodebox/helm/operator | lurker.image.tag | string | defaults to the charts version | Parser image tag | | metrics | object | `{"serviceMonitor":{"enabled":false}}` | Configuration for the metrics the operator exports | | metrics.serviceMonitor.enabled | bool | `false` | Creates a prometheus operator ServiceMonitor rule to automatically scrape the operators metrics: https://github.com/prometheus-operator/prometheus-operator | -| minio | object | `{"auth":{"rootPassword":"password","rootUser":"admin"},"defaultBuckets":"securecodebox","enabled":true,"resources":{"requests":{"memory":"256Mi"}},"tls":{"enabled":false}}` | Minio default config. More config options an info: https://github.com/minio/minio/blob/master/helm/minio/values.yaml | +| minio | object | `{"auth":{"existingSecret":"","rootPassword":"","rootUser":"admin"},"defaultBuckets":"securecodebox","enabled":true,"image":{"pullPolicy":"IfNotPresent","repository":"docker.io/minio/minio","tag":"RELEASE.2025-07-23T15-54-02Z"},"persistence":{"size":"10Gi","storageClass":""},"podSecurityContext":{"fsGroup":1000,"runAsGroup":1000,"runAsUser":1000},"resources":{"limits":{"cpu":"500m","ephemeral-storage":"1Gi","memory":"512Mi"},"requests":{"cpu":"100m","memory":"256Mi"}},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"runAsGroup":1000,"runAsNonRoot":true,"runAsUser":1000,"seccompProfile":{"type":"RuntimeDefault"}},"tls":{"enabled":false}}` | Minio configuration for direct deployment | +| minio.auth | object | `{"existingSecret":"","rootPassword":"","rootUser":"admin"}` | Authentication configuration | +| minio.auth.existingSecret | string | `""` | Name of existing secret containing minio credentials (if set, auth.rootUser and auth.rootPassword are ignored) | +| minio.auth.rootPassword | string | `""` | Root password for minio (leave empty to generate a secure random password) | +| minio.auth.rootUser | string | `"admin"` | Root user for minio | +| minio.defaultBuckets | string | `"securecodebox"` | Default buckets to create on startup | | minio.enabled | bool | `true` | Enable this to use minio as storage backend instead of a cloud bucket provider like AWS S3, Google Cloud Storage, DigitalOcean Spaces etc. | +| minio.image | object | `{"pullPolicy":"IfNotPresent","repository":"docker.io/minio/minio","tag":"RELEASE.2025-07-23T15-54-02Z"}` | Minio image configuration | +| minio.persistence | object | `{"size":"10Gi","storageClass":""}` | Persistence configuration | +| minio.persistence.size | string | `"10Gi"` | Size of the persistent volume | +| minio.persistence.storageClass | string | `""` | Storage class for minio data persistence | +| minio.podSecurityContext | object | `{"fsGroup":1000,"runAsGroup":1000,"runAsUser":1000}` | Pod security context for minio | +| minio.resources | object | `{"limits":{"cpu":"500m","ephemeral-storage":"1Gi","memory":"512Mi"},"requests":{"cpu":"100m","memory":"256Mi"}}` | Resource limits and requests for minio | +| minio.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"runAsGroup":1000,"runAsNonRoot":true,"runAsUser":1000,"seccompProfile":{"type":"RuntimeDefault"}}` | Container security context for minio | +| minio.tls | object | `{"enabled":false}` | TLS configuration (currently not implemented) | | nodeSelector | object | `{}` | | | podSecurityContext | object | `{}` | Sets the securityContext on the operators pod level. See: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container | | presignedUrlExpirationTimes | object | `{"hooks":"1h","parsers":"1h","scanners":"12h"}` | Duration how long presigned urls are valid | +| probes | object | `{"liveness":{"httpGet":{"path":"/healthz","port":"healthchecks"},"initialDelaySeconds":15,"periodSeconds":20},"readiness":{"httpGet":{"path":"/readyz","port":"healthchecks"},"initialDelaySeconds":5,"periodSeconds":10}}` | Health and liveness probe configuration for the controller manager | +| probes.liveness | object | `{"httpGet":{"path":"/healthz","port":"healthchecks"},"initialDelaySeconds":15,"periodSeconds":20}` | Liveness probe configuration | +| probes.readiness | object | `{"httpGet":{"path":"/readyz","port":"healthchecks"},"initialDelaySeconds":5,"periodSeconds":10}` | Readiness probe configuration | | resources | object | `{"limits":{"cpu":"100m","memory":"30Mi"},"requests":{"cpu":"100m","memory":"20Mi"}}` | CPU/memory resource requests/limits (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/, https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/) | -| s3.authType | string | `"access-secret-key"` | Authentication method. Supports access-secret-key (used by most s3 endpoint) and aws-irsa (Used by AWS EKS IAM Role to Kubenetes Service Account Binding. Support for AWS IRSA is considered experimental in the secureCodeBox) | -| s3.awsStsEndpoint | string | `"https://sts.amazonaws.com"` | STS Endpoint used in AWS IRSA Authentication. Change this to the sts endpoint of your aws region. Only used when s3.authType is set to "aws-irsa" | +| s3.authType | string | `"access-secret-key"` | Authentication method. Supports `access-secret-key` (used by most s3 endpoints) and `aws-iam`` (Used by AWS EKS IAM Role to Kubernetes Service Account Binding (IRSA) and EKS Pod Identity Authentication. Support for AWS IRSA is considered experimental in the secureCodeBox) | +| s3.awsStsEndpoint | string | `"https://sts.amazonaws.com"` | STS Endpoint used in AWS IRSA Authentication. Change this to the sts endpoint of your aws region. Only used when s3.authType is set to "aws-iam". Usually not required, even in IRSA or Pod Identity setups as the region gets injected by AWS into the pod. | | s3.bucket | string | `"my-bucket"` | | | s3.enabled | bool | `false` | | | s3.endpoint | string | `"fra1.digitaloceanspaces.com"` | | diff --git a/operator/charts/minio-15.0.2.tgz b/operator/charts/minio-15.0.2.tgz deleted file mode 100644 index 593937dd74..0000000000 Binary files a/operator/charts/minio-15.0.2.tgz and /dev/null differ diff --git a/operator/controllers/execution/scans/hook_reconciler.go b/operator/controllers/execution/scans/hook_reconciler.go index 5219071414..cf5cf3638d 100644 --- a/operator/controllers/execution/scans/hook_reconciler.go +++ b/operator/controllers/execution/scans/hook_reconciler.go @@ -55,7 +55,7 @@ func (r *ScanReconciler) setHookStatus(scan *executionv1.Scan) error { hookStatuses = utils.MapClusterHooksToHookStatus(clusterScanCompletionHooks.Items) } - r.Log.Info("Found ScanCompletionHooks", "ScanCompletionHooks", len(hookStatuses)) + r.Log.V(7).Info("Found ScanCompletionHooks", "ScanCompletionHooks", len(hookStatuses)) orderedHookStatus := utils.FromUnorderedList(hookStatuses) scan.Status.OrderedHookStatuses = orderedHookStatus @@ -468,6 +468,8 @@ func (r *ScanReconciler) createJobForHook(hookName string, hookSpec *executionv1 return "", err } + r.Log.Info("Creating hook job", "job", job.Name, "scanCompletionHook", hookName, "scan", scan.Name, "namespace", scan.Namespace) + if err := r.Create(ctx, job); err != nil { return "", err } diff --git a/operator/controllers/execution/scans/parse_reconciler.go b/operator/controllers/execution/scans/parse_reconciler.go index 477cb706db..d5aa6d8985 100644 --- a/operator/controllers/execution/scans/parse_reconciler.go +++ b/operator/controllers/execution/scans/parse_reconciler.go @@ -7,7 +7,6 @@ package scancontrollers import ( "context" "fmt" - "strings" executionv1 "github.com/secureCodeBox/secureCodeBox/operator/apis/execution/v1" util "github.com/secureCodeBox/secureCodeBox/operator/utils" @@ -53,7 +52,7 @@ func (r *ScanReconciler) startParser(scan *executionv1.Scan) error { return fmt.Errorf("no ParseDefinition of type '%s' found", parseType) } - log.Info("Matching ParseDefinition Found", "ParseDefinition", parseType) + log.V(7).Info("Matching ParseDefinition Found", "ParseDefinition", parseType) parseDefinitionSpec = parseDefinition.Spec } else if *scan.Spec.ResourceMode == executionv1.ClusterWide { var clusterParseDefinition executionv1.ClusterParseDefinition @@ -243,7 +242,7 @@ func (r *ScanReconciler) startParser(scan *executionv1.Scan) error { return err } - log.V(7).Info("Constructed Job object", "job args", strings.Join(job.Spec.Template.Spec.Containers[0].Args, ", ")) + log.Info("Creating parse job", "job", job.Name, "parseDefinition", parseType, "scan", scan.Name, "namespace", scan.Namespace) if err := r.Create(ctx, job); err != nil { log.Error(err, "unable to create Job for Parser", "job", job) diff --git a/operator/controllers/execution/scans/scan_controller.go b/operator/controllers/execution/scans/scan_controller.go index 18b251fddd..5a0f202113 100644 --- a/operator/controllers/execution/scans/scan_controller.go +++ b/operator/controllers/execution/scans/scan_controller.go @@ -43,7 +43,10 @@ var ( // Finalizer to delete related files in s3 when the scan gets deleted // https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#finalizers -var s3StorageFinalizer = "s3.storage.securecodebox.io" +var s3StorageFinalizer = "s3.storage.securecodebox.io/scan-files" + +// Legacy finalizer name for backward compatibility during migration +var s3StorageFinalizerLegacy = "s3.storage.securecodebox.io" // +kubebuilder:rbac:groups=execution.securecodebox.io,resources=scans,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=execution.securecodebox.io,resources=scans/status,verbs=get;update;patch @@ -140,23 +143,18 @@ func (r *ScanReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl. var errNotFound = "The specified key does not exist." func (r *ScanReconciler) handleFinalizer(scan *executionv1.Scan) error { - if containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizer) { - bucketName := os.Getenv("S3_BUCKET") - r.Log.V(3).Info("Deleting External Files from FileStorage", "ScanUID", scan.UID) - - rawResultUrl := getPresignedUrlPath(*scan, scan.Status.RawResultFile) - err := r.MinioClient.RemoveObject(context.Background(), bucketName, rawResultUrl, minio.RemoveObjectOptions{}) - if err != nil && err.Error() != errNotFound { - return err - } - - findingsJsonUrl := getPresignedUrlPath(*scan, "findings.json") - err = r.MinioClient.RemoveObject(context.Background(), bucketName, findingsJsonUrl, minio.RemoveObjectOptions{}) + // Handle migration from legacy finalizer + if err := r.migrateFinalizer(scan); err != nil { + return err + } - if err != nil && err.Error() != errNotFound { + // Check if we have the s3 storage finalizer + if containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizer) { + if err := r.cleanupS3Files(scan); err != nil { return err } + // Remove the s3 storage finalizer scan.ObjectMeta.Finalizers = removeString(scan.ObjectMeta.Finalizers, s3StorageFinalizer) if err := r.Update(context.Background(), scan); err != nil { return err @@ -165,6 +163,51 @@ func (r *ScanReconciler) handleFinalizer(scan *executionv1.Scan) error { return nil } +// todo: remove this with v6.0.0 +// migrateFinalizer handles migration from legacy finalizer +func (r *ScanReconciler) migrateFinalizer(scan *executionv1.Scan) error { + if !containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizerLegacy) { + return nil + } + + r.Log.Info("Migrating legacy finalizer", "scan", scan.Name, "namespace", scan.Namespace, "legacy", s3StorageFinalizerLegacy, "current", s3StorageFinalizer) + + // Clean up S3 files using legacy finalizer logic + if err := r.cleanupS3Files(scan); err != nil { + return err + } + + // Remove legacy finalizer - no need to add current one since scan is being deleted + scan.ObjectMeta.Finalizers = removeString(scan.ObjectMeta.Finalizers, s3StorageFinalizerLegacy) + if err := r.Update(context.Background(), scan); err != nil { + return err + } + + return nil +} + +// cleanupS3Files removes scan-related files from S3 storage +func (r *ScanReconciler) cleanupS3Files(scan *executionv1.Scan) error { + bucketName := os.Getenv("S3_BUCKET") + r.Log.V(3).Info("Deleting External Files from FileStorage", "ScanUID", scan.UID) + + // Clean up raw results file + rawResultUrl := getPresignedUrlPath(*scan, scan.Status.RawResultFile) + err := r.MinioClient.RemoveObject(context.Background(), bucketName, rawResultUrl, minio.RemoveObjectOptions{}) + if err != nil && err.Error() != errNotFound { + return err + } + + // Clean up findings.json file + findingsJsonUrl := getPresignedUrlPath(*scan, "findings.json") + err = r.MinioClient.RemoveObject(context.Background(), bucketName, findingsJsonUrl, minio.RemoveObjectOptions{}) + if err != nil && err.Error() != errNotFound { + return err + } + + return nil +} + // PresignedGetURL returns a presigned URL from the s3 (or compatible) serice. func (r *ScanReconciler) PresignedGetURL(scan executionv1.Scan, filename string, duration time.Duration) (string, error) { bucketName := os.Getenv("S3_BUCKET") @@ -218,13 +261,18 @@ func (r *ScanReconciler) initS3Connection() *minio.Client { var creds *credentials.Credentials - if authType, ok := os.LookupEnv("S3_AUTH_TYPE"); ok && strings.ToLower(authType) == "aws-irsa" { + // todo(v6): remove support for authType = "aws-irsa" and only support "aws-iam": https://github.com/secureCodeBox/secureCodeBox/issues/3327 + if authType, ok := os.LookupEnv("S3_AUTH_TYPE"); ok && (strings.ToLower(authType) == "aws-irsa" || strings.ToLower(authType) == "aws-iam") { stsEndpoint := "" + // todo(v6): remove support for S3_AWS_STS_ENDPOINT env var and only support S3_AWS_IRSA_STS_ENDPOINT: https://github.com/secureCodeBox/secureCodeBox/issues/3327 if configuredStsEndpoint, ok := os.LookupEnv("S3_AWS_IRSA_STS_ENDPOINT"); ok { stsEndpoint = configuredStsEndpoint } + if configuredStsEndpoint, ok := os.LookupEnv("S3_AWS_STS_ENDPOINT"); ok { + stsEndpoint = configuredStsEndpoint + } - r.Log.Info("Using AWS IRSA ServiceAccount Bindung for S3 Authentication", "sts", stsEndpoint) + r.Log.Info("Using AWS IAM ServiceAccount Binding for S3 Authentication (IRSA or EKS Pod Identity)", "sts", stsEndpoint) creds = credentials.NewIAM(stsEndpoint) } else { creds = credentials.NewEnvMinio() diff --git a/operator/controllers/execution/scans/scan_reconciler.go b/operator/controllers/execution/scans/scan_reconciler.go index 77a7185859..c261feeb6b 100644 --- a/operator/controllers/execution/scans/scan_reconciler.go +++ b/operator/controllers/execution/scans/scan_reconciler.go @@ -10,7 +10,6 @@ import ( "fmt" "os" "path/filepath" - "strings" "time" executionv1 "github.com/secureCodeBox/secureCodeBox/operator/apis/execution/v1" @@ -41,9 +40,25 @@ func (r *ScanReconciler) startScan(scan *executionv1.Scan) error { return nil } - // Add s3 storage finalizer to scan + // Add s3 storage finalizer to scan (and migrate legacy finalizer if needed) + updated := false + + // Migrate legacy finalizer for active scans + if containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizerLegacy) && !containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizer) { + log.Info("Migrating legacy finalizer for active scan", "legacy", s3StorageFinalizerLegacy, "current", s3StorageFinalizer) + scan.ObjectMeta.Finalizers = removeString(scan.ObjectMeta.Finalizers, s3StorageFinalizerLegacy) + scan.ObjectMeta.Finalizers = append(scan.ObjectMeta.Finalizers, s3StorageFinalizer) + updated = true + } + + // Add s3 storage finalizer if it doesn't exist if !containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizer) { scan.ObjectMeta.Finalizers = append(scan.ObjectMeta.Finalizers, s3StorageFinalizer) + updated = true + } + + // Update scan if finalizers were modified + if updated { if err := r.Update(context.Background(), scan); err != nil { return err } @@ -66,7 +81,7 @@ func (r *ScanReconciler) startScan(scan *executionv1.Scan) error { return fmt.Errorf("no ScanType of type '%s' found", scan.Spec.ScanType) } - log.Info("Matching ScanType Found", "ScanType", scanType.Name) + log.V(7).Info("Matching ScanType Found", "ScanType", scanType.Name) scanTypeSpec = scanType.Spec } else if *scan.Spec.ResourceMode == executionv1.ClusterWide { var clusterScanType executionv1.ClusterScanType @@ -108,8 +123,7 @@ func (r *ScanReconciler) startScan(scan *executionv1.Scan) error { return err } - log.V(7).Info("Constructed Job object", "job args", strings.Join(job.Spec.Template.Spec.Containers[0].Args, ", ")) - + log.Info("Creating scan job", "job", job.Name, "scanType", scan.Spec.ScanType, "scan", scan.Name, "namespace", scan.Namespace) if err := r.Create(ctx, job); err != nil { log.Error(err, "unable to create Job for Scan", "job", job) return err @@ -154,7 +168,6 @@ func (r *ScanReconciler) startScan(scan *executionv1.Scan) error { r.updateScanStatus(ctx, scan) - log.V(7).Info("created Job for Scan", "job", job) return nil } @@ -308,7 +321,7 @@ func (r *ScanReconciler) constructJobForScan(scan *executionv1.Scan, scanTypeSpe return nil, fmt.Errorf("unknown seccompProfile for lurker: %s", seccompProfileRaw) } - r.Log.Info("Using Lurker Image", "seccompProfile", seccompProfileRaw) + r.Log.V(8).Info("Using Lurker Image", "seccompProfile", seccompProfileRaw) falsePointer := false truePointer := true @@ -366,7 +379,7 @@ func (r *ScanReconciler) constructJobForScan(scan *executionv1.Scan, scanTypeSpe } customCACertificate, isConfigured := os.LookupEnv("CUSTOM_CA_CERTIFICATE_EXISTING_CERTIFICATE") - r.Log.Info("Configuring customCACerts for lurker", "customCACertificate", customCACertificate, "isConfigured", isConfigured) + r.Log.V(7).Info("Configuring customCACerts for lurker", "customCACertificate", customCACertificate, "isConfigured", isConfigured) if customCACertificate != "" { job.Spec.Template.Spec.Volumes = append(job.Spec.Template.Spec.Volumes, corev1.Volume{ Name: "ca-certificate", diff --git a/operator/controllers/execution/scans/scan_reconciler_test.go b/operator/controllers/execution/scans/scan_reconciler_test.go index 8e3a5f1d82..b730eb5ca2 100644 --- a/operator/controllers/execution/scans/scan_reconciler_test.go +++ b/operator/controllers/execution/scans/scan_reconciler_test.go @@ -19,6 +19,162 @@ import ( var namespace = "test-namespace" var reconciler = &ScanReconciler{} var _ = Describe("ScanControllers", func() { + Context("Finalizer Migration", func() { + var scan *executionv1.Scan + + BeforeEach(func() { + scan = &executionv1.Scan{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: "test-scan", + Finalizers: []string{}, + }, + Spec: executionv1.ScanSpec{ + ScanType: "nmap", + Parameters: []string{"example.com"}, + }, + Status: executionv1.ScanStatus{ + RawResultFile: "raw-results.json", + }, + } + }) + + It("should handle legacy finalizer migration logic", func() { + // Set up scan with legacy finalizer + scan.ObjectMeta.Finalizers = []string{s3StorageFinalizerLegacy, "other-finalizer"} + + // Test that legacy finalizer is present initially + Expect(containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizerLegacy)).To(BeTrue()) + + // Test that it would be detected for migration (without actually running migration + // which requires MinioClient setup) + hasLegacy := containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizerLegacy) + Expect(hasLegacy).To(BeTrue()) + + // Simulate the migration logic manually (what migrateFinalizer would do) + if hasLegacy { + scan.ObjectMeta.Finalizers = removeString(scan.ObjectMeta.Finalizers, s3StorageFinalizerLegacy) + } + + // After migration, legacy finalizer should be removed + Expect(containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizerLegacy)).To(BeFalse()) + // Other finalizers should remain + Expect(containsString(scan.ObjectMeta.Finalizers, "other-finalizer")).To(BeTrue()) + }) + + It("should not migrate when legacy finalizer is not present", func() { + // Set up scan without legacy finalizer + scan.ObjectMeta.Finalizers = []string{s3StorageFinalizer} + + mockReconciler := &ScanReconciler{} + err := mockReconciler.migrateFinalizer(scan) + + // Should return nil (no migration needed) + Expect(err).To(BeNil()) + // Should still have the new finalizer + Expect(containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizer)).To(BeTrue()) + }) + + It("should not migrate when no finalizers are present", func() { + // Set up scan without any finalizers + scan.ObjectMeta.Finalizers = []string{} + + // Test detection logic (no migration needed) + hasLegacy := containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizerLegacy) + Expect(hasLegacy).To(BeFalse()) + + // Should have no finalizers + Expect(len(scan.ObjectMeta.Finalizers)).To(Equal(0)) + }) + + It("should handle active scan migration from legacy finalizer", func() { + // Set up scan with legacy finalizer (simulating existing scan) + scan.ObjectMeta.Finalizers = []string{s3StorageFinalizerLegacy} + + // Simulate the active scan migration logic from startScan function + updated := false + + // Check if migration is needed + if containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizerLegacy) && !containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizer) { + scan.ObjectMeta.Finalizers = removeString(scan.ObjectMeta.Finalizers, s3StorageFinalizerLegacy) + scan.ObjectMeta.Finalizers = append(scan.ObjectMeta.Finalizers, s3StorageFinalizer) + updated = true + } + + // Verify migration occurred + Expect(updated).To(BeTrue()) + Expect(containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizerLegacy)).To(BeFalse()) + Expect(containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizer)).To(BeTrue()) + }) + + It("should not migrate active scan when current finalizer already exists", func() { + // Set up scan with both finalizers (edge case) + scan.ObjectMeta.Finalizers = []string{s3StorageFinalizerLegacy, s3StorageFinalizer} + + // Simulate the active scan migration logic + updated := false + + // Check migration condition (should not migrate if current finalizer exists) + if containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizerLegacy) && !containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizer) { + // This block should not execute + updated = true + } + + // Verify no migration occurred + Expect(updated).To(BeFalse()) + Expect(containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizerLegacy)).To(BeTrue()) + Expect(containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizer)).To(BeTrue()) + }) + + It("should add s3 storage finalizer to scan without any finalizers", func() { + // Set up scan without finalizers + scan.ObjectMeta.Finalizers = []string{} + + // Simulate adding s3 storage finalizer + updated := false + + if !containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizer) { + scan.ObjectMeta.Finalizers = append(scan.ObjectMeta.Finalizers, s3StorageFinalizer) + updated = true + } + + // Verify finalizer was added + Expect(updated).To(BeTrue()) + Expect(containsString(scan.ObjectMeta.Finalizers, s3StorageFinalizer)).To(BeTrue()) + Expect(len(scan.ObjectMeta.Finalizers)).To(Equal(1)) + }) + }) + + Context("Helper Functions", func() { + It("should correctly identify when string contains finalizer", func() { + finalizers := []string{"other-finalizer", s3StorageFinalizer, "another-finalizer"} + Expect(containsString(finalizers, s3StorageFinalizer)).To(BeTrue()) + Expect(containsString(finalizers, s3StorageFinalizerLegacy)).To(BeFalse()) + Expect(containsString(finalizers, "non-existent")).To(BeFalse()) + }) + + It("should correctly remove string from slice", func() { + originalSlice := []string{"first", s3StorageFinalizerLegacy, "last"} + result := removeString(originalSlice, s3StorageFinalizerLegacy) + + Expect(len(result)).To(Equal(2)) + Expect(result).To(Equal([]string{"first", "last"})) + Expect(containsString(result, s3StorageFinalizerLegacy)).To(BeFalse()) + }) + + It("should handle removing non-existent string", func() { + originalSlice := []string{"first", "second", "third"} + result := removeString(originalSlice, "non-existent") + + Expect(len(result)).To(Equal(3)) + Expect(result).To(Equal(originalSlice)) + }) + + It("should handle empty slice", func() { + result := removeString([]string{}, "any-string") + Expect(len(result)).To(Equal(0)) + }) + }) Context("checkIfTTLSecondsAfterFinishedIsCompleted", func() { It("should return true if TTLSecondsAfterFinished is set", func() { finishTime := time.Date( diff --git a/operator/controllers/execution/scans/serviceaccount.go b/operator/controllers/execution/scans/serviceaccount.go index 88e48a2872..781dff44f4 100644 --- a/operator/controllers/execution/scans/serviceaccount.go +++ b/operator/controllers/execution/scans/serviceaccount.go @@ -22,7 +22,7 @@ func (r *ScanReconciler) ensureServiceAccountExists(namespace, serviceAccountNam var serviceAccount corev1.ServiceAccount err := r.Get(ctx, types.NamespacedName{Name: serviceAccountName, Namespace: namespace}, &serviceAccount) if apierrors.IsNotFound(err) { - r.Log.Info("Service Account doesn't exist creating now") + r.Log.Info("Creating missing service account", "serviceAccountName", serviceAccountName, "namespace", namespace) serviceAccount = corev1.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ Name: serviceAccountName, @@ -34,18 +34,18 @@ func (r *ScanReconciler) ensureServiceAccountExists(namespace, serviceAccountNam } err := r.Create(ctx, &serviceAccount) if err != nil { - r.Log.Error(err, "Failed to create ServiceAccount") + r.Log.Error(err, "Failed to create ServiceAccount", "serviceAccountName", serviceAccountName, "namespace", namespace) return err } } else if err != nil { - r.Log.Error(err, "Unexpected error while checking if a ServiceAccount exists") + r.Log.Error(err, "Unexpected error while checking if a ServiceAccount exists", "serviceAccountName", serviceAccountName, "namespace", namespace) return err } var role rbacv1.Role err = r.Get(ctx, types.NamespacedName{Name: serviceAccountName, Namespace: namespace}, &role) if apierrors.IsNotFound(err) { - r.Log.Info("Role doesn't exist creating now") + r.Log.Info("Creating missing Role", "roleName", serviceAccountName, "namespace", namespace) role = rbacv1.Role{ ObjectMeta: metav1.ObjectMeta{ Name: serviceAccountName, @@ -58,7 +58,7 @@ func (r *ScanReconciler) ensureServiceAccountExists(namespace, serviceAccountNam } err := r.Create(ctx, &role) if err != nil { - r.Log.Error(err, "Failed to create Role") + r.Log.Error(err, "Failed to create Role", "roleName", serviceAccountName, "namespace", namespace) return err } } else if !reflect.DeepEqual(role.Rules, policyRules) { @@ -66,18 +66,18 @@ func (r *ScanReconciler) ensureServiceAccountExists(namespace, serviceAccountNam role.Rules = policyRules err := r.Update(ctx, &role) if err != nil { - r.Log.Error(err, "Failed to update Role") + r.Log.Error(err, "Failed to update Role", "roleName", serviceAccountName, "namespace", namespace) return err } } else if err != nil { - r.Log.Error(err, "Unexpected error while checking if a Role exists") + r.Log.Error(err, "Unexpected error while checking if a Role exists", "roleName", serviceAccountName, "namespace", namespace) return err } var roleBinding rbacv1.RoleBinding err = r.Get(ctx, types.NamespacedName{Name: serviceAccountName, Namespace: namespace}, &roleBinding) if apierrors.IsNotFound(err) { - r.Log.Info("RoleBinding doesn't exist creating now") + r.Log.Info("Creating missing RoleBinding", "roleName", serviceAccountName, "namespace", namespace) roleBinding = rbacv1.RoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: serviceAccountName, @@ -100,11 +100,11 @@ func (r *ScanReconciler) ensureServiceAccountExists(namespace, serviceAccountNam } err := r.Create(ctx, &roleBinding) if err != nil { - r.Log.Error(err, "Failed to create RoleBinding") + r.Log.Error(err, "Failed to create RoleBinding", "roleName", serviceAccountName, "namespace", namespace) return err } } else if err != nil { - r.Log.Error(err, "Unexpected error while checking if a RoleBinding exists") + r.Log.Error(err, "Unexpected error while checking if a RoleBinding exists", "roleName", serviceAccountName, "namespace", namespace) return err } diff --git a/operator/crds/cascading.securecodebox.io_cascadingrules.yaml b/operator/crds/cascading.securecodebox.io_cascadingrules.yaml index c222ceaab0..c5de223579 100644 --- a/operator/crds/cascading.securecodebox.io_cascadingrules.yaml +++ b/operator/crds/cascading.securecodebox.io_cascadingrules.yaml @@ -1108,8 +1108,9 @@ spec: in a Container. properties: name: - description: Name of the environment variable. Must be a - C_IDENTIFIER. + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. type: string value: description: |- @@ -1162,6 +1163,39 @@ spec: - fieldPath type: object x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount containing + the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: |- Selects a resource of the container: only resources limits and requests @@ -1298,8 +1332,9 @@ spec: present in a Container. properties: name: - description: Name of the environment variable. Must - be a C_IDENTIFIER. + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. type: string value: description: |- @@ -1352,6 +1387,39 @@ spec: - fieldPath type: object x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount + containing the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: |- Selects a resource of the container: only resources limits and requests @@ -1412,8 +1480,7 @@ spec: envFrom: description: |- List of sources to populate environment variables in the container. - The keys defined within a source must be a C_IDENTIFIER. All invalid keys - will be reported as an event when the container is starting. + The keys defined within a source may consist of any printable ASCII characters except '='. items: description: EnvFromSource represents the source of a set of ConfigMaps or Secrets @@ -1437,8 +1504,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: Optional text to prepend to the name - of each environment variable. Must be a C_IDENTIFIER. + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. type: string secretRef: description: The Secret to select from @@ -2045,7 +2113,9 @@ spec: type: integer type: object resizePolicy: - description: Resources resize policy for the container. + description: |- + Resources resize policy for the container. + This field cannot be set on ephemeral containers. items: description: ContainerResizePolicy represents resource resize policy for the container. @@ -2077,7 +2147,7 @@ spec: Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -2131,8 +2201,53 @@ spec: restartPolicy: description: |- RestartPolicy defines the restart behavior of individual containers in a pod. - This field may only be set for init containers, and the only allowed value is "Always". + This overrides the pod-level restart policy. When this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. The rules are evaluated in + order. Once a rule matches a container exit condition, the remaining + rules are ignored. + items: + description: ContainerRestartRule describes how a container + exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes to check on + container exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic securityContext: description: |- SecurityContext defines the security options the container should be run with. @@ -2599,7 +2714,7 @@ spec: Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -2673,7 +2788,7 @@ spec: operator: description: |- Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. + Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. type: string @@ -3241,8 +3356,11 @@ spec: - name type: object resources: - description: resources represents the minimum - resources the volume should have. + description: |- + resources represents the minimum resources the volume should have. + Users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. properties: limits: additionalProperties: @@ -3500,12 +3618,10 @@ spec: description: |- glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. - More info: https://examples.k8s.io/volumes/glusterfs/README.md properties: endpoints: - description: |- - endpoints is the endpoint name that details Glusterfs topology. - More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + description: endpoints is the endpoint name that details + Glusterfs topology. type: string path: description: |- @@ -3565,7 +3681,7 @@ spec: description: |- iscsi represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod. - More info: https://examples.k8s.io/volumes/iscsi/README.md + More info: https://kubernetes.io/docs/concepts/storage/volumes/#iscsi properties: chapAuthDiscovery: description: chapAuthDiscovery defines whether support @@ -3961,6 +4077,70 @@ spec: type: array x-kubernetes-list-type: atomic type: object + podCertificate: + description: |- + Projects an auto-rotating credential bundle (private key and certificate + chain) that the pod can use either as a TLS client or server. + + Kubelet generates a private key and uses it to send a + PodCertificateRequest to the named signer. + properties: + certificateChainPath: + description: |- + Write the certificate chain at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + credentialBundlePath: + description: |- + Write the credential bundle at this path in the projected volume. + + The credential bundle is a single file that contains multiple PEM blocks. + The first PEM block is a PRIVATE KEY block, containing a PKCS#8 private + key. + type: string + keyPath: + description: |- + Write the key at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + keyType: + description: |- + The type of keypair Kubelet will generate for the pod. + + Valid values are "RSA3072", "RSA4096", "ECDSAP256", "ECDSAP384", + "ECDSAP521", and "ED25519". + type: string + maxExpirationSeconds: + description: |- + maxExpirationSeconds is the maximum lifetime permitted for the + certificate. + + Kubelet copies this value verbatim into the PodCertificateRequests it + generates for this projection. + + If omitted, kube-apiserver will set it to 86400(24 hours). + format: int32 + type: integer + signerName: + description: Kubelet's generated CSRs will + be addressed to this signer. + type: string + userAnnotations: + additionalProperties: + type: string + description: |- + userAnnotations allow pod authors to pass additional information to + the signer implementation. Kubernetes does not restrict or validate this + metadata in any way. + + These values are copied verbatim into the `spec. + type: object + required: + - keyType + - signerName + type: object secret: description: secret information about the secret data to project @@ -4085,7 +4265,6 @@ spec: description: |- rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. - More info: https://examples.k8s.io/volumes/rbd/README.md properties: fsType: description: |- diff --git a/operator/crds/execution.securecodebox.io_clusterparsedefinitions.yaml b/operator/crds/execution.securecodebox.io_clusterparsedefinitions.yaml index 1b61a85d27..efc4ea2726 100644 --- a/operator/crds/execution.securecodebox.io_clusterparsedefinitions.yaml +++ b/operator/crds/execution.securecodebox.io_clusterparsedefinitions.yaml @@ -877,7 +877,9 @@ spec: a Container. properties: name: - description: Name of the environment variable. Must be a C_IDENTIFIER. + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. type: string value: description: |- @@ -930,6 +932,39 @@ spec: - fieldPath type: object x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount containing + the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: |- Selects a resource of the container: only resources limits and requests @@ -1033,7 +1068,7 @@ spec: Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -1108,7 +1143,7 @@ spec: operator: description: |- Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. + Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. type: string @@ -1671,8 +1706,11 @@ spec: - name type: object resources: - description: resources represents the minimum resources - the volume should have. + description: |- + resources represents the minimum resources the volume should have. + Users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. properties: limits: additionalProperties: @@ -1930,12 +1968,10 @@ spec: description: |- glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. - More info: https://examples.k8s.io/volumes/glusterfs/README.md properties: endpoints: - description: |- - endpoints is the endpoint name that details Glusterfs topology. - More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + description: endpoints is the endpoint name that details + Glusterfs topology. type: string path: description: |- @@ -1994,7 +2030,7 @@ spec: description: |- iscsi represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod. - More info: https://examples.k8s.io/volumes/iscsi/README.md + More info: https://kubernetes.io/docs/concepts/storage/volumes/#iscsi properties: chapAuthDiscovery: description: chapAuthDiscovery defines whether support iSCSI @@ -2388,6 +2424,70 @@ spec: type: array x-kubernetes-list-type: atomic type: object + podCertificate: + description: |- + Projects an auto-rotating credential bundle (private key and certificate + chain) that the pod can use either as a TLS client or server. + + Kubelet generates a private key and uses it to send a + PodCertificateRequest to the named signer. + properties: + certificateChainPath: + description: |- + Write the certificate chain at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + credentialBundlePath: + description: |- + Write the credential bundle at this path in the projected volume. + + The credential bundle is a single file that contains multiple PEM blocks. + The first PEM block is a PRIVATE KEY block, containing a PKCS#8 private + key. + type: string + keyPath: + description: |- + Write the key at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + keyType: + description: |- + The type of keypair Kubelet will generate for the pod. + + Valid values are "RSA3072", "RSA4096", "ECDSAP256", "ECDSAP384", + "ECDSAP521", and "ED25519". + type: string + maxExpirationSeconds: + description: |- + maxExpirationSeconds is the maximum lifetime permitted for the + certificate. + + Kubelet copies this value verbatim into the PodCertificateRequests it + generates for this projection. + + If omitted, kube-apiserver will set it to 86400(24 hours). + format: int32 + type: integer + signerName: + description: Kubelet's generated CSRs will be + addressed to this signer. + type: string + userAnnotations: + additionalProperties: + type: string + description: |- + userAnnotations allow pod authors to pass additional information to + the signer implementation. Kubernetes does not restrict or validate this + metadata in any way. + + These values are copied verbatim into the `spec. + type: object + required: + - keyType + - signerName + type: object secret: description: secret information about the secret data to project @@ -2512,7 +2612,6 @@ spec: description: |- rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. - More info: https://examples.k8s.io/volumes/rbd/README.md properties: fsType: description: |- diff --git a/operator/crds/execution.securecodebox.io_clusterscancompletionhooks.yaml b/operator/crds/execution.securecodebox.io_clusterscancompletionhooks.yaml index efc7719207..4bbd0611af 100644 --- a/operator/crds/execution.securecodebox.io_clusterscancompletionhooks.yaml +++ b/operator/crds/execution.securecodebox.io_clusterscancompletionhooks.yaml @@ -874,7 +874,9 @@ spec: a Container. properties: name: - description: Name of the environment variable. Must be a C_IDENTIFIER. + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. type: string value: description: |- @@ -927,6 +929,39 @@ spec: - fieldPath type: object x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount containing + the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: |- Selects a resource of the container: only resources limits and requests @@ -1037,7 +1072,7 @@ spec: Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -1114,7 +1149,7 @@ spec: operator: description: |- Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. + Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. type: string @@ -1681,8 +1716,11 @@ spec: - name type: object resources: - description: resources represents the minimum resources - the volume should have. + description: |- + resources represents the minimum resources the volume should have. + Users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. properties: limits: additionalProperties: @@ -1940,12 +1978,10 @@ spec: description: |- glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. - More info: https://examples.k8s.io/volumes/glusterfs/README.md properties: endpoints: - description: |- - endpoints is the endpoint name that details Glusterfs topology. - More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + description: endpoints is the endpoint name that details + Glusterfs topology. type: string path: description: |- @@ -2004,7 +2040,7 @@ spec: description: |- iscsi represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod. - More info: https://examples.k8s.io/volumes/iscsi/README.md + More info: https://kubernetes.io/docs/concepts/storage/volumes/#iscsi properties: chapAuthDiscovery: description: chapAuthDiscovery defines whether support iSCSI @@ -2398,6 +2434,70 @@ spec: type: array x-kubernetes-list-type: atomic type: object + podCertificate: + description: |- + Projects an auto-rotating credential bundle (private key and certificate + chain) that the pod can use either as a TLS client or server. + + Kubelet generates a private key and uses it to send a + PodCertificateRequest to the named signer. + properties: + certificateChainPath: + description: |- + Write the certificate chain at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + credentialBundlePath: + description: |- + Write the credential bundle at this path in the projected volume. + + The credential bundle is a single file that contains multiple PEM blocks. + The first PEM block is a PRIVATE KEY block, containing a PKCS#8 private + key. + type: string + keyPath: + description: |- + Write the key at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + keyType: + description: |- + The type of keypair Kubelet will generate for the pod. + + Valid values are "RSA3072", "RSA4096", "ECDSAP256", "ECDSAP384", + "ECDSAP521", and "ED25519". + type: string + maxExpirationSeconds: + description: |- + maxExpirationSeconds is the maximum lifetime permitted for the + certificate. + + Kubelet copies this value verbatim into the PodCertificateRequests it + generates for this projection. + + If omitted, kube-apiserver will set it to 86400(24 hours). + format: int32 + type: integer + signerName: + description: Kubelet's generated CSRs will be + addressed to this signer. + type: string + userAnnotations: + additionalProperties: + type: string + description: |- + userAnnotations allow pod authors to pass additional information to + the signer implementation. Kubernetes does not restrict or validate this + metadata in any way. + + These values are copied verbatim into the `spec. + type: object + required: + - keyType + - signerName + type: object secret: description: secret information about the secret data to project @@ -2522,7 +2622,6 @@ spec: description: |- rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. - More info: https://examples.k8s.io/volumes/rbd/README.md properties: fsType: description: |- diff --git a/operator/crds/execution.securecodebox.io_clusterscantypes.yaml b/operator/crds/execution.securecodebox.io_clusterscantypes.yaml index e81769f0c4..34e200b2f5 100644 --- a/operator/crds/execution.securecodebox.io_clusterscantypes.yaml +++ b/operator/crds/execution.securecodebox.io_clusterscantypes.yaml @@ -100,7 +100,8 @@ spec: backoffLimit: description: |- Specifies the number of retries before marking this job failed. - Defaults to 6 + Defaults to 6, unless backoffLimitPerIndex (only Indexed Job) is specified. + When backoffLimitPerIndex is specified, backoffLimit defaults to 2147483647. format: int32 type: integer backoffLimitPerIndex: @@ -233,7 +234,6 @@ spec: it is required that specified type equals the pod condition type. type: string required: - - status - type type: object type: array @@ -312,7 +312,7 @@ spec: description: |- rules represents the list of alternative rules for the declaring the Jobs as successful before `.status.succeeded >= .spec.completions`. Once any of the rules are met, - the "SucceededCriteriaMet" condition is added, and the lingering pods are removed. + the "SuccessCriteriaMet" condition is added, and the lingering pods are removed. items: description: |- SuccessPolicyRule describes rule for declaring a Job as succeeded. @@ -1245,8 +1245,9 @@ spec: variable present in a Container. properties: name: - description: Name of the environment variable. - Must be a C_IDENTIFIER. + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. type: string value: description: |- @@ -1303,6 +1304,39 @@ spec: - fieldPath type: object x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume + mount containing the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: |- Selects a resource of the container: only resources limits and requests @@ -1367,8 +1401,7 @@ spec: envFrom: description: |- List of sources to populate environment variables in the container. - The keys defined within a source must be a C_IDENTIFIER. All invalid keys - will be reported as an event when the container is starting. + The keys defined within a source may consist of any printable ASCII characters except '='. items: description: EnvFromSource represents the source of a set of ConfigMaps or Secrets @@ -1392,9 +1425,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: Optional text to prepend - to the name of each environment variable. - Must be a C_IDENTIFIER. + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. type: string secretRef: description: The Secret to select from @@ -2023,8 +2056,9 @@ spec: type: integer type: object resizePolicy: - description: Resources resize policy for the - container. + description: |- + Resources resize policy for the container. + This field cannot be set on ephemeral containers. items: description: ContainerResizePolicy represents resource resize policy for the container. @@ -2056,7 +2090,7 @@ spec: Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -2110,8 +2144,53 @@ spec: restartPolicy: description: |- RestartPolicy defines the restart behavior of individual containers in a pod. - This field may only be set for init containers, and the only allowed value is "Always". + This overrides the pod-level restart policy. When this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. The rules are evaluated in + order. Once a rule matches a container exit condition, the remaining + rules are ignored. + items: + description: ContainerRestartRule describes + how a container exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes + to check on container exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic securityContext: description: |- SecurityContext defines the security options the container should be run with. @@ -2660,8 +2739,9 @@ spec: variable present in a Container. properties: name: - description: Name of the environment variable. - Must be a C_IDENTIFIER. + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. type: string value: description: |- @@ -2718,6 +2798,39 @@ spec: - fieldPath type: object x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume + mount containing the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: |- Selects a resource of the container: only resources limits and requests @@ -2782,8 +2895,7 @@ spec: envFrom: description: |- List of sources to populate environment variables in the container. - The keys defined within a source must be a C_IDENTIFIER. All invalid keys - will be reported as an event when the container is starting. + The keys defined within a source may consist of any printable ASCII characters except '='. items: description: EnvFromSource represents the source of a set of ConfigMaps or Secrets @@ -2807,9 +2919,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: Optional text to prepend - to the name of each environment variable. - Must be a C_IDENTIFIER. + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. type: string secretRef: description: The Secret to select from @@ -3457,7 +3569,7 @@ spec: Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -3512,9 +3624,51 @@ spec: description: |- Restart policy for the container to manage the restart behavior of each container within a pod. - This may only be set for init containers. You cannot set this field on - ephemeral containers. + You cannot set this field on ephemeral containers. type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. You cannot set this field on + ephemeral containers. + items: + description: ContainerRestartRule describes + how a container exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes + to check on container exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic securityContext: description: |- Optional: SecurityContext defines the security options the ephemeral container should be run with. @@ -4000,8 +4154,7 @@ spec: hostNetwork: description: |- Host networking requested for this pod. Use the host's network namespace. - If this option is set, the ports that will be used must be specified. - Default to false. + When using HostNetwork you should specify ports so the scheduler is aware. type: boolean hostPID: description: |- @@ -4018,6 +4171,11 @@ spec: Specifies the hostname of the Pod If not specified, the pod's hostname will be set to a system-defined value. type: string + hostnameOverride: + description: |- + HostnameOverride specifies an explicit override for the pod's hostname as perceived by the pod. + This field only specifies the pod's hostname and does not affect its DNS records. + type: string imagePullSecrets: description: |- ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. @@ -4080,8 +4238,9 @@ spec: variable present in a Container. properties: name: - description: Name of the environment variable. - Must be a C_IDENTIFIER. + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. type: string value: description: |- @@ -4138,6 +4297,39 @@ spec: - fieldPath type: object x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume + mount containing the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: |- Selects a resource of the container: only resources limits and requests @@ -4202,8 +4394,7 @@ spec: envFrom: description: |- List of sources to populate environment variables in the container. - The keys defined within a source must be a C_IDENTIFIER. All invalid keys - will be reported as an event when the container is starting. + The keys defined within a source may consist of any printable ASCII characters except '='. items: description: EnvFromSource represents the source of a set of ConfigMaps or Secrets @@ -4227,9 +4418,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: Optional text to prepend - to the name of each environment variable. - Must be a C_IDENTIFIER. + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. type: string secretRef: description: The Secret to select from @@ -4858,8 +5049,9 @@ spec: type: integer type: object resizePolicy: - description: Resources resize policy for the - container. + description: |- + Resources resize policy for the container. + This field cannot be set on ephemeral containers. items: description: ContainerResizePolicy represents resource resize policy for the container. @@ -4891,7 +5083,7 @@ spec: Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -4945,8 +5137,53 @@ spec: restartPolicy: description: |- RestartPolicy defines the restart behavior of individual containers in a pod. - This field may only be set for init containers, and the only allowed value is "Always". + This overrides the pod-level restart policy. When this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. The rules are evaluated in + order. Once a rule matches a container exit condition, the remaining + rules are ignored. + items: + description: ContainerRestartRule describes + how a container exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes + to check on container exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic securityContext: description: |- SecurityContext defines the security options the container should be run with. @@ -5526,14 +5763,14 @@ spec: description: |- Resources is the total amount of CPU and Memory resources required by all containers in the pod. It supports specifying Requests and Limits for - "cpu" and "memory" resource names only. ResourceClaims are not supported. + "cpu", "memory" and "hugepages-" resource names only. ResourceClaims are not supported. properties: claims: description: |- Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -5857,7 +6094,7 @@ spec: operator: description: |- Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. + Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. type: string @@ -6502,9 +6739,11 @@ spec: - name type: object resources: - description: resources represents - the minimum resources the volume - should have. + description: |- + resources represents the minimum resources the volume should have. + Users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. properties: limits: additionalProperties: @@ -6768,12 +7007,10 @@ spec: description: |- glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. - More info: https://examples.k8s.io/volumes/glusterfs/README.md properties: endpoints: - description: |- - endpoints is the endpoint name that details Glusterfs topology. - More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + description: endpoints is the endpoint name + that details Glusterfs topology. type: string path: description: |- @@ -6833,7 +7070,7 @@ spec: description: |- iscsi represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod. - More info: https://examples.k8s.io/volumes/iscsi/README.md + More info: https://kubernetes.io/docs/concepts/storage/volumes/#iscsi properties: chapAuthDiscovery: description: chapAuthDiscovery defines whether @@ -7251,6 +7488,71 @@ spec: type: array x-kubernetes-list-type: atomic type: object + podCertificate: + description: |- + Projects an auto-rotating credential bundle (private key and certificate + chain) that the pod can use either as a TLS client or server. + + Kubelet generates a private key and uses it to send a + PodCertificateRequest to the named signer. + properties: + certificateChainPath: + description: |- + Write the certificate chain at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + credentialBundlePath: + description: |- + Write the credential bundle at this path in the projected volume. + + The credential bundle is a single file that contains multiple PEM blocks. + The first PEM block is a PRIVATE KEY block, containing a PKCS#8 private + key. + type: string + keyPath: + description: |- + Write the key at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + keyType: + description: |- + The type of keypair Kubelet will generate for the pod. + + Valid values are "RSA3072", "RSA4096", "ECDSAP256", "ECDSAP384", + "ECDSAP521", and "ED25519". + type: string + maxExpirationSeconds: + description: |- + maxExpirationSeconds is the maximum lifetime permitted for the + certificate. + + Kubelet copies this value verbatim into the PodCertificateRequests it + generates for this projection. + + If omitted, kube-apiserver will set it to 86400(24 hours). + format: int32 + type: integer + signerName: + description: Kubelet's generated + CSRs will be addressed to this + signer. + type: string + userAnnotations: + additionalProperties: + type: string + description: |- + userAnnotations allow pod authors to pass additional information to + the signer implementation. Kubernetes does not restrict or validate this + metadata in any way. + + These values are copied verbatim into the `spec. + type: object + required: + - keyType + - signerName + type: object secret: description: secret information about the secret data to project @@ -7378,7 +7680,6 @@ spec: description: |- rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. - More info: https://examples.k8s.io/volumes/rbd/README.md properties: fsType: description: |- @@ -7654,6 +7955,34 @@ spec: x-kubernetes-list-map-keys: - name x-kubernetes-list-type: map + workloadRef: + description: |- + WorkloadRef provides a reference to the Workload object that this Pod belongs to. + This field is used by the scheduler to identify the PodGroup and apply the + correct group scheduling policies. + properties: + name: + description: |- + Name defines the name of the Workload object this Pod belongs to. + Workload must be in the same namespace as the Pod. + type: string + podGroup: + description: |- + PodGroup is the name of the PodGroup within the Workload that this Pod + belongs to. If it doesn't match any existing PodGroup within the Workload, + the Pod will remain unschedulable until the Workload object is recreated + and observed by the kube-scheduler. + type: string + podGroupReplicaKey: + description: |- + PodGroupReplicaKey specifies the replica key of the PodGroup to which this + Pod belongs. It is used to distinguish pods belonging to different replicas + of the same pod group. The pod group policy is applied separately to each replica. + type: string + required: + - name + - podGroup + type: object required: - containers type: object diff --git a/operator/crds/execution.securecodebox.io_parsedefinitions.yaml b/operator/crds/execution.securecodebox.io_parsedefinitions.yaml index 4597d395ee..3428809ad3 100644 --- a/operator/crds/execution.securecodebox.io_parsedefinitions.yaml +++ b/operator/crds/execution.securecodebox.io_parsedefinitions.yaml @@ -876,7 +876,9 @@ spec: a Container. properties: name: - description: Name of the environment variable. Must be a C_IDENTIFIER. + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. type: string value: description: |- @@ -929,6 +931,39 @@ spec: - fieldPath type: object x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount containing + the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: |- Selects a resource of the container: only resources limits and requests @@ -1032,7 +1067,7 @@ spec: Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -1107,7 +1142,7 @@ spec: operator: description: |- Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. + Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. type: string @@ -1670,8 +1705,11 @@ spec: - name type: object resources: - description: resources represents the minimum resources - the volume should have. + description: |- + resources represents the minimum resources the volume should have. + Users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. properties: limits: additionalProperties: @@ -1929,12 +1967,10 @@ spec: description: |- glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. - More info: https://examples.k8s.io/volumes/glusterfs/README.md properties: endpoints: - description: |- - endpoints is the endpoint name that details Glusterfs topology. - More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + description: endpoints is the endpoint name that details + Glusterfs topology. type: string path: description: |- @@ -1993,7 +2029,7 @@ spec: description: |- iscsi represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod. - More info: https://examples.k8s.io/volumes/iscsi/README.md + More info: https://kubernetes.io/docs/concepts/storage/volumes/#iscsi properties: chapAuthDiscovery: description: chapAuthDiscovery defines whether support iSCSI @@ -2387,6 +2423,70 @@ spec: type: array x-kubernetes-list-type: atomic type: object + podCertificate: + description: |- + Projects an auto-rotating credential bundle (private key and certificate + chain) that the pod can use either as a TLS client or server. + + Kubelet generates a private key and uses it to send a + PodCertificateRequest to the named signer. + properties: + certificateChainPath: + description: |- + Write the certificate chain at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + credentialBundlePath: + description: |- + Write the credential bundle at this path in the projected volume. + + The credential bundle is a single file that contains multiple PEM blocks. + The first PEM block is a PRIVATE KEY block, containing a PKCS#8 private + key. + type: string + keyPath: + description: |- + Write the key at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + keyType: + description: |- + The type of keypair Kubelet will generate for the pod. + + Valid values are "RSA3072", "RSA4096", "ECDSAP256", "ECDSAP384", + "ECDSAP521", and "ED25519". + type: string + maxExpirationSeconds: + description: |- + maxExpirationSeconds is the maximum lifetime permitted for the + certificate. + + Kubelet copies this value verbatim into the PodCertificateRequests it + generates for this projection. + + If omitted, kube-apiserver will set it to 86400(24 hours). + format: int32 + type: integer + signerName: + description: Kubelet's generated CSRs will be + addressed to this signer. + type: string + userAnnotations: + additionalProperties: + type: string + description: |- + userAnnotations allow pod authors to pass additional information to + the signer implementation. Kubernetes does not restrict or validate this + metadata in any way. + + These values are copied verbatim into the `spec. + type: object + required: + - keyType + - signerName + type: object secret: description: secret information about the secret data to project @@ -2511,7 +2611,6 @@ spec: description: |- rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. - More info: https://examples.k8s.io/volumes/rbd/README.md properties: fsType: description: |- diff --git a/operator/crds/execution.securecodebox.io_scancompletionhooks.yaml b/operator/crds/execution.securecodebox.io_scancompletionhooks.yaml index 29b04fbc63..7edaee293b 100644 --- a/operator/crds/execution.securecodebox.io_scancompletionhooks.yaml +++ b/operator/crds/execution.securecodebox.io_scancompletionhooks.yaml @@ -874,7 +874,9 @@ spec: a Container. properties: name: - description: Name of the environment variable. Must be a C_IDENTIFIER. + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. type: string value: description: |- @@ -927,6 +929,39 @@ spec: - fieldPath type: object x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount containing + the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: |- Selects a resource of the container: only resources limits and requests @@ -1037,7 +1072,7 @@ spec: Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -1114,7 +1149,7 @@ spec: operator: description: |- Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. + Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. type: string @@ -1681,8 +1716,11 @@ spec: - name type: object resources: - description: resources represents the minimum resources - the volume should have. + description: |- + resources represents the minimum resources the volume should have. + Users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. properties: limits: additionalProperties: @@ -1940,12 +1978,10 @@ spec: description: |- glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. - More info: https://examples.k8s.io/volumes/glusterfs/README.md properties: endpoints: - description: |- - endpoints is the endpoint name that details Glusterfs topology. - More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + description: endpoints is the endpoint name that details + Glusterfs topology. type: string path: description: |- @@ -2004,7 +2040,7 @@ spec: description: |- iscsi represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod. - More info: https://examples.k8s.io/volumes/iscsi/README.md + More info: https://kubernetes.io/docs/concepts/storage/volumes/#iscsi properties: chapAuthDiscovery: description: chapAuthDiscovery defines whether support iSCSI @@ -2398,6 +2434,70 @@ spec: type: array x-kubernetes-list-type: atomic type: object + podCertificate: + description: |- + Projects an auto-rotating credential bundle (private key and certificate + chain) that the pod can use either as a TLS client or server. + + Kubelet generates a private key and uses it to send a + PodCertificateRequest to the named signer. + properties: + certificateChainPath: + description: |- + Write the certificate chain at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + credentialBundlePath: + description: |- + Write the credential bundle at this path in the projected volume. + + The credential bundle is a single file that contains multiple PEM blocks. + The first PEM block is a PRIVATE KEY block, containing a PKCS#8 private + key. + type: string + keyPath: + description: |- + Write the key at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + keyType: + description: |- + The type of keypair Kubelet will generate for the pod. + + Valid values are "RSA3072", "RSA4096", "ECDSAP256", "ECDSAP384", + "ECDSAP521", and "ED25519". + type: string + maxExpirationSeconds: + description: |- + maxExpirationSeconds is the maximum lifetime permitted for the + certificate. + + Kubelet copies this value verbatim into the PodCertificateRequests it + generates for this projection. + + If omitted, kube-apiserver will set it to 86400(24 hours). + format: int32 + type: integer + signerName: + description: Kubelet's generated CSRs will be + addressed to this signer. + type: string + userAnnotations: + additionalProperties: + type: string + description: |- + userAnnotations allow pod authors to pass additional information to + the signer implementation. Kubernetes does not restrict or validate this + metadata in any way. + + These values are copied verbatim into the `spec. + type: object + required: + - keyType + - signerName + type: object secret: description: secret information about the secret data to project @@ -2522,7 +2622,6 @@ spec: description: |- rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. - More info: https://examples.k8s.io/volumes/rbd/README.md properties: fsType: description: |- diff --git a/operator/crds/execution.securecodebox.io_scans.yaml b/operator/crds/execution.securecodebox.io_scans.yaml index 87e0acbb65..bf626f1e7e 100644 --- a/operator/crds/execution.securecodebox.io_scans.yaml +++ b/operator/crds/execution.securecodebox.io_scans.yaml @@ -1061,7 +1061,9 @@ spec: a Container. properties: name: - description: Name of the environment variable. Must be a C_IDENTIFIER. + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. type: string value: description: |- @@ -1114,6 +1116,39 @@ spec: - fieldPath type: object x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount containing + the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: |- Selects a resource of the container: only resources limits and requests @@ -1249,8 +1284,9 @@ spec: in a Container. properties: name: - description: Name of the environment variable. Must be - a C_IDENTIFIER. + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. type: string value: description: |- @@ -1303,6 +1339,39 @@ spec: - fieldPath type: object x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount containing + the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: |- Selects a resource of the container: only resources limits and requests @@ -1363,8 +1432,7 @@ spec: envFrom: description: |- List of sources to populate environment variables in the container. - The keys defined within a source must be a C_IDENTIFIER. All invalid keys - will be reported as an event when the container is starting. + The keys defined within a source may consist of any printable ASCII characters except '='. items: description: EnvFromSource represents the source of a set of ConfigMaps or Secrets @@ -1388,8 +1456,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: Optional text to prepend to the name of each - environment variable. Must be a C_IDENTIFIER. + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. type: string secretRef: description: The Secret to select from @@ -1990,7 +2059,9 @@ spec: type: integer type: object resizePolicy: - description: Resources resize policy for the container. + description: |- + Resources resize policy for the container. + This field cannot be set on ephemeral containers. items: description: ContainerResizePolicy represents resource resize policy for the container. @@ -2022,7 +2093,7 @@ spec: Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -2075,8 +2146,53 @@ spec: restartPolicy: description: |- RestartPolicy defines the restart behavior of individual containers in a pod. - This field may only be set for init containers, and the only allowed value is "Always". + This overrides the pod-level restart policy. When this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. The rules are evaluated in + order. Once a rule matches a container exit condition, the remaining + rules are ignored. + items: + description: ContainerRestartRule describes how a container + exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes to check on container + exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic securityContext: description: |- SecurityContext defines the security options the container should be run with. @@ -2541,7 +2657,7 @@ spec: Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -2615,7 +2731,7 @@ spec: operator: description: |- Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. + Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. type: string @@ -3179,8 +3295,11 @@ spec: - name type: object resources: - description: resources represents the minimum resources - the volume should have. + description: |- + resources represents the minimum resources the volume should have. + Users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. properties: limits: additionalProperties: @@ -3438,12 +3557,10 @@ spec: description: |- glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. - More info: https://examples.k8s.io/volumes/glusterfs/README.md properties: endpoints: - description: |- - endpoints is the endpoint name that details Glusterfs topology. - More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + description: endpoints is the endpoint name that details + Glusterfs topology. type: string path: description: |- @@ -3502,7 +3619,7 @@ spec: description: |- iscsi represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod. - More info: https://examples.k8s.io/volumes/iscsi/README.md + More info: https://kubernetes.io/docs/concepts/storage/volumes/#iscsi properties: chapAuthDiscovery: description: chapAuthDiscovery defines whether support iSCSI @@ -3896,6 +4013,70 @@ spec: type: array x-kubernetes-list-type: atomic type: object + podCertificate: + description: |- + Projects an auto-rotating credential bundle (private key and certificate + chain) that the pod can use either as a TLS client or server. + + Kubelet generates a private key and uses it to send a + PodCertificateRequest to the named signer. + properties: + certificateChainPath: + description: |- + Write the certificate chain at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + credentialBundlePath: + description: |- + Write the credential bundle at this path in the projected volume. + + The credential bundle is a single file that contains multiple PEM blocks. + The first PEM block is a PRIVATE KEY block, containing a PKCS#8 private + key. + type: string + keyPath: + description: |- + Write the key at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + keyType: + description: |- + The type of keypair Kubelet will generate for the pod. + + Valid values are "RSA3072", "RSA4096", "ECDSAP256", "ECDSAP384", + "ECDSAP521", and "ED25519". + type: string + maxExpirationSeconds: + description: |- + maxExpirationSeconds is the maximum lifetime permitted for the + certificate. + + Kubelet copies this value verbatim into the PodCertificateRequests it + generates for this projection. + + If omitted, kube-apiserver will set it to 86400(24 hours). + format: int32 + type: integer + signerName: + description: Kubelet's generated CSRs will be + addressed to this signer. + type: string + userAnnotations: + additionalProperties: + type: string + description: |- + userAnnotations allow pod authors to pass additional information to + the signer implementation. Kubernetes does not restrict or validate this + metadata in any way. + + These values are copied verbatim into the `spec. + type: object + required: + - keyType + - signerName + type: object secret: description: secret information about the secret data to project @@ -4020,7 +4201,6 @@ spec: description: |- rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. - More info: https://examples.k8s.io/volumes/rbd/README.md properties: fsType: description: |- diff --git a/operator/crds/execution.securecodebox.io_scantypes.yaml b/operator/crds/execution.securecodebox.io_scantypes.yaml index 2bad1ee108..aa08ae534a 100644 --- a/operator/crds/execution.securecodebox.io_scantypes.yaml +++ b/operator/crds/execution.securecodebox.io_scantypes.yaml @@ -100,7 +100,8 @@ spec: backoffLimit: description: |- Specifies the number of retries before marking this job failed. - Defaults to 6 + Defaults to 6, unless backoffLimitPerIndex (only Indexed Job) is specified. + When backoffLimitPerIndex is specified, backoffLimit defaults to 2147483647. format: int32 type: integer backoffLimitPerIndex: @@ -233,7 +234,6 @@ spec: it is required that specified type equals the pod condition type. type: string required: - - status - type type: object type: array @@ -312,7 +312,7 @@ spec: description: |- rules represents the list of alternative rules for the declaring the Jobs as successful before `.status.succeeded >= .spec.completions`. Once any of the rules are met, - the "SucceededCriteriaMet" condition is added, and the lingering pods are removed. + the "SuccessCriteriaMet" condition is added, and the lingering pods are removed. items: description: |- SuccessPolicyRule describes rule for declaring a Job as succeeded. @@ -1245,8 +1245,9 @@ spec: variable present in a Container. properties: name: - description: Name of the environment variable. - Must be a C_IDENTIFIER. + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. type: string value: description: |- @@ -1303,6 +1304,39 @@ spec: - fieldPath type: object x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume + mount containing the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: |- Selects a resource of the container: only resources limits and requests @@ -1367,8 +1401,7 @@ spec: envFrom: description: |- List of sources to populate environment variables in the container. - The keys defined within a source must be a C_IDENTIFIER. All invalid keys - will be reported as an event when the container is starting. + The keys defined within a source may consist of any printable ASCII characters except '='. items: description: EnvFromSource represents the source of a set of ConfigMaps or Secrets @@ -1392,9 +1425,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: Optional text to prepend - to the name of each environment variable. - Must be a C_IDENTIFIER. + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. type: string secretRef: description: The Secret to select from @@ -2023,8 +2056,9 @@ spec: type: integer type: object resizePolicy: - description: Resources resize policy for the - container. + description: |- + Resources resize policy for the container. + This field cannot be set on ephemeral containers. items: description: ContainerResizePolicy represents resource resize policy for the container. @@ -2056,7 +2090,7 @@ spec: Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -2110,8 +2144,53 @@ spec: restartPolicy: description: |- RestartPolicy defines the restart behavior of individual containers in a pod. - This field may only be set for init containers, and the only allowed value is "Always". + This overrides the pod-level restart policy. When this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. The rules are evaluated in + order. Once a rule matches a container exit condition, the remaining + rules are ignored. + items: + description: ContainerRestartRule describes + how a container exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes + to check on container exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic securityContext: description: |- SecurityContext defines the security options the container should be run with. @@ -2660,8 +2739,9 @@ spec: variable present in a Container. properties: name: - description: Name of the environment variable. - Must be a C_IDENTIFIER. + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. type: string value: description: |- @@ -2718,6 +2798,39 @@ spec: - fieldPath type: object x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume + mount containing the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: |- Selects a resource of the container: only resources limits and requests @@ -2782,8 +2895,7 @@ spec: envFrom: description: |- List of sources to populate environment variables in the container. - The keys defined within a source must be a C_IDENTIFIER. All invalid keys - will be reported as an event when the container is starting. + The keys defined within a source may consist of any printable ASCII characters except '='. items: description: EnvFromSource represents the source of a set of ConfigMaps or Secrets @@ -2807,9 +2919,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: Optional text to prepend - to the name of each environment variable. - Must be a C_IDENTIFIER. + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. type: string secretRef: description: The Secret to select from @@ -3457,7 +3569,7 @@ spec: Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -3512,9 +3624,51 @@ spec: description: |- Restart policy for the container to manage the restart behavior of each container within a pod. - This may only be set for init containers. You cannot set this field on - ephemeral containers. + You cannot set this field on ephemeral containers. type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. You cannot set this field on + ephemeral containers. + items: + description: ContainerRestartRule describes + how a container exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes + to check on container exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic securityContext: description: |- Optional: SecurityContext defines the security options the ephemeral container should be run with. @@ -4000,8 +4154,7 @@ spec: hostNetwork: description: |- Host networking requested for this pod. Use the host's network namespace. - If this option is set, the ports that will be used must be specified. - Default to false. + When using HostNetwork you should specify ports so the scheduler is aware. type: boolean hostPID: description: |- @@ -4018,6 +4171,11 @@ spec: Specifies the hostname of the Pod If not specified, the pod's hostname will be set to a system-defined value. type: string + hostnameOverride: + description: |- + HostnameOverride specifies an explicit override for the pod's hostname as perceived by the pod. + This field only specifies the pod's hostname and does not affect its DNS records. + type: string imagePullSecrets: description: |- ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. @@ -4080,8 +4238,9 @@ spec: variable present in a Container. properties: name: - description: Name of the environment variable. - Must be a C_IDENTIFIER. + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. type: string value: description: |- @@ -4138,6 +4297,39 @@ spec: - fieldPath type: object x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume + mount containing the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: |- Selects a resource of the container: only resources limits and requests @@ -4202,8 +4394,7 @@ spec: envFrom: description: |- List of sources to populate environment variables in the container. - The keys defined within a source must be a C_IDENTIFIER. All invalid keys - will be reported as an event when the container is starting. + The keys defined within a source may consist of any printable ASCII characters except '='. items: description: EnvFromSource represents the source of a set of ConfigMaps or Secrets @@ -4227,9 +4418,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: Optional text to prepend - to the name of each environment variable. - Must be a C_IDENTIFIER. + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. type: string secretRef: description: The Secret to select from @@ -4858,8 +5049,9 @@ spec: type: integer type: object resizePolicy: - description: Resources resize policy for the - container. + description: |- + Resources resize policy for the container. + This field cannot be set on ephemeral containers. items: description: ContainerResizePolicy represents resource resize policy for the container. @@ -4891,7 +5083,7 @@ spec: Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -4945,8 +5137,53 @@ spec: restartPolicy: description: |- RestartPolicy defines the restart behavior of individual containers in a pod. - This field may only be set for init containers, and the only allowed value is "Always". + This overrides the pod-level restart policy. When this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. The rules are evaluated in + order. Once a rule matches a container exit condition, the remaining + rules are ignored. + items: + description: ContainerRestartRule describes + how a container exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes + to check on container exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic securityContext: description: |- SecurityContext defines the security options the container should be run with. @@ -5526,14 +5763,14 @@ spec: description: |- Resources is the total amount of CPU and Memory resources required by all containers in the pod. It supports specifying Requests and Limits for - "cpu" and "memory" resource names only. ResourceClaims are not supported. + "cpu", "memory" and "hugepages-" resource names only. ResourceClaims are not supported. properties: claims: description: |- Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -5857,7 +6094,7 @@ spec: operator: description: |- Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. + Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. type: string @@ -6502,9 +6739,11 @@ spec: - name type: object resources: - description: resources represents - the minimum resources the volume - should have. + description: |- + resources represents the minimum resources the volume should have. + Users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. properties: limits: additionalProperties: @@ -6768,12 +7007,10 @@ spec: description: |- glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. - More info: https://examples.k8s.io/volumes/glusterfs/README.md properties: endpoints: - description: |- - endpoints is the endpoint name that details Glusterfs topology. - More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + description: endpoints is the endpoint name + that details Glusterfs topology. type: string path: description: |- @@ -6833,7 +7070,7 @@ spec: description: |- iscsi represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod. - More info: https://examples.k8s.io/volumes/iscsi/README.md + More info: https://kubernetes.io/docs/concepts/storage/volumes/#iscsi properties: chapAuthDiscovery: description: chapAuthDiscovery defines whether @@ -7251,6 +7488,71 @@ spec: type: array x-kubernetes-list-type: atomic type: object + podCertificate: + description: |- + Projects an auto-rotating credential bundle (private key and certificate + chain) that the pod can use either as a TLS client or server. + + Kubelet generates a private key and uses it to send a + PodCertificateRequest to the named signer. + properties: + certificateChainPath: + description: |- + Write the certificate chain at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + credentialBundlePath: + description: |- + Write the credential bundle at this path in the projected volume. + + The credential bundle is a single file that contains multiple PEM blocks. + The first PEM block is a PRIVATE KEY block, containing a PKCS#8 private + key. + type: string + keyPath: + description: |- + Write the key at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + keyType: + description: |- + The type of keypair Kubelet will generate for the pod. + + Valid values are "RSA3072", "RSA4096", "ECDSAP256", "ECDSAP384", + "ECDSAP521", and "ED25519". + type: string + maxExpirationSeconds: + description: |- + maxExpirationSeconds is the maximum lifetime permitted for the + certificate. + + Kubelet copies this value verbatim into the PodCertificateRequests it + generates for this projection. + + If omitted, kube-apiserver will set it to 86400(24 hours). + format: int32 + type: integer + signerName: + description: Kubelet's generated + CSRs will be addressed to this + signer. + type: string + userAnnotations: + additionalProperties: + type: string + description: |- + userAnnotations allow pod authors to pass additional information to + the signer implementation. Kubernetes does not restrict or validate this + metadata in any way. + + These values are copied verbatim into the `spec. + type: object + required: + - keyType + - signerName + type: object secret: description: secret information about the secret data to project @@ -7378,7 +7680,6 @@ spec: description: |- rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. - More info: https://examples.k8s.io/volumes/rbd/README.md properties: fsType: description: |- @@ -7654,6 +7955,34 @@ spec: x-kubernetes-list-map-keys: - name x-kubernetes-list-type: map + workloadRef: + description: |- + WorkloadRef provides a reference to the Workload object that this Pod belongs to. + This field is used by the scheduler to identify the PodGroup and apply the + correct group scheduling policies. + properties: + name: + description: |- + Name defines the name of the Workload object this Pod belongs to. + Workload must be in the same namespace as the Pod. + type: string + podGroup: + description: |- + PodGroup is the name of the PodGroup within the Workload that this Pod + belongs to. If it doesn't match any existing PodGroup within the Workload, + the Pod will remain unschedulable until the Workload object is recreated + and observed by the kube-scheduler. + type: string + podGroupReplicaKey: + description: |- + PodGroupReplicaKey specifies the replica key of the PodGroup to which this + Pod belongs. It is used to distinguish pods belonging to different replicas + of the same pod group. The pod group policy is applied separately to each replica. + type: string + required: + - name + - podGroup + type: object required: - containers type: object diff --git a/operator/crds/execution.securecodebox.io_scheduledscans.yaml b/operator/crds/execution.securecodebox.io_scheduledscans.yaml index 1a21ce1de7..dc0d85c7d4 100644 --- a/operator/crds/execution.securecodebox.io_scheduledscans.yaml +++ b/operator/crds/execution.securecodebox.io_scheduledscans.yaml @@ -1102,8 +1102,9 @@ spec: in a Container. properties: name: - description: Name of the environment variable. Must be a - C_IDENTIFIER. + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. type: string value: description: |- @@ -1156,6 +1157,39 @@ spec: - fieldPath type: object x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount containing + the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: |- Selects a resource of the container: only resources limits and requests @@ -1292,8 +1326,9 @@ spec: present in a Container. properties: name: - description: Name of the environment variable. Must - be a C_IDENTIFIER. + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. type: string value: description: |- @@ -1346,6 +1381,39 @@ spec: - fieldPath type: object x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount + containing the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: |- Selects a resource of the container: only resources limits and requests @@ -1406,8 +1474,7 @@ spec: envFrom: description: |- List of sources to populate environment variables in the container. - The keys defined within a source must be a C_IDENTIFIER. All invalid keys - will be reported as an event when the container is starting. + The keys defined within a source may consist of any printable ASCII characters except '='. items: description: EnvFromSource represents the source of a set of ConfigMaps or Secrets @@ -1431,8 +1498,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: Optional text to prepend to the name - of each environment variable. Must be a C_IDENTIFIER. + description: |- + Optional text to prepend to the name of each environment variable. + May consist of any printable ASCII characters except '='. type: string secretRef: description: The Secret to select from @@ -2039,7 +2107,9 @@ spec: type: integer type: object resizePolicy: - description: Resources resize policy for the container. + description: |- + Resources resize policy for the container. + This field cannot be set on ephemeral containers. items: description: ContainerResizePolicy represents resource resize policy for the container. @@ -2071,7 +2141,7 @@ spec: Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -2125,8 +2195,53 @@ spec: restartPolicy: description: |- RestartPolicy defines the restart behavior of individual containers in a pod. - This field may only be set for init containers, and the only allowed value is "Always". + This overrides the pod-level restart policy. When this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. type: string + restartPolicyRules: + description: |- + Represents a list of rules to be checked to determine if the + container should be restarted on exit. The rules are evaluated in + order. Once a rule matches a container exit condition, the remaining + rules are ignored. + items: + description: ContainerRestartRule describes how a container + exit is handled. + properties: + action: + description: |- + Specifies the action taken on a container exit if the requirements + are satisfied. The only possible value is "Restart" to restart the + container. + type: string + exitCodes: + description: Represents the exit codes to check on + container exits. + properties: + operator: + description: |- + Represents the relationship between the container exit code(s) and the + specified values. Possible values are: + - In: the requirement is satisfied if the container exit code is in the + set of specified values. + type: string + values: + description: |- + Specifies the set of values to check for container exit codes. + At most 255 elements are allowed. + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic securityContext: description: |- SecurityContext defines the security options the container should be run with. @@ -2593,7 +2708,7 @@ spec: Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - This is an alpha field and requires enabling the + This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. @@ -2667,7 +2782,7 @@ spec: operator: description: |- Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. + Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. type: string @@ -3235,8 +3350,11 @@ spec: - name type: object resources: - description: resources represents the minimum - resources the volume should have. + description: |- + resources represents the minimum resources the volume should have. + Users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. properties: limits: additionalProperties: @@ -3494,12 +3612,10 @@ spec: description: |- glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported. - More info: https://examples.k8s.io/volumes/glusterfs/README.md properties: endpoints: - description: |- - endpoints is the endpoint name that details Glusterfs topology. - More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + description: endpoints is the endpoint name that details + Glusterfs topology. type: string path: description: |- @@ -3559,7 +3675,7 @@ spec: description: |- iscsi represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod. - More info: https://examples.k8s.io/volumes/iscsi/README.md + More info: https://kubernetes.io/docs/concepts/storage/volumes/#iscsi properties: chapAuthDiscovery: description: chapAuthDiscovery defines whether support @@ -3955,6 +4071,70 @@ spec: type: array x-kubernetes-list-type: atomic type: object + podCertificate: + description: |- + Projects an auto-rotating credential bundle (private key and certificate + chain) that the pod can use either as a TLS client or server. + + Kubelet generates a private key and uses it to send a + PodCertificateRequest to the named signer. + properties: + certificateChainPath: + description: |- + Write the certificate chain at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + credentialBundlePath: + description: |- + Write the credential bundle at this path in the projected volume. + + The credential bundle is a single file that contains multiple PEM blocks. + The first PEM block is a PRIVATE KEY block, containing a PKCS#8 private + key. + type: string + keyPath: + description: |- + Write the key at this path in the projected volume. + + Most applications should use credentialBundlePath. + type: string + keyType: + description: |- + The type of keypair Kubelet will generate for the pod. + + Valid values are "RSA3072", "RSA4096", "ECDSAP256", "ECDSAP384", + "ECDSAP521", and "ED25519". + type: string + maxExpirationSeconds: + description: |- + maxExpirationSeconds is the maximum lifetime permitted for the + certificate. + + Kubelet copies this value verbatim into the PodCertificateRequests it + generates for this projection. + + If omitted, kube-apiserver will set it to 86400(24 hours). + format: int32 + type: integer + signerName: + description: Kubelet's generated CSRs will + be addressed to this signer. + type: string + userAnnotations: + additionalProperties: + type: string + description: |- + userAnnotations allow pod authors to pass additional information to + the signer implementation. Kubernetes does not restrict or validate this + metadata in any way. + + These values are copied verbatim into the `spec. + type: object + required: + - keyType + - signerName + type: object secret: description: secret information about the secret data to project @@ -4079,7 +4259,6 @@ spec: description: |- rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported. - More info: https://examples.k8s.io/volumes/rbd/README.md properties: fsType: description: |- diff --git a/operator/docs/README.ArtifactHub.md b/operator/docs/README.ArtifactHub.md index 5ca311d6f6..bec0ea13b5 100644 --- a/operator/docs/README.ArtifactHub.md +++ b/operator/docs/README.ArtifactHub.md @@ -57,10 +57,6 @@ helm upgrade --install operator oci://ghcr.io/securecodebox/helm/operator Kubernetes: `>=v1.11.0-0` -| Repository | Name | Version | -|------------|------|---------| -| https://charts.bitnami.com/bitnami | minio | 17.0.12 | - ## Deployment The secureCodeBox Operator can be deployed via helm: @@ -82,6 +78,8 @@ helm install securecodebox-operator oci://ghcr.io/securecodebox/helm/operator | customCACertificate | object | `{"certificate":"public.crt","existingCertificate":null}` | Setup for Custom CA certificates. These are automatically mounted into every secureCodeBox component (lurker, parser & hooks). Requires that every namespace has a configmap with the CA certificate(s) | | customCACertificate.certificate | string | `"public.crt"` | key in the configmap holding the certificate(s) | | customCACertificate.existingCertificate | string | `nil` | name of the configMap holding the ca certificate(s), needs to be the same across all namespaces | +| extraVolumeMounts | list | `[]` | Additional volume mounts to be mounted to the operator deployment | +| extraVolumes | list | `[]` | Additional volumes to be mounted to the operator deployment | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images | | image.repository | string | `"docker.io/securecodebox/operator"` | The operator image repository | | image.tag | string | defaults to the charts version | Parser image tag | @@ -91,14 +89,30 @@ helm install securecodebox-operator oci://ghcr.io/securecodebox/helm/operator | lurker.image.tag | string | defaults to the charts version | Parser image tag | | metrics | object | `{"serviceMonitor":{"enabled":false}}` | Configuration for the metrics the operator exports | | metrics.serviceMonitor.enabled | bool | `false` | Creates a prometheus operator ServiceMonitor rule to automatically scrape the operators metrics: https://github.com/prometheus-operator/prometheus-operator | -| minio | object | `{"auth":{"rootPassword":"password","rootUser":"admin"},"defaultBuckets":"securecodebox","enabled":true,"resources":{"requests":{"memory":"256Mi"}},"tls":{"enabled":false}}` | Minio default config. More config options an info: https://github.com/minio/minio/blob/master/helm/minio/values.yaml | +| minio | object | `{"auth":{"existingSecret":"","rootPassword":"","rootUser":"admin"},"defaultBuckets":"securecodebox","enabled":true,"image":{"pullPolicy":"IfNotPresent","repository":"docker.io/minio/minio","tag":"RELEASE.2025-07-23T15-54-02Z"},"persistence":{"size":"10Gi","storageClass":""},"podSecurityContext":{"fsGroup":1000,"runAsGroup":1000,"runAsUser":1000},"resources":{"limits":{"cpu":"500m","ephemeral-storage":"1Gi","memory":"512Mi"},"requests":{"cpu":"100m","memory":"256Mi"}},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"runAsGroup":1000,"runAsNonRoot":true,"runAsUser":1000,"seccompProfile":{"type":"RuntimeDefault"}},"tls":{"enabled":false}}` | Minio configuration for direct deployment | +| minio.auth | object | `{"existingSecret":"","rootPassword":"","rootUser":"admin"}` | Authentication configuration | +| minio.auth.existingSecret | string | `""` | Name of existing secret containing minio credentials (if set, auth.rootUser and auth.rootPassword are ignored) | +| minio.auth.rootPassword | string | `""` | Root password for minio (leave empty to generate a secure random password) | +| minio.auth.rootUser | string | `"admin"` | Root user for minio | +| minio.defaultBuckets | string | `"securecodebox"` | Default buckets to create on startup | | minio.enabled | bool | `true` | Enable this to use minio as storage backend instead of a cloud bucket provider like AWS S3, Google Cloud Storage, DigitalOcean Spaces etc. | +| minio.image | object | `{"pullPolicy":"IfNotPresent","repository":"docker.io/minio/minio","tag":"RELEASE.2025-07-23T15-54-02Z"}` | Minio image configuration | +| minio.persistence | object | `{"size":"10Gi","storageClass":""}` | Persistence configuration | +| minio.persistence.size | string | `"10Gi"` | Size of the persistent volume | +| minio.persistence.storageClass | string | `""` | Storage class for minio data persistence | +| minio.podSecurityContext | object | `{"fsGroup":1000,"runAsGroup":1000,"runAsUser":1000}` | Pod security context for minio | +| minio.resources | object | `{"limits":{"cpu":"500m","ephemeral-storage":"1Gi","memory":"512Mi"},"requests":{"cpu":"100m","memory":"256Mi"}}` | Resource limits and requests for minio | +| minio.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"runAsGroup":1000,"runAsNonRoot":true,"runAsUser":1000,"seccompProfile":{"type":"RuntimeDefault"}}` | Container security context for minio | +| minio.tls | object | `{"enabled":false}` | TLS configuration (currently not implemented) | | nodeSelector | object | `{}` | | | podSecurityContext | object | `{}` | Sets the securityContext on the operators pod level. See: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container | | presignedUrlExpirationTimes | object | `{"hooks":"1h","parsers":"1h","scanners":"12h"}` | Duration how long presigned urls are valid | +| probes | object | `{"liveness":{"httpGet":{"path":"/healthz","port":"healthchecks"},"initialDelaySeconds":15,"periodSeconds":20},"readiness":{"httpGet":{"path":"/readyz","port":"healthchecks"},"initialDelaySeconds":5,"periodSeconds":10}}` | Health and liveness probe configuration for the controller manager | +| probes.liveness | object | `{"httpGet":{"path":"/healthz","port":"healthchecks"},"initialDelaySeconds":15,"periodSeconds":20}` | Liveness probe configuration | +| probes.readiness | object | `{"httpGet":{"path":"/readyz","port":"healthchecks"},"initialDelaySeconds":5,"periodSeconds":10}` | Readiness probe configuration | | resources | object | `{"limits":{"cpu":"100m","memory":"30Mi"},"requests":{"cpu":"100m","memory":"20Mi"}}` | CPU/memory resource requests/limits (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/, https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/) | -| s3.authType | string | `"access-secret-key"` | Authentication method. Supports access-secret-key (used by most s3 endpoint) and aws-irsa (Used by AWS EKS IAM Role to Kubenetes Service Account Binding. Support for AWS IRSA is considered experimental in the secureCodeBox) | -| s3.awsStsEndpoint | string | `"https://sts.amazonaws.com"` | STS Endpoint used in AWS IRSA Authentication. Change this to the sts endpoint of your aws region. Only used when s3.authType is set to "aws-irsa" | +| s3.authType | string | `"access-secret-key"` | Authentication method. Supports `access-secret-key` (used by most s3 endpoints) and `aws-iam`` (Used by AWS EKS IAM Role to Kubernetes Service Account Binding (IRSA) and EKS Pod Identity Authentication. Support for AWS IRSA is considered experimental in the secureCodeBox) | +| s3.awsStsEndpoint | string | `"https://sts.amazonaws.com"` | STS Endpoint used in AWS IRSA Authentication. Change this to the sts endpoint of your aws region. Only used when s3.authType is set to "aws-iam". Usually not required, even in IRSA or Pod Identity setups as the region gets injected by AWS into the pod. | | s3.bucket | string | `"my-bucket"` | | | s3.enabled | bool | `false` | | | s3.endpoint | string | `"fra1.digitaloceanspaces.com"` | | diff --git a/operator/go.mod b/operator/go.mod index 8affe85235..de220eb4c9 100644 --- a/operator/go.mod +++ b/operator/go.mod @@ -4,36 +4,39 @@ module github.com/secureCodeBox/secureCodeBox/operator -go 1.24.2 +go 1.25.0 require ( github.com/go-logr/logr v1.4.3 - github.com/minio/minio-go/v7 v7.0.94 + github.com/minio/minio-go/v7 v7.0.98 github.com/mitchellh/hashstructure/v2 v2.0.2 github.com/onsi/ginkgo v1.16.5 - github.com/onsi/gomega v1.37.0 - k8s.io/api v0.33.2 - k8s.io/apimachinery v0.33.2 - k8s.io/client-go v0.33.2 - sigs.k8s.io/controller-runtime v0.21.0 + github.com/onsi/gomega v1.39.1 + k8s.io/api v0.35.0 + k8s.io/apimachinery v0.35.0 + k8s.io/client-go v0.35.0 + sigs.k8s.io/controller-runtime v0.23.1 ) require ( - github.com/blang/semver/v4 v4.0.0 // indirect github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect - github.com/fxamacker/cbor/v2 v2.8.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/go-ini/ini v1.67.0 // indirect - github.com/goccy/go-json v0.10.5 // indirect github.com/google/btree v1.1.3 // indirect - github.com/google/gnostic-models v0.6.9 // indirect - github.com/minio/crc64nvme v1.0.1 // indirect - github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect - github.com/tinylib/msgp v1.3.0 // indirect + github.com/google/gnostic-models v0.7.0 // indirect + github.com/klauspost/crc32 v1.3.0 // indirect + github.com/minio/crc64nvme v1.1.1 // indirect + github.com/philhofer/fwd v1.2.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/tinylib/msgp v1.6.1 // indirect github.com/x448/float16 v0.8.4 // indirect - golang.org/x/sync v0.13.0 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/sync v0.19.0 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 // indirect ) require ( @@ -47,46 +50,43 @@ require ( github.com/go-openapi/jsonpointer v0.21.1 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.1 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.18.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/klauspost/compress v1.18.2 // indirect + github.com/klauspost/cpuid/v2 v2.2.11 // indirect github.com/mailru/easyjson v0.9.0 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/nxadm/tail v1.4.8 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.22.0 - github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.63.0 // indirect - github.com/prometheus/procfs v0.16.0 // indirect + github.com/prometheus/client_golang v1.23.2 + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.66.1 // indirect + github.com/prometheus/procfs v0.16.1 // indirect github.com/robfig/cron v1.2.0 github.com/rs/xid v1.6.0 // indirect - github.com/spf13/pflag v1.0.6 // indirect + github.com/spf13/pflag v1.0.9 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.37.0 // indirect - golang.org/x/net v0.39.0 // indirect - golang.org/x/oauth2 v0.29.0 // indirect - golang.org/x/sys v0.32.0 // indirect - golang.org/x/term v0.31.0 // indirect - golang.org/x/text v0.24.0 // indirect + golang.org/x/crypto v0.47.0 // indirect + golang.org/x/net v0.49.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/term v0.39.0 // indirect + golang.org/x/text v0.33.0 // indirect golang.org/x/time v0.11.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.33.0 // indirect - k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect - k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect + k8s.io/apiextensions-apiserver v0.35.0 // indirect + k8s.io/klog/v2 v2.130.1 + k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect ) diff --git a/operator/go.sum b/operator/go.sum index 66c11818ff..b192f3e23d 100644 --- a/operator/go.sum +++ b/operator/go.sum @@ -1,7 +1,7 @@ +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -20,8 +20,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU= -github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= @@ -38,10 +38,6 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8Wd github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= -github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -51,19 +47,18 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= -github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= +github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= +github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -71,13 +66,13 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= +github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= -github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU= +github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/klauspost/crc32 v1.3.0 h1:sSmTt3gUt81RP655XGZPElI0PelVTZ6YwCRnPSupoFM= +github.com/klauspost/crc32 v1.3.0/go.mod h1:D7kQaZhnkX/Y0tstFGf8VUzv2UofNGqCjnC3zdHB0Hw= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -86,19 +81,20 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= -github.com/minio/crc64nvme v1.0.1 h1:DHQPrYPdqK7jQG/Ls5CTBZWeex/2FMS3G5XGkycuFrY= -github.com/minio/crc64nvme v1.0.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg= +github.com/minio/crc64nvme v1.1.1 h1:8dwx/Pz49suywbO+auHCBpCtlW1OfpcLN7wYgVR6wAI= +github.com/minio/crc64nvme v1.1.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= -github.com/minio/minio-go/v7 v7.0.94 h1:1ZoksIKPyaSt64AVOyaQvhDOgVC3MfZsWM6mZXRUGtM= -github.com/minio/minio-go/v7 v7.0.94/go.mod h1:71t2CqDt3ThzESgZUlU1rBN54mksGGlkLcFgguDnnAc= +github.com/minio/minio-go/v7 v7.0.98 h1:MeAVKjLVz+XJ28zFcuYyImNSAh8Mq725uNW4beRisi0= +github.com/minio/minio-go/v7 v7.0.98/go.mod h1:cY0Y+W7yozf0mdIclrttzo1Iiu7mEf9y7nk2uXqMOvM= github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -108,46 +104,45 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.23.3 h1:edHxnszytJ4lD9D5Jjc4tiDkPBZ3siDeJJkUZJJVkp0= -github.com/onsi/ginkgo/v2 v2.23.3/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM= +github.com/onsi/ginkgo/v2 v2.28.0 h1:Rrf+lVLmtlBIKv6KrIGJCjyY8N36vDVcutbGJkyqjJc= +github.com/onsi/ginkgo/v2 v2.28.0/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y= -github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= -github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY= -github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= +github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= +github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= +github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= +github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= -github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= -github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= -github.com/prometheus/procfs v0.16.0 h1:xh6oHhKwnOJKMYiYBDWmkHqQPyiY40sny36Cmx2bbsM= -github.com/prometheus/procfs v0.16.0/go.mod h1:8veyXUu3nGP7oaCxhX6yeaM5u4stL2FeMXnCqhDthZg= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= +github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= +github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= -github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= -github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tinylib/msgp v1.3.0 h1:ULuf7GPooDaIlbyvgAxBV/FI7ynli6LZ1/nVUNu+0ww= -github.com/tinylib/msgp v1.3.0/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/tinylib/msgp v1.6.1 h1:ESRv8eL3u+DNHUoSAAQRE50Hm162zqAnBoGv9PzScPY= +github.com/tinylib/msgp v1.6.1/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -155,29 +150,32 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= -golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= +golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= +golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= -golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= -golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98= -golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -187,23 +185,21 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= -golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= -golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= +golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= -golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= +golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -216,13 +212,13 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= @@ -233,28 +229,27 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.33.2 h1:YgwIS5jKfA+BZg//OQhkJNIfie/kmRsO0BmNaVSimvY= -k8s.io/api v0.33.2/go.mod h1:fhrbphQJSM2cXzCWgqU29xLDuks4mu7ti9vveEnpSXs= -k8s.io/apiextensions-apiserver v0.33.0 h1:d2qpYL7Mngbsc1taA4IjJPRJ9ilnsXIrndH+r9IimOs= -k8s.io/apiextensions-apiserver v0.33.0/go.mod h1:VeJ8u9dEEN+tbETo+lFkwaaZPg6uFKLGj5vyNEwwSzc= -k8s.io/apimachinery v0.33.2 h1:IHFVhqg59mb8PJWTLi8m1mAoepkUNYmptHsV+Z1m5jY= -k8s.io/apimachinery v0.33.2/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= -k8s.io/client-go v0.33.2 h1:z8CIcc0P581x/J1ZYf4CNzRKxRvQAwoAolYPbtQes+E= -k8s.io/client-go v0.33.2/go.mod h1:9mCgT4wROvL948w6f6ArJNb7yQd7QsvqavDeZHvNmHo= +k8s.io/api v0.35.0 h1:iBAU5LTyBI9vw3L5glmat1njFK34srdLmktWwLTprlY= +k8s.io/api v0.35.0/go.mod h1:AQ0SNTzm4ZAczM03QH42c7l3bih1TbAXYo0DkF8ktnA= +k8s.io/apiextensions-apiserver v0.35.0 h1:3xHk2rTOdWXXJM+RDQZJvdx0yEOgC0FgQ1PlJatA5T4= +k8s.io/apiextensions-apiserver v0.35.0/go.mod h1:E1Ahk9SADaLQ4qtzYFkwUqusXTcaV2uw3l14aqpL2LU= +k8s.io/apimachinery v0.35.0 h1:Z2L3IHvPVv/MJ7xRxHEtk6GoJElaAqDCCU0S6ncYok8= +k8s.io/apimachinery v0.35.0/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= +k8s.io/client-go v0.35.0 h1:IAW0ifFbfQQwQmga0UdoH0yvdqrbwMdq9vIFEhRpxBE= +k8s.io/client-go v0.35.0/go.mod h1:q2E5AAyqcbeLGPdoRB+Nxe3KYTfPce1Dnu1myQdqz9o= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= -k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro= -k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= -sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= -sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE= +sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 h1:2WOzJpHUBVrrkDjU4KBT8n5LDcj824eX0I5UKcgeRUs= +sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/operator/internal/telemetry/telemetry.go b/operator/internal/telemetry/telemetry.go index cceaa45320..a0a7010bb2 100644 --- a/operator/internal/telemetry/telemetry.go +++ b/operator/internal/telemetry/telemetry.go @@ -24,8 +24,8 @@ var telemetryInterval = 24 * time.Hour // officialScanTypes contains the list of official secureCodeBox Scan Types. // Unofficial Scan Types should be reported as "other" to avoid leakage of confidential data via the scan-types name var officialScanTypes map[string]bool = map[string]bool{ - "amass": true, - "cmseek": true, + "amass": true, // deprecated. we'll keep it in this list to still recieve telemetry data from older versions + "cmseek": true, // deprecated. we'll keep it in this list to still recieve telemetry data from older versions "doggo": true, // deprecated. we'll keep it in this list to still recieve telemetry data from older versions "ffuf": true, "git-repo-scanner": true, @@ -41,17 +41,18 @@ var officialScanTypes map[string]bool = map[string]bool{ "ssh-audit": true, "ssh-scan": true, // deprecated. we'll keep it in this list to still recieve telemetry data from older versions "sslyze": true, + "subfinder": true, "trivy-image": true, "trivy-filesystem": true, "trivy-repo": true, "trivy-sbom-image": true, "typo3scan": true, // deprecated. we'll keep it in this list to still recieve telemetry data from older versions - "whatweb": true, + "whatweb": true, // deprecated. we'll keep it in this list to still recieve telemetry data from older versions "wpscan": true, "zap-baseline-scan": true, // deprecated. we'll keep it in this list to still recieve telemetry data from older versions - "zap-api-scan": true, - "zap-full-scan": true, - "zap-automation-scan": true, + "zap-api-scan": true, // deprecated. we'll keep it in this list to still recieve telemetry data from older versions + "zap-full-scan": true, // deprecated. we'll keep it in this list to still recieve telemetry data from older versions + "zap-automation-scan": true, // deprecated. we'll keep it in this list to still recieve telemetry data from older versions "zap-automation-framework": true, "zap-advanced-scan": true, // deprecated. we'll keep it in this list to still recieve telemetry data from older versions } diff --git a/operator/main.go b/operator/main.go index 61a0bf754e..a194750a52 100644 --- a/operator/main.go +++ b/operator/main.go @@ -15,6 +15,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" + "k8s.io/klog/v2" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" @@ -51,12 +52,14 @@ func main() { "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") opts := zap.Options{ - Development: true, + Development: false, } opts.BindFlags(flag.CommandLine) flag.Parse() - ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + logger := zap.New(zap.UseFlagOptions(&opts)) + ctrl.SetLogger(logger) + klog.SetLogger(logger) mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ Scheme: scheme, diff --git a/operator/templates/_helpers.tpl b/operator/templates/_helpers.tpl new file mode 100644 index 0000000000..c530383315 --- /dev/null +++ b/operator/templates/_helpers.tpl @@ -0,0 +1,57 @@ +{{- /* +SPDX-FileCopyrightText: the secureCodeBox authors + +SPDX-License-Identifier: Apache-2.0 +*/ -}} + +{{/* +Expand the name of the chart. +*/}} +{{- define "operator.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "operator.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "operator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "operator.labels" -}} +helm.sh/chart: {{ include "operator.chart" . }} +{{ include "operator.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "operator.selectorLabels" -}} +app.kubernetes.io/name: {{ include "operator.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} \ No newline at end of file diff --git a/operator/templates/manager/manager.yaml b/operator/templates/manager/manager.yaml index f5f90a8382..a6661074e8 100644 --- a/operator/templates/manager/manager.yaml +++ b/operator/templates/manager/manager.yaml @@ -19,11 +19,16 @@ spec: labels: control-plane: securecodebox-controller-manager spec: - {{- if .Values.customCACertificate.existingCertificate }} + {{- if or .Values.customCACertificate.existingCertificate .Values.extraVolumes }} volumes: + {{- if .Values.customCACertificate.existingCertificate }} - name: ca-certificate configMap: name: {{ .Values.customCACertificate.existingCertificate }} + {{- end }} + {{- range .Values.extraVolumes }} + - {{ toYaml . | nindent 10 }} + {{- end }} {{- end }} serviceAccountName: {{ .Values.serviceAccount.name }} securityContext: @@ -38,11 +43,16 @@ spec: args: - --leader-elect image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.Version }}" - {{- if .Values.customCACertificate.existingCertificate }} + {{- if or .Values.customCACertificate.existingCertificate .Values.extraVolumeMounts }} volumeMounts: + {{- if .Values.customCACertificate.existingCertificate }} - name: ca-certificate mountPath: /etc/ssl/certs/{{ .Values.customCACertificate.certificate }} subPath: {{ .Values.customCACertificate.certificate }} + {{- end }} + {{- range .Values.extraVolumeMounts }} + - {{ toYaml . | nindent 14 }} + {{- end }} {{- end }} imagePullPolicy: {{ .Values.image.pullPolicy }} name: manager @@ -52,17 +62,9 @@ spec: - name: healthchecks containerPort: 8081 livenessProbe: - httpGet: - path: /healthz - port: healthchecks - initialDelaySeconds: 15 - periodSeconds: 20 + {{- toYaml .Values.probes.liveness | nindent 12 }} readinessProbe: - httpGet: - path: /readyz - port: healthchecks - initialDelaySeconds: 5 - periodSeconds: 10 + {{- toYaml .Values.probes.readiness | nindent 12 }} env: - name: TELEMETRY_ENABLED value: {{ .Values.telemetryEnabled | quote }} @@ -79,12 +81,12 @@ spec: - name: MINIO_ACCESS_KEY valueFrom: secretKeyRef: - name: "{{ .Release.Name }}-minio" + name: {{ .Values.minio.auth.existingSecret | default (printf "%s-minio" (include "operator.fullname" .)) }} key: root-user - name: MINIO_SECRET_KEY valueFrom: secretKeyRef: - name: "{{ .Release.Name }}-minio" + name: {{ .Values.minio.auth.existingSecret | default (printf "%s-minio" (include "operator.fullname" .)) }} key: root-password - name: S3_BUCKET value: {{ .Values.minio.defaultBuckets }} @@ -98,7 +100,7 @@ spec: value: {{ .Values.s3.bucket }} {{- if .Values.s3.port }} - name: S3_PORT - value: {{ .Values.s3.port }} + value: {{ .Values.s3.port | quote }} {{- end }} - name: S3_AUTH_TYPE value: {{ .Values.s3.authType }} @@ -114,7 +116,8 @@ spec: name: {{ .Values.s3.keySecret }} key: {{ .Values.s3.secretAttributeNames.secretkey }} {{- end }} - {{- if eq .Values.s3.authType "aws-irsa" }} + # todo(v6): remove support for authType = "aws-irsa" and only support "aws-iam": https://github.com/secureCodeBox/secureCodeBox/issues/3327 + {{- if or (eq .Values.s3.authType "aws-irsa") (eq .Values.s3.authType "aws-iam") }} - name: S3_AWS_IRSA_STS_ENDPOINT value: {{ .Values.s3.awsStsEndpoint | quote }} {{- end }} diff --git a/operator/templates/minio/secret.yaml b/operator/templates/minio/secret.yaml new file mode 100644 index 0000000000..00998ec193 --- /dev/null +++ b/operator/templates/minio/secret.yaml @@ -0,0 +1,22 @@ +# SPDX-FileCopyrightText: the secureCodeBox authors +# +# SPDX-License-Identifier: Apache-2.0 + +{{- if .Values.minio.enabled }} +{{- if not .Values.minio.auth.existingSecret }} +{{- $minioSecretName := printf "%s-minio" (include "operator.fullname" .) }} +{{- $existingSecret := lookup "v1" "Secret" .Release.Namespace $minioSecretName }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ $minioSecretName }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "operator.labels" . | nindent 4 }} + app.kubernetes.io/component: minio +type: Opaque +data: + root-user: {{ if $existingSecret }}{{ index $existingSecret.data "root-user" }}{{ else }}{{ .Values.minio.auth.rootUser | b64enc | quote }}{{ end }} + root-password: {{ if $existingSecret }}{{ index $existingSecret.data "root-password" }}{{ else }}{{ if .Values.minio.auth.rootPassword }}{{ .Values.minio.auth.rootPassword | b64enc | quote }}{{ else }}{{ (randAlphaNum 32) | b64enc | quote }}{{ end }}{{ end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/operator/templates/minio/service.yaml b/operator/templates/minio/service.yaml new file mode 100644 index 0000000000..b51eb6fbce --- /dev/null +++ b/operator/templates/minio/service.yaml @@ -0,0 +1,28 @@ +# SPDX-FileCopyrightText: the secureCodeBox authors +# +# SPDX-License-Identifier: Apache-2.0 + +{{- if .Values.minio.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "operator.fullname" . }}-minio + namespace: {{ .Release.Namespace }} + labels: + {{- include "operator.labels" . | nindent 4 }} + app.kubernetes.io/component: minio +spec: + type: ClusterIP + ports: + - port: 9000 + targetPort: 9000 + protocol: TCP + name: api + - port: 9001 + targetPort: 9001 + protocol: TCP + name: console + selector: + {{- include "operator.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: minio +{{- end }} \ No newline at end of file diff --git a/operator/templates/minio/statefulset.yaml b/operator/templates/minio/statefulset.yaml new file mode 100644 index 0000000000..49d8560c45 --- /dev/null +++ b/operator/templates/minio/statefulset.yaml @@ -0,0 +1,117 @@ +# SPDX-FileCopyrightText: the secureCodeBox authors +# +# SPDX-License-Identifier: Apache-2.0 + +{{- if .Values.minio.enabled }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "operator.fullname" . }}-minio + namespace: {{ .Release.Namespace }} + labels: + {{- include "operator.labels" . | nindent 4 }} + app.kubernetes.io/component: minio +spec: + serviceName: {{ include "operator.fullname" . }}-minio + replicas: 1 + selector: + matchLabels: + {{- include "operator.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: minio + template: + metadata: + labels: + {{- include "operator.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: minio + spec: + automountServiceAccountToken: false + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- toYaml .Values.minio.podSecurityContext | nindent 8 }} + containers: + - name: minio + image: {{ .Values.minio.image.repository }}:{{ .Values.minio.image.tag }} + imagePullPolicy: {{ .Values.minio.image.pullPolicy }} + command: + - /bin/bash + - -c + args: + - | + set -e + echo "Starting minio server..." + minio server /data --console-address ":9001" & + MINIO_PID=$! + + echo "Waiting for minio to be ready..." + sleep 5 + + echo "Creating bucket: $MINIO_DEFAULT_BUCKETS" + mc alias set myminio http://localhost:9000 $MINIO_ROOT_USER $MINIO_ROOT_PASSWORD + mc mb myminio/$MINIO_DEFAULT_BUCKETS --ignore-existing || true + echo "Bucket creation completed" + + wait $MINIO_PID + env: + - name: MINIO_ROOT_USER + valueFrom: + secretKeyRef: + name: {{ .Values.minio.auth.existingSecret | default (printf "%s-minio" (include "operator.fullname" .)) }} + key: root-user + - name: MINIO_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.minio.auth.existingSecret | default (printf "%s-minio" (include "operator.fullname" .)) }} + key: root-password + - name: MINIO_DEFAULT_BUCKETS + value: {{ .Values.minio.defaultBuckets | quote }} + ports: + - name: api + containerPort: 9000 + protocol: TCP + - name: console + containerPort: 9001 + protocol: TCP + livenessProbe: + httpGet: + path: /minio/health/live + port: api + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /minio/health/ready + port: api + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 3 + resources: + {{- toYaml .Values.minio.resources | nindent 12 }} + volumeMounts: + - name: data + mountPath: /data + securityContext: + {{- toYaml .Values.minio.securityContext | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + volumeClaimTemplates: + - metadata: + name: data + spec: + accessModes: [ "ReadWriteOnce" ] + {{- if .Values.minio.persistence.storageClass }} + storageClassName: {{ .Values.minio.persistence.storageClass | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.minio.persistence.size | quote }} +{{- end }} \ No newline at end of file diff --git a/operator/tests/__snapshot__/operator_test.yaml.snap b/operator/tests/__snapshot__/operator_test.yaml.snap index 4fa4ecf859..0df925307e 100644 --- a/operator/tests/__snapshot__/operator_test.yaml.snap +++ b/operator/tests/__snapshot__/operator_test.yaml.snap @@ -1,6 +1,6 @@ matches the snapshot: 1: | - raw: "\nsecureCodeBox Operator Deployed \U0001F680\n\nThe operator can orchestrate the execution of various security scanning tools inside of your cluster.\nYou can find a list of all officially supported scanners here: https://www.securecodebox.io/\nThe website also lists other integrations, like persisting scan results to DefectDojo or Elasticsearch.\n\nThe operator send out regular telemetry pings to a central service.\nThis lets us, the secureCodeBox team, get a grasp on how much the secureCodeBox is used.\nThe submitted data is chosen to be as anonymous as possible.\nYou can find a complete report of the data submitted and links to the source-code at: https://www.securecodebox.io/docs/telemetry\nThe first ping is send one hour after the install, you can prevent this by upgrading the chart and setting `telemetryEnabled` to `false`.\n" + raw: "secureCodeBox Operator Deployed \U0001F680\n\nThe operator can orchestrate the execution of various security scanning tools inside of your cluster.\nYou can find a list of all officially supported scanners here: https://www.securecodebox.io/\nThe website also lists other integrations, like persisting scan results to DefectDojo or Elasticsearch.\n\nThe operator send out regular telemetry pings to a central service.\nThis lets us, the secureCodeBox team, get a grasp on how much the secureCodeBox is used.\nThe submitted data is chosen to be as anonymous as possible.\nYou can find a complete report of the data submitted and links to the source-code at: https://www.securecodebox.io/docs/telemetry\nThe first ping is send one hour after the install, you can prevent this by upgrading the chart and setting `telemetryEnabled` to `false`.\n" 2: | apiVersion: v1 kind: Service @@ -56,12 +56,12 @@ matches the snapshot: valueFrom: secretKeyRef: key: root-user - name: RELEASE-NAME-minio + name: RELEASE-NAME-operator-minio - name: MINIO_SECRET_KEY valueFrom: secretKeyRef: key: root-password - name: RELEASE-NAME-minio + name: RELEASE-NAME-operator-minio - name: S3_BUCKET value: securecodebox - name: LURKER_IMAGE @@ -134,6 +134,177 @@ matches the snapshot: name: foo name: ca-certificate 4: | + apiVersion: v1 + data: + root-password: dGVzdHBhc3N3b3Jk + root-user: dGVzdHVzZXI= + kind: Secret + metadata: + labels: + app.kubernetes.io/component: minio + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: operator + app.kubernetes.io/version: 0.0.0 + helm.sh/chart: operator-0.0.0 + name: RELEASE-NAME-operator-minio + namespace: NAMESPACE + type: Opaque + 5: | + apiVersion: v1 + kind: Service + metadata: + labels: + app.kubernetes.io/component: minio + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: operator + app.kubernetes.io/version: 0.0.0 + helm.sh/chart: operator-0.0.0 + name: RELEASE-NAME-operator-minio + namespace: NAMESPACE + spec: + ports: + - name: api + port: 9000 + protocol: TCP + targetPort: 9000 + - name: console + port: 9001 + protocol: TCP + targetPort: 9001 + selector: + app.kubernetes.io/component: minio + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: operator + type: ClusterIP + 6: | + apiVersion: apps/v1 + kind: StatefulSet + metadata: + labels: + app.kubernetes.io/component: minio + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: operator + app.kubernetes.io/version: 0.0.0 + helm.sh/chart: operator-0.0.0 + name: RELEASE-NAME-operator-minio + namespace: NAMESPACE + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: minio + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: operator + serviceName: RELEASE-NAME-operator-minio + template: + metadata: + labels: + app.kubernetes.io/component: minio + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: operator + spec: + automountServiceAccountToken: false + containers: + - args: + - | + set -e + echo "Starting minio server..." + minio server /data --console-address ":9001" & + MINIO_PID=$! + + echo "Waiting for minio to be ready..." + sleep 5 + + echo "Creating bucket: $MINIO_DEFAULT_BUCKETS" + mc alias set myminio http://localhost:9000 $MINIO_ROOT_USER $MINIO_ROOT_PASSWORD + mc mb myminio/$MINIO_DEFAULT_BUCKETS --ignore-existing || true + echo "Bucket creation completed" + + wait $MINIO_PID + command: + - /bin/bash + - -c + env: + - name: MINIO_ROOT_USER + valueFrom: + secretKeyRef: + key: root-user + name: RELEASE-NAME-operator-minio + - name: MINIO_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: root-password + name: RELEASE-NAME-operator-minio + - name: MINIO_DEFAULT_BUCKETS + value: securecodebox + image: docker.io/minio/minio:RELEASE.2025-07-23T15-54-02Z + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /minio/health/live + port: api + initialDelaySeconds: 30 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 10 + name: minio + ports: + - containerPort: 9000 + name: api + protocol: TCP + - containerPort: 9001 + name: console + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /minio/health/ready + port: api + initialDelaySeconds: 5 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 5 + resources: + limits: + cpu: 500m + ephemeral-storage: 1Gi + memory: 512Mi + requests: + cpu: 100m + memory: 256Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /data + name: data + imagePullSecrets: + - name: foo + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsUser: 1000 + volumeClaimTemplates: + - metadata: + name: data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + 7: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -157,7 +328,7 @@ matches the snapshot: - cascadingrules/status verbs: - get - 5: | + 8: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -177,7 +348,7 @@ matches the snapshot: - cascadingrules/status verbs: - get - 6: | + 9: | apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: @@ -214,7 +385,7 @@ matches the snapshot: verbs: - create - patch - 7: | + 10: | apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: @@ -227,7 +398,7 @@ matches the snapshot: - kind: ServiceAccount name: securecodebox-operator namespace: NAMESPACE - 8: | + 11: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -251,7 +422,7 @@ matches the snapshot: - parsedefinitions/status verbs: - get - 9: | + 12: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -271,7 +442,7 @@ matches the snapshot: - parsedefinitions/status verbs: - get - 10: | + 13: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -370,7 +541,7 @@ matches the snapshot: - list - update - watch - 11: | + 14: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: @@ -383,7 +554,7 @@ matches the snapshot: - kind: ServiceAccount name: securecodebox-operator namespace: NAMESPACE - 12: | + 15: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -407,7 +578,7 @@ matches the snapshot: - scans/status verbs: - get - 13: | + 16: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -427,7 +598,7 @@ matches the snapshot: - scans/status verbs: - get - 14: | + 17: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -451,7 +622,7 @@ matches the snapshot: - scancompletionhooks/status verbs: - get - 15: | + 18: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -471,7 +642,7 @@ matches the snapshot: - scancompletionhooks/status verbs: - get - 16: | + 19: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -495,7 +666,7 @@ matches the snapshot: - scantypes/status verbs: - get - 17: | + 20: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -515,7 +686,7 @@ matches the snapshot: - scantypes/status verbs: - get - 18: | + 21: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -539,7 +710,7 @@ matches the snapshot: - scheduledscans/status verbs: - get - 19: | + 22: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -559,7 +730,7 @@ matches the snapshot: - scheduledscans/status verbs: - get - 20: | + 23: | apiVersion: v1 kind: ServiceAccount metadata: @@ -568,7 +739,7 @@ matches the snapshot: name: securecodebox-operator properly-renders-the-service-monitor-when-enabled: 1: | - raw: "\nsecureCodeBox Operator Deployed \U0001F680\n\nThe operator can orchestrate the execution of various security scanning tools inside of your cluster.\nYou can find a list of all officially supported scanners here: https://www.securecodebox.io/\nThe website also lists other integrations, like persisting scan results to DefectDojo or Elasticsearch.\n\nThe operator send out regular telemetry pings to a central service.\nThis lets us, the secureCodeBox team, get a grasp on how much the secureCodeBox is used.\nThe submitted data is chosen to be as anonymous as possible.\nYou can find a complete report of the data submitted and links to the source-code at: https://www.securecodebox.io/docs/telemetry\nThe first ping is send one hour after the install, you can prevent this by upgrading the chart and setting `telemetryEnabled` to `false`.\n" + raw: "secureCodeBox Operator Deployed \U0001F680\n\nThe operator can orchestrate the execution of various security scanning tools inside of your cluster.\nYou can find a list of all officially supported scanners here: https://www.securecodebox.io/\nThe website also lists other integrations, like persisting scan results to DefectDojo or Elasticsearch.\n\nThe operator send out regular telemetry pings to a central service.\nThis lets us, the secureCodeBox team, get a grasp on how much the secureCodeBox is used.\nThe submitted data is chosen to be as anonymous as possible.\nYou can find a complete report of the data submitted and links to the source-code at: https://www.securecodebox.io/docs/telemetry\nThe first ping is send one hour after the install, you can prevent this by upgrading the chart and setting `telemetryEnabled` to `false`.\n" 2: | apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor @@ -637,12 +808,12 @@ properly-renders-the-service-monitor-when-enabled: valueFrom: secretKeyRef: key: root-user - name: RELEASE-NAME-minio + name: RELEASE-NAME-operator-minio - name: MINIO_SECRET_KEY valueFrom: secretKeyRef: key: root-password - name: RELEASE-NAME-minio + name: RELEASE-NAME-operator-minio - name: S3_BUCKET value: securecodebox - name: LURKER_IMAGE @@ -715,6 +886,177 @@ properly-renders-the-service-monitor-when-enabled: name: foo name: ca-certificate 5: | + apiVersion: v1 + data: + root-password: dGVzdHBhc3N3b3Jk + root-user: dGVzdHVzZXI= + kind: Secret + metadata: + labels: + app.kubernetes.io/component: minio + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: operator + app.kubernetes.io/version: 0.0.0 + helm.sh/chart: operator-0.0.0 + name: RELEASE-NAME-operator-minio + namespace: NAMESPACE + type: Opaque + 6: | + apiVersion: v1 + kind: Service + metadata: + labels: + app.kubernetes.io/component: minio + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: operator + app.kubernetes.io/version: 0.0.0 + helm.sh/chart: operator-0.0.0 + name: RELEASE-NAME-operator-minio + namespace: NAMESPACE + spec: + ports: + - name: api + port: 9000 + protocol: TCP + targetPort: 9000 + - name: console + port: 9001 + protocol: TCP + targetPort: 9001 + selector: + app.kubernetes.io/component: minio + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: operator + type: ClusterIP + 7: | + apiVersion: apps/v1 + kind: StatefulSet + metadata: + labels: + app.kubernetes.io/component: minio + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: operator + app.kubernetes.io/version: 0.0.0 + helm.sh/chart: operator-0.0.0 + name: RELEASE-NAME-operator-minio + namespace: NAMESPACE + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: minio + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: operator + serviceName: RELEASE-NAME-operator-minio + template: + metadata: + labels: + app.kubernetes.io/component: minio + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: operator + spec: + automountServiceAccountToken: false + containers: + - args: + - | + set -e + echo "Starting minio server..." + minio server /data --console-address ":9001" & + MINIO_PID=$! + + echo "Waiting for minio to be ready..." + sleep 5 + + echo "Creating bucket: $MINIO_DEFAULT_BUCKETS" + mc alias set myminio http://localhost:9000 $MINIO_ROOT_USER $MINIO_ROOT_PASSWORD + mc mb myminio/$MINIO_DEFAULT_BUCKETS --ignore-existing || true + echo "Bucket creation completed" + + wait $MINIO_PID + command: + - /bin/bash + - -c + env: + - name: MINIO_ROOT_USER + valueFrom: + secretKeyRef: + key: root-user + name: RELEASE-NAME-operator-minio + - name: MINIO_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: root-password + name: RELEASE-NAME-operator-minio + - name: MINIO_DEFAULT_BUCKETS + value: securecodebox + image: docker.io/minio/minio:RELEASE.2025-07-23T15-54-02Z + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /minio/health/live + port: api + initialDelaySeconds: 30 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 10 + name: minio + ports: + - containerPort: 9000 + name: api + protocol: TCP + - containerPort: 9001 + name: console + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /minio/health/ready + port: api + initialDelaySeconds: 5 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 5 + resources: + limits: + cpu: 500m + ephemeral-storage: 1Gi + memory: 512Mi + requests: + cpu: 100m + memory: 256Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /data + name: data + imagePullSecrets: + - name: foo + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsUser: 1000 + volumeClaimTemplates: + - metadata: + name: data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + 8: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -738,7 +1080,7 @@ properly-renders-the-service-monitor-when-enabled: - cascadingrules/status verbs: - get - 6: | + 9: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -758,7 +1100,7 @@ properly-renders-the-service-monitor-when-enabled: - cascadingrules/status verbs: - get - 7: | + 10: | apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: @@ -795,7 +1137,7 @@ properly-renders-the-service-monitor-when-enabled: verbs: - create - patch - 8: | + 11: | apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: @@ -808,7 +1150,7 @@ properly-renders-the-service-monitor-when-enabled: - kind: ServiceAccount name: securecodebox-operator namespace: NAMESPACE - 9: | + 12: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -832,7 +1174,7 @@ properly-renders-the-service-monitor-when-enabled: - parsedefinitions/status verbs: - get - 10: | + 13: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -852,7 +1194,7 @@ properly-renders-the-service-monitor-when-enabled: - parsedefinitions/status verbs: - get - 11: | + 14: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -951,7 +1293,7 @@ properly-renders-the-service-monitor-when-enabled: - list - update - watch - 12: | + 15: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: @@ -964,7 +1306,7 @@ properly-renders-the-service-monitor-when-enabled: - kind: ServiceAccount name: securecodebox-operator namespace: NAMESPACE - 13: | + 16: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -988,7 +1330,7 @@ properly-renders-the-service-monitor-when-enabled: - scans/status verbs: - get - 14: | + 17: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -1008,7 +1350,7 @@ properly-renders-the-service-monitor-when-enabled: - scans/status verbs: - get - 15: | + 18: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -1032,7 +1374,7 @@ properly-renders-the-service-monitor-when-enabled: - scancompletionhooks/status verbs: - get - 16: | + 19: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -1052,7 +1394,7 @@ properly-renders-the-service-monitor-when-enabled: - scancompletionhooks/status verbs: - get - 17: | + 20: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -1076,7 +1418,7 @@ properly-renders-the-service-monitor-when-enabled: - scantypes/status verbs: - get - 18: | + 21: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -1096,7 +1438,7 @@ properly-renders-the-service-monitor-when-enabled: - scantypes/status verbs: - get - 19: | + 22: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -1120,7 +1462,7 @@ properly-renders-the-service-monitor-when-enabled: - scheduledscans/status verbs: - get - 20: | + 23: | apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -1140,7 +1482,7 @@ properly-renders-the-service-monitor-when-enabled: - scheduledscans/status verbs: - get - 21: | + 24: | apiVersion: v1 kind: ServiceAccount metadata: diff --git a/operator/tests/operator_test.yaml b/operator/tests/operator_test.yaml index bd56c7eeaf..6c8dbc6380 100644 --- a/operator/tests/operator_test.yaml +++ b/operator/tests/operator_test.yaml @@ -7,6 +7,7 @@ templates: - NOTES.txt - rbac/*.yaml - manager/*.yaml + - minio/*.yaml tests: - it: matches the snapshot chart: @@ -17,6 +18,11 @@ tests: customCACertificate.existingCertificate: foo serviceaccount: {create: true, annotations: {foo: bar}, name: foo} podSecurityContext: {fsGroup: 1234} + minio: + enabled: true + auth: + rootUser: testuser + rootPassword: testpassword asserts: - matchSnapshot: {} - it: properly-renders-the-service-monitor-when-enabled @@ -28,9 +34,133 @@ tests: customCACertificate.existingCertificate: foo serviceaccount: {create: true, annotations: {foo: bar}, name: foo} podSecurityContext: {fsGroup: 1234} - metrics: serviceMonitor: enabled: true + minio: + enabled: true + auth: + rootUser: testuser + rootPassword: testpassword asserts: - matchSnapshot: {} + - it: renders minio resources when minio is enabled + templates: + - minio/secret.yaml + - minio/service.yaml + - minio/statefulset.yaml + chart: + version: 0.0.0 + appVersion: 0.0.0 + set: + minio: + enabled: true + auth: + rootUser: testuser + rootPassword: testpassword + asserts: + - hasDocuments: + count: 1 + - it: does not render minio resources when minio is disabled + templates: + - minio/secret.yaml + - minio/service.yaml + - minio/statefulset.yaml + chart: + version: 0.0.0 + appVersion: 0.0.0 + set: + minio: + enabled: false + asserts: + - hasDocuments: + count: 0 + - it: configures manager deployment for minio + templates: + - manager/manager.yaml + chart: + version: 0.0.0 + appVersion: 0.0.0 + set: + minio: + enabled: true + asserts: + - equal: + path: spec.template.spec.containers[0].env[?(@.name=="S3_USE_SSL")].value + value: "false" + - equal: + path: spec.template.spec.containers[0].env[?(@.name=="S3_ENDPOINT")].value + value: "RELEASE-NAME-minio.NAMESPACE.svc.cluster.local" + - it: configures manager deployment for external s3 + templates: + - manager/manager.yaml + chart: + version: 0.0.0 + appVersion: 0.0.0 + set: + minio: + enabled: false + s3: + enabled: true + endpoint: "s3.amazonaws.com" + bucket: "my-bucket" + tls: + enabled: true + asserts: + - equal: + path: spec.template.spec.containers[0].env[?(@.name=="S3_USE_SSL")].value + value: "true" + - equal: + path: spec.template.spec.containers[0].env[?(@.name=="S3_ENDPOINT")].value + value: "s3.amazonaws.com" + - equal: + path: spec.template.spec.containers[0].env[?(@.name=="S3_BUCKET")].value + value: "my-bucket" + - it: renders minio secret with custom credentials + templates: + - minio/secret.yaml + chart: + version: 0.0.0 + appVersion: 0.0.0 + set: + minio: + enabled: true + auth: + rootUser: customuser + rootPassword: custompassword + asserts: + - equal: + path: data.root-user + value: Y3VzdG9tdXNlcg== + - equal: + path: data.root-password + value: Y3VzdG9tcGFzc3dvcmQ= + - it: omits storageClassName when not specified to use default + templates: + - minio/statefulset.yaml + chart: + version: 0.0.0 + appVersion: 0.0.0 + set: + minio: + enabled: true + persistence: + storageClass: "" + asserts: + - notExists: + path: spec.volumeClaimTemplates[0].spec.storageClassName + - it: includes storageClassName when specified + templates: + - minio/statefulset.yaml + chart: + version: 0.0.0 + appVersion: 0.0.0 + set: + minio: + enabled: true + persistence: + storageClass: "fast-ssd" + asserts: + - equal: + path: spec.volumeClaimTemplates[0].spec.storageClassName + value: "fast-ssd" diff --git a/operator/utils/hash_test.go b/operator/utils/hash_test.go index 049591fa0c..d084c9fa8d 100644 --- a/operator/utils/hash_test.go +++ b/operator/utils/hash_test.go @@ -53,7 +53,7 @@ var _ = Describe("ScanType Hashing", func() { It("should hash scantype consistently", func() { hashValues := HashScanType(scanType) // note: this hash changes with every kubernetes release as kubernetes adds new field to their objects which causes the hashes to change. - Expect(hashValues).To(Equal(uint64(0xba4b605a6550aca3)), "Should hash scantype consistently") + Expect(hashValues).To(Equal(uint64(6491418262890710719)), "Should hash scantype consistently") }) It("should ignore non-scb annotations on the scantypes", func() { diff --git a/operator/values.yaml b/operator/values.yaml index ae9a70be41..468a21c4f2 100644 --- a/operator/values.yaml +++ b/operator/values.yaml @@ -29,6 +29,32 @@ customCACertificate: # -- key in the configmap holding the certificate(s) certificate: "public.crt" + +# -- Additional volumes to be mounted to the operator deployment +extraVolumes: [ ] +# Example: +# extraVolumes: +# - name: ssl-certificates +# secret: +# secretName: ssl-cert-secret +# - name: config-volume +# configMap: +# name: operator-config +# - name: cache-volume +# emptyDir: {} + +# -- Additional volume mounts to be mounted to the operator deployment +extraVolumeMounts: [ ] +# Example: +# extraVolumeMounts: +# - name: ssl-certificates +# mountPath: /etc/ssl/certs +# readOnly: true +# - name: config-volume +# mountPath: /etc/config +# - name: cache-volume +# mountPath: /cache + serviceAccount: # -- Name of the serviceAccount the operator uses to talk to the k8s api name: securecodebox-operator @@ -59,6 +85,23 @@ securityContext: # -- Sets the securityContext on the operators pod level. See: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container podSecurityContext: {} +# -- Health and liveness probe configuration for the controller manager +probes: + # -- Liveness probe configuration + liveness: + httpGet: + path: /healthz + port: healthchecks + initialDelaySeconds: 15 + periodSeconds: 20 + # -- Readiness probe configuration + readiness: + httpGet: + path: /readyz + port: healthchecks + initialDelaySeconds: 5 + periodSeconds: 10 + nodeSelector: {} # -- Configuration for the metrics the operator exports @@ -77,20 +120,68 @@ lurker: # -- Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images pullPolicy: IfNotPresent -# -- Minio default config. More config options an info: https://github.com/minio/minio/blob/master/helm/minio/values.yaml +# -- Minio configuration for direct deployment minio: # -- Enable this to use minio as storage backend instead of a cloud bucket provider like AWS S3, Google Cloud Storage, DigitalOcean Spaces etc. enabled: true - tls: - enabled: false + + # -- Minio image configuration + image: + repository: docker.io/minio/minio + # renovate: image=docker.io/minio/minio + tag: "RELEASE.2025-07-23T15-54-02Z" + pullPolicy: IfNotPresent + + # -- Default buckets to create on startup defaultBuckets: "securecodebox" - # Overwrite Minio's default 4Gi memory request + + # -- Authentication configuration + auth: + # -- Root user for minio + rootUser: "admin" + # -- Root password for minio (leave empty to generate a secure random password) + rootPassword: "" + # -- Name of existing secret containing minio credentials (if set, auth.rootUser and auth.rootPassword are ignored) + existingSecret: "" + + # -- Resource limits and requests for minio resources: requests: memory: "256Mi" - auth: - rootUser: "admin" # placeholder user - rootPassword: "password" # placeholder password + cpu: "100m" + limits: + memory: "512Mi" + cpu: "500m" + ephemeral-storage: "1Gi" + + # -- Persistence configuration + persistence: + # -- Storage class for minio data persistence + storageClass: "" + # -- Size of the persistent volume + size: "10Gi" + + # -- Pod security context for minio + podSecurityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + + # -- Container security context for minio + securityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + + # -- TLS configuration (currently not implemented) + tls: + enabled: false # Config for external s3 systems s3: @@ -102,7 +193,7 @@ s3: bucket: "my-bucket" # Implicit 443. You probably only need to change this when the system uses a non default port port: null - # s3.authType -- Authentication method. Supports access-secret-key (used by most s3 endpoint) and aws-irsa (Used by AWS EKS IAM Role to Kubenetes Service Account Binding. Support for AWS IRSA is considered experimental in the secureCodeBox) + # s3.authType -- Authentication method. Supports `access-secret-key` (used by most s3 endpoints) and `aws-iam`` (Used by AWS EKS IAM Role to Kubernetes Service Account Binding (IRSA) and EKS Pod Identity Authentication. Support for AWS IRSA is considered experimental in the secureCodeBox) authType: access-secret-key # Name to a k8s secret in the same namespace as this release with credentials to the s3 bucket. Only used when s3.authType is set to "access-secret-key" # By default this assumes to have 'accesskey' and 'secretkey' as attributes @@ -113,7 +204,7 @@ s3: secretAttributeNames: accesskey: accesskey secretkey: secretkey - # s3.awsStsEndpoint -- STS Endpoint used in AWS IRSA Authentication. Change this to the sts endpoint of your aws region. Only used when s3.authType is set to "aws-irsa" + # s3.awsStsEndpoint -- STS Endpoint used in AWS IRSA Authentication. Change this to the sts endpoint of your aws region. Only used when s3.authType is set to "aws-iam". Usually not required, even in IRSA or Pod Identity setups as the region gets injected by AWS into the pod. awsStsEndpoint: "https://sts.amazonaws.com" # -- Go Template that generates the path used to store raw result file and findings.json file in the s3 bucket. Can be used to store the files in a subfolder of the s3 bucket diff --git a/parser-sdk/nodejs/.dockerignore b/parser-sdk/nodejs/.dockerignore index 2d2da7ae86..dbb6e76bfb 100644 --- a/parser-sdk/nodejs/.dockerignore +++ b/parser-sdk/nodejs/.dockerignore @@ -3,3 +3,4 @@ # SPDX-License-Identifier: Apache-2.0 node_modules/ +build/ diff --git a/parser-sdk/nodejs/Dockerfile b/parser-sdk/nodejs/Dockerfile index 19e5b1ec55..5f71a0ce7b 100644 --- a/parser-sdk/nodejs/Dockerfile +++ b/parser-sdk/nodejs/Dockerfile @@ -2,19 +2,19 @@ # # SPDX-License-Identifier: Apache-2.0 -FROM oven/bun:1.2 AS build +FROM oven/bun:1.3 AS build WORKDIR /home/app/ COPY package.json package-lock.json ./ -RUN bun install -COPY *.js ./ +RUN bun install --ignore-scripts +COPY *.ts findings-schema.json ./ RUN bun run build -FROM node:22-alpine +FROM node:24-alpine ARG NODE_ENV RUN addgroup --system --gid 1001 app && adduser app --system --uid 1001 --ingroup app WORKDIR /home/app/parser-wrapper/ +COPY --chown=root:root --chmod=755 ./package.json ./package-lock.json ./ COPY --from=build --chown=root:root --chmod=755 /home/app/build/ ./ -COPY --chown=root:root --chmod=755 ./findings-schema.json ./findings-schema.json USER 1001 ENV NODE_ENV=${NODE_ENV:-production} ENTRYPOINT ["node", "--enable-source-maps", "/home/app/parser-wrapper/parser-wrapper.js"] diff --git a/parser-sdk/nodejs/package-lock.json b/parser-sdk/nodejs/package-lock.json index b051d18711..d4784d5d02 100644 --- a/parser-sdk/nodejs/package-lock.json +++ b/parser-sdk/nodejs/package-lock.json @@ -9,13 +9,15 @@ "version": "1.0.0", "license": "Apache-2.0", "dependencies": { - "@kubernetes/client-node": "^1.3.0", + "@kubernetes/client-node": "^1.4.0", "ajv": "^8.17.1", "ajv-draft-04": "^1.0.0", "ajv-formats": "^3.0.1", "jsonpointer": "^5.0.1" }, - "devDependencies": {} + "devDependencies": { + "@types/node": "^25.0.10" + } }, "node_modules/@jsep-plugin/assignment": { "version": "1.3.0", @@ -42,29 +44,36 @@ } }, "node_modules/@kubernetes/client-node": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-1.3.0.tgz", - "integrity": "sha512-IE0yrIpOT97YS5fg2QpzmPzm8Wmcdf4ueWMn+FiJSI3jgTTQT1u+LUhoYpdfhdHAVxdrNsaBg2C0UXSnOgMoCQ==", - "license": "Apache-2.0", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-1.4.0.tgz", + "integrity": "sha512-Zge3YvF7DJi264dU1b3wb/GmzR99JhUpqTvp+VGHfwZT+g7EOOYNScDJNZwXy9cszyIGPIs0VHr+kk8e95qqrA==", "dependencies": { "@types/js-yaml": "^4.0.1", - "@types/node": "^22.0.0", - "@types/node-fetch": "^2.6.9", + "@types/node": "^24.0.0", + "@types/node-fetch": "^2.6.13", "@types/stream-buffers": "^3.0.3", "form-data": "^4.0.0", "hpagent": "^1.2.0", "isomorphic-ws": "^5.0.0", "js-yaml": "^4.1.0", "jsonpath-plus": "^10.3.0", - "node-fetch": "^2.6.9", + "node-fetch": "^2.7.0", "openid-client": "^6.1.3", "rfc4648": "^1.3.0", "socks-proxy-agent": "^8.0.4", "stream-buffers": "^3.0.2", - "tar-fs": "^3.0.8", + "tar-fs": "^3.0.9", "ws": "^8.18.2" } }, + "node_modules/@kubernetes/client-node/node_modules/@types/node": { + "version": "24.10.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.4.tgz", + "integrity": "sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg==", + "dependencies": { + "undici-types": "~7.16.0" + } + }, "node_modules/@types/js-yaml": { "version": "4.0.9", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", @@ -72,22 +81,20 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.10.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", - "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", - "license": "MIT", + "version": "25.0.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.10.tgz", + "integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==", "dependencies": { - "undici-types": "~6.20.0" + "undici-types": "~7.16.0" } }, "node_modules/@types/node-fetch": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", - "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", - "license": "MIT", + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", "dependencies": { "@types/node": "*", - "form-data": "^4.0.0" + "form-data": "^4.0.4" } }, "node_modules/@types/stream-buffers": { @@ -160,7 +167,7 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/b4a": { "version": "1.6.7", @@ -240,6 +247,18 @@ } } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -271,11 +290,24 @@ "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { "node": ">=0.4.0" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -285,6 +317,47 @@ "once": "^1.4.0" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -302,19 +375,110 @@ "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==" }, "node_modules/form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", - "license": "MIT", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { "node": ">= 6" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/hpagent": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz", @@ -354,9 +518,9 @@ } }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dependencies": { "argparse": "^2.0.1" }, @@ -410,20 +574,28 @@ "node": ">=0.10.0" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/mime-db": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", - "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.32", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", - "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { - "mime-db": "1.49.0" + "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" @@ -573,9 +745,9 @@ } }, "node_modules/tar-fs": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.9.tgz", - "integrity": "sha512-XF4w9Xp+ZQgifKakjZYmFdkLoSWd34VGKcsTCwlNWM7QG3ZbaxnTsaBwnjFZqHRf/rROxaR8rXnbtwdvaDI+lA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "license": "MIT", "dependencies": { "pump": "^3.0.0", @@ -613,10 +785,9 @@ "license": "MIT" }, "node_modules/undici-types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", - "license": "MIT" + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==" }, "node_modules/webidl-conversions": { "version": "3.0.1", @@ -676,26 +847,36 @@ "requires": {} }, "@kubernetes/client-node": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-1.3.0.tgz", - "integrity": "sha512-IE0yrIpOT97YS5fg2QpzmPzm8Wmcdf4ueWMn+FiJSI3jgTTQT1u+LUhoYpdfhdHAVxdrNsaBg2C0UXSnOgMoCQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-1.4.0.tgz", + "integrity": "sha512-Zge3YvF7DJi264dU1b3wb/GmzR99JhUpqTvp+VGHfwZT+g7EOOYNScDJNZwXy9cszyIGPIs0VHr+kk8e95qqrA==", "requires": { "@types/js-yaml": "^4.0.1", - "@types/node": "^22.0.0", - "@types/node-fetch": "^2.6.9", + "@types/node": "^24.0.0", + "@types/node-fetch": "^2.6.13", "@types/stream-buffers": "^3.0.3", "form-data": "^4.0.0", "hpagent": "^1.2.0", "isomorphic-ws": "^5.0.0", "js-yaml": "^4.1.0", "jsonpath-plus": "^10.3.0", - "node-fetch": "^2.6.9", + "node-fetch": "^2.7.0", "openid-client": "^6.1.3", "rfc4648": "^1.3.0", "socks-proxy-agent": "^8.0.4", "stream-buffers": "^3.0.2", - "tar-fs": "^3.0.8", + "tar-fs": "^3.0.9", "ws": "^8.18.2" + }, + "dependencies": { + "@types/node": { + "version": "24.10.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.4.tgz", + "integrity": "sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg==", + "requires": { + "undici-types": "~7.16.0" + } + } } }, "@types/js-yaml": { @@ -704,20 +885,20 @@ "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==" }, "@types/node": { - "version": "22.10.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", - "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", + "version": "25.0.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.10.tgz", + "integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==", "requires": { - "undici-types": "~6.20.0" + "undici-types": "~7.16.0" } }, "@types/node-fetch": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", - "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", "requires": { "@types/node": "*", - "form-data": "^4.0.0" + "form-data": "^4.0.4" } }, "@types/stream-buffers": { @@ -766,7 +947,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "b4a": { "version": "1.6.7", @@ -814,6 +995,15 @@ "streamx": "^2.21.0" } }, + "call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + } + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -833,7 +1023,17 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "requires": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + } }, "end-of-stream": { "version": "1.4.4", @@ -843,6 +1043,35 @@ "once": "^1.4.0" } }, + "es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, + "es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "requires": { + "es-errors": "^1.3.0" + } + }, + "es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "requires": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + } + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -859,15 +1088,74 @@ "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==" }, "form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "requires": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + } + }, + "get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "requires": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + } + }, + "gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" + }, + "has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "requires": { + "has-symbols": "^1.0.3" + } + }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "requires": { + "function-bind": "^1.1.2" + } + }, "hpagent": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz", @@ -894,9 +1182,9 @@ "integrity": "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==" }, "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "requires": { "argparse": "^2.0.1" } @@ -931,17 +1219,22 @@ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==" }, + "math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" + }, "mime-db": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", - "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==" + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { - "version": "2.1.32", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", - "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "requires": { - "mime-db": "1.49.0" + "mime-db": "1.52.0" } }, "ms": { @@ -1043,9 +1336,9 @@ } }, "tar-fs": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.9.tgz", - "integrity": "sha512-XF4w9Xp+ZQgifKakjZYmFdkLoSWd34VGKcsTCwlNWM7QG3ZbaxnTsaBwnjFZqHRf/rROxaR8rXnbtwdvaDI+lA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "requires": { "bare-fs": "^4.0.1", "bare-path": "^3.0.0", @@ -1077,9 +1370,9 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "undici-types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==" }, "webidl-conversions": { "version": "3.0.1", diff --git a/parser-sdk/nodejs/package.json b/parser-sdk/nodejs/package.json index 78ea9a283c..61f8d5b991 100644 --- a/parser-sdk/nodejs/package.json +++ b/parser-sdk/nodejs/package.json @@ -11,11 +11,13 @@ "build": "bun build --production --target=node --outdir=build/ --external=./parser/parser.js --sourcemap=external --minify ./parser-wrapper.js" }, "dependencies": { - "@kubernetes/client-node": "^1.3.0", + "@kubernetes/client-node": "^1.4.0", "ajv": "^8.17.1", "ajv-draft-04": "^1.0.0", "ajv-formats": "^3.0.1", "jsonpointer": "^5.0.1" }, - "devDependencies": {} + "devDependencies": { + "@types/node": "^25.0.10" + } } diff --git a/parser-sdk/nodejs/parser-utils.js b/parser-sdk/nodejs/parser-utils.js deleted file mode 100644 index 5f072896b9..0000000000 --- a/parser-sdk/nodejs/parser-utils.js +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-FileCopyrightText: the secureCodeBox authors -// -// SPDX-License-Identifier: Apache-2.0 - -import { readFile } from "node:fs/promises"; -import { randomUUID } from "node:crypto"; - -import addFormats from "ajv-formats"; -import { get } from "jsonpointer"; -import Ajv from "ajv-draft-04"; - -const ajv = new Ajv(); -addFormats(ajv); - -export async function validate(findings) { - const jsonSchemaString = await readFile( - import.meta.dirname + "/findings-schema.json", - "utf8", - ); - const jsonSchema = JSON.parse(jsonSchemaString); - const validator = ajv.compile(jsonSchema); - const valid = validator(findings); - if (!valid) { - const errorMessage = generateErrorMessage(validator.errors, findings); - throw new Error(errorMessage); - } -} - -export function addScanMetadata(findings, scan) { - const scanMetadata = { - created_at: scan.metadata.creationTimestamp, - name: scan.metadata.name, - namespace: scan.metadata.namespace, - scan_type: scan.spec.scanType, - }; - - return findings.map((finding) => ({ - ...finding, - scan: scanMetadata, - })); -} - -export function addIdsAndDates(findings) { - return findings.map((finding) => { - return { - ...finding, - id: randomUUID(), - parsed_at: new Date().toISOString(), - }; - }); -} - -// used for tests to validate if the parser sets all required fields correctly. Adds sample IDs and Dates to the findings which would normally be set by the parser-sdk. -export async function validateParser(findings) { - const sampleScan = { - metadata: { - creationTimestamp: new Date().toISOString(), - name: "sample-scan-name", - namespace: "sample-namespace", - }, - spec: { - scanType: "sample-scan-type", - }, - }; - // add sample IDs and Dates only if the findings Array is not empty - const extendedData = addScanMetadata(addIdsAndDates(findings), sampleScan); - return validate(extendedData); -} - -function generateErrorMessage(errors, findings) { - return JSON.stringify( - errors.map((error) => { - return { - ...error, - invalidValue: get(findings, error.instancePath), - }; - }), - null, - 2, - ); -} diff --git a/parser-sdk/nodejs/parser-utils.ts b/parser-sdk/nodejs/parser-utils.ts new file mode 100644 index 0000000000..d01b13075d --- /dev/null +++ b/parser-sdk/nodejs/parser-utils.ts @@ -0,0 +1,136 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +import { randomUUID } from "node:crypto"; + +import addFormats from "ajv-formats"; +import { get } from "jsonpointer"; +import Ajv, { type ErrorObject } from "ajv-draft-04"; +import findingsSchema from "./findings-schema.json" with { type: "json" }; + +const ajv = new Ajv(); +addFormats(ajv); + +export type Severity = "INFORMATIONAL" | "LOW" | "MEDIUM" | "HIGH"; + +export interface Reference { + type: string; + value: string; +} + +export interface ScanSummary { + created_at: string; // ISO8601 date-time + name: string; + namespace: string; + scan_type: string; +} + +// parsers do not need to set all fields as fields like the ID are set by the parser-sdk +export interface FindingFromParser { + identified_at?: string | null; // ISO8601 date-time + name: string; + description?: string | null; + category: string; + severity: Severity; + mitigation?: string | null; + references?: Reference[] | null; + attributes?: Record; + location?: string | null; +} + +export interface FindingWithIdsAndDates extends FindingFromParser { + id: string; // UUID v4 + parsed_at: string; // ISO8601 date-time +} + +export interface Finding extends FindingWithIdsAndDates { + scan: ScanSummary; +} + +export interface Scan { + metadata: { + name: string; + namespace: string; + creationTimestamp: string; + }; + spec: { + scanType: string; + }; + status: { + rawResultType: string; + }; +} + +export function validate(findings: unknown): asserts findings is Finding[] { + const validator = ajv.compile(findingsSchema); + const valid = validator(findings); + if (!valid && validator.errors) { + const errorMessage = generateErrorMessage(validator.errors, findings); + throw new Error(errorMessage); + } else if (!valid) { + throw new Error("Validation of findings failed for unknown reasons."); + } +} + +export function addScanMetadata( + findings: FindingWithIdsAndDates[], + scan: Scan, +): Finding[] { + const scanMetadata = { + created_at: scan.metadata.creationTimestamp, + name: scan.metadata.name, + namespace: scan.metadata.namespace, + scan_type: scan.spec.scanType, + }; + + return findings.map((finding) => ({ + ...finding, + scan: scanMetadata, + })); +} + +export function addIdsAndDates( + findings: FindingFromParser[], +): FindingWithIdsAndDates[] { + return findings.map((finding) => { + return { + ...finding, + id: randomUUID(), + parsed_at: new Date().toISOString(), + }; + }); +} + +// used for tests to validate if the parser sets all required fields correctly. Adds sample IDs and Dates to the findings which would normally be set by the parser-sdk. +export function validateParser(findings: FindingFromParser[]) { + const sampleScan: Scan = { + metadata: { + creationTimestamp: new Date().toISOString(), + name: "sample-scan-name", + namespace: "sample-namespace", + }, + spec: { + scanType: "sample-scan-type", + }, + status: { + rawResultType: "example-results", + }, + }; + // add sample IDs and Dates only if the findings Array is not empty + const extendedData = addScanMetadata(addIdsAndDates(findings), sampleScan); + return validate(extendedData); +} + +function generateErrorMessage(errors: ErrorObject[], findings: Finding[]) { + return JSON.stringify( + errors.map((error) => { + return { + ...error, + invalidValue: get(findings, error.instancePath), + }; + }), + null, + 2, + ); +} diff --git a/parser-sdk/nodejs/parser-wrapper.js b/parser-sdk/nodejs/parser-wrapper.ts similarity index 81% rename from parser-sdk/nodejs/parser-wrapper.js rename to parser-sdk/nodejs/parser-wrapper.ts index 4534185bc7..e46c2c59f2 100644 --- a/parser-sdk/nodejs/parser-wrapper.js +++ b/parser-sdk/nodejs/parser-wrapper.ts @@ -10,17 +10,43 @@ import { PatchStrategy, } from "@kubernetes/client-node"; +// @ts-ignore: parsers are provided during the docker build of the acutal parsers. import { parse } from "./parser/parser.js"; -import { validate, addIdsAndDates, addScanMetadata } from "./parser-utils.js"; +import { + validate, + addIdsAndDates, + addScanMetadata, + type Finding, + type Severity, + type Scan, +} from "./parser-utils.js"; const kc = new KubeConfig(); kc.loadFromCluster(); const k8sApi = kc.makeApiClient(CustomObjectsApi); -const scanName = process.env["SCAN_NAME"]; -const namespace = process.env["NAMESPACE"]; +const scanName = process.env["SCAN_NAME"]!; +if (!scanName) { + console.error( + "Parser was started without `SCAN_NAME` environment variable set. This is normally done by the operator.", + ); + console.error( + "If you are seeing this error during a normal scan execution please open up an issue..", + ); + process.exit(1); +} +const namespace = process.env["NAMESPACE"]!; +if (!namespace) { + console.error( + "Parser was started without `NAMESPACE` environment variable set. This is normally done by the operator.", + ); + console.error( + "If you are seeing this error during a normal scan execution please open up an issue..", + ); + process.exit(1); +} -function severityCount(findings, severity) { +function severityCount(findings: Finding[], severity: Severity) { return findings.filter( ({ severity: findingSeverity }) => findingSeverity.toUpperCase() === severity, @@ -28,8 +54,8 @@ function severityCount(findings, severity) { } async function uploadResultToFileStorageService( - resultUploadUrl, - findingsWithIdsAndDates, + resultUploadUrl: string, + findingsWithIdsAndDates: Finding[], ) { try { const res = await fetch(resultUploadUrl, { @@ -61,7 +87,7 @@ async function uploadResultToFileStorageService( } } -async function updateScanStatus(findings) { +async function updateScanStatus(findings: Finding[]) { try { const findingCategories = new Map(); for (const { category } of findings) { @@ -104,7 +130,7 @@ async function updateScanStatus(findings) { } } -async function extractScan() { +async function extractScan(): Promise { try { return await k8sApi.getNamespacedCustomObject({ group: "execution.securecodebox.io", @@ -120,7 +146,7 @@ async function extractScan() { } } -async function extractParseDefinition(scan) { +async function extractParseDefinition(scan: Scan) { try { return await k8sApi.getNamespacedCustomObject({ group: "execution.securecodebox.io", @@ -136,7 +162,7 @@ async function extractParseDefinition(scan) { } } -async function fetchResultFile(resultFileUrl, contentType) { +async function fetchResultFile(resultFileUrl: string, contentType?: "Binary") { try { const response = await fetch(resultFileUrl, { method: "GET" }); if (!response.ok) { @@ -164,7 +190,7 @@ async function main() { const resultUploadUrl = process.argv[3]; console.log("Fetching result file"); - let data = null; + let data: string | Buffer | null = null; try { data = await fetchResultFile( resultFileUrl, @@ -201,7 +227,7 @@ async function main() { crash_on_failed_validation, ); try { - await validate(findingsWithMetadata); + validate(findingsWithMetadata); console.log("The Findings were successfully validated"); } catch (error) { console.error("The Findings Validation failed with error(s):"); diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000000..38ce5f46f8 --- /dev/null +++ b/renovate.json @@ -0,0 +1,47 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended", + "group:recommended", + ":disableDependencyDashboard" + ], + "enabledManagers": ["dockerfile", "custom.regex"], + + "labels": ["dependencies"], + + "ignorePaths": [ + "demo-targets/http-webhook/**", + "demo-targets/old-typo3/**", + "demo-targets/old-joomla/**", + "demo-targets/old-wordpress/**", + "demo-targets/vulnerable-log4j/**" + ], + + "customManagers": [ + { + "customType": "regex", + "datasourceTemplate": "docker", + "managerFilePatterns": ["/demo-targets/.*/Chart\\.yaml$/"], + "matchStrings": [ + "#\\s?renovate: image=(?.*?)\\s?appVersion:\\s?(?[\\w+\\.\\-]*)" + ] + }, + { + "customType": "regex", + "datasourceTemplate": "docker", + "managerFilePatterns": ["/operator/values\\.yaml$/"], + "matchStrings": [ + "#\\s?renovate: image=(?.*?)\\s?tag:\\s?[\"']?(?.*?)[\"']?" + ] + }, + { + "customType": "regex", + "description": "Update GitHub releases dependencies in CI workflow", + "fileMatch": ["^\\.github/workflows/.*\\.ya?ml$"], + "matchStrings": [ + "# renovate: datasource=github-releases depName=(?.*?)\\s*\\w+_VERSION:\\s*[\"']?(?[^\"'\\s]+)[\"']?" + ], + "datasourceTemplate": "github-releases" + } + ] +} diff --git a/operator/charts/minio-15.0.2.tgz.license b/renovate.json.license similarity index 100% rename from operator/charts/minio-15.0.2.tgz.license rename to renovate.json.license diff --git a/scanners/amass/.helm-docs.gotmpl b/scanners/amass/.helm-docs.gotmpl deleted file mode 100644 index 8ee5d9e737..0000000000 --- a/scanners/amass/.helm-docs.gotmpl +++ /dev/null @@ -1,65 +0,0 @@ -{{- /* -SPDX-FileCopyrightText: the secureCodeBox authors - -SPDX-License-Identifier: Apache-2.0 -*/ -}} - -{{- define "extra.docsSection" -}} ---- -title: "Amass" -category: "scanner" -type: "Network" -state: "released" -appVersion: "{{ template "chart.appVersion" . }}" -usecase: "Subdomain Enumeration Scanner" ---- - -![owasp logo](https://owasp.org/assets/images/logo.png) - -{{- end }} - -{{- define "extra.dockerDeploymentSection" -}} - -## Notice -This image is a workaround for the official Amass docker image, older amass versions are regularly removed from the official docker registry, this is often breaks our builds. -To prevent this we create a new image based on the official one and push it to our docker registry. -Copyright 2017 Jeff Foley. All rights reserved. - -## Supported Tags -- `latest` (represents the latest stable release build) -- tagged releases, e.g. `3.0.0`, `2.9.0`, `2.8.0`, `2.7.0` -{{- end }} - -{{- define "extra.chartAboutSection" -}} -## What is OWASP Amass? - -:::caution -Amass currently has a [known issue](https://github.com/owasp-amass/amass/issues/918) where the enumeration sometimes does not exit correctly and keeps running indefinitely. This is why we recommend using the option `-timeout MINUTES` mitigate the issue. The scan will then exit after the specified amount of minutes, and the findings should be correctly parsed. -::: - - -The [OWASP Amass Project][owasp_amass_project] has developed a tool to help information security professionals perform network mapping of attack surfaces and perform external asset discovery using open source information gathering and active reconnaissance techniques. To learn more about the Amass scanner itself visit [OWASP Amass Project][owasp_amass_project] or [Amass GitHub]. -{{- end }} - -{{- define "extra.scannerConfigurationSection" -}} -## Scanner Configuration - -The following security scan configuration example are based on the [Amass User Guide](https://github.com/owasp-amass/amass/blob/master/doc/user_guide.md#the-enum-subcommand), please take a look at the original documentation for more configuration examples. - -- The most basic use of the tool for subdomain enumeration: `amass enum -d example.com` -- Typical parameters for DNS enumeration: `amass enum -v -brute -min-for-recursive 2 -d example.com` - -Special command line options: - -- Enable generation of altered names `amass enum -alts -d example.com` -- Turn off recursive brute forcing `amass enum -brute -norecursive -d example.com` -- Domain names separated by commas (can be used multiple times) `amass enum -d example.com` -{{- end }} - -{{- define "extra.chartConfigurationSection" -}}{{- end }} - -{{- define "extra.scannerLinksSection" -}} -[owasp_amass_project]: https://owasp.org/www-project-amass/ -[amass github]: https://github.com/OWASP/Amass -[amass user guide]: https://github.com/OWASP/Amass/blob/master/doc/user_guide.md -{{- end }} diff --git a/scanners/amass/Chart.yaml b/scanners/amass/Chart.yaml deleted file mode 100644 index 41b79759a6..0000000000 --- a/scanners/amass/Chart.yaml +++ /dev/null @@ -1,28 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -apiVersion: v2 -name: amass -description: A Helm chart for the Amass security scanner that integrates with the secureCodeBox. -type: application -# version - gets automatically set to the secureCodeBox release version when the helm charts gets published -version: v3.1.0-alpha1 -appVersion: "v4.2.0" -kubeVersion: ">=v1.11.0-0" -annotations: - versionApi: https://api.github.com/repos/OWASP/Amass/releases/latest - supported-platforms: linux/amd64,linux/arm64 -keywords: - - security - - amass - - subdomain - - scanner - - secureCodeBox -home: https://www.securecodebox.io/docs/scanners/Amass -icon: https://www.securecodebox.io/img/integrationIcons/Amass.svg -sources: - - https://github.com/secureCodeBox/secureCodeBox -maintainers: - - name: iteratec GmbH - email: secureCodeBox@iteratec.com diff --git a/scanners/amass/README.md b/scanners/amass/README.md deleted file mode 100644 index 1a84f1f480..0000000000 --- a/scanners/amass/README.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: "Amass" -category: "scanner" -type: "Network" -state: "released" -appVersion: "v4.2.0" -usecase: "Subdomain Enumeration Scanner" ---- - -![owasp logo](https://owasp.org/assets/images/logo.png) - - - - -

- License Apache-2.0 - GitHub release (latest SemVer) - OWASP Lab Project - Artifact HUB - GitHub Repo stars - Mastodon Follower -

- -## What is OWASP Amass? - -:::caution -Amass currently has a [known issue](https://github.com/owasp-amass/amass/issues/918) where the enumeration sometimes does not exit correctly and keeps running indefinitely. This is why we recommend using the option `-timeout MINUTES` mitigate the issue. The scan will then exit after the specified amount of minutes, and the findings should be correctly parsed. -::: - -The [OWASP Amass Project][owasp_amass_project] has developed a tool to help information security professionals perform network mapping of attack surfaces and perform external asset discovery using open source information gathering and active reconnaissance techniques. To learn more about the Amass scanner itself visit [OWASP Amass Project][owasp_amass_project] or [Amass GitHub]. - -## Deployment -The amass chart can be deployed via helm: - -```bash -# Install HelmChart (use -n to configure another namespace) -helm upgrade --install amass oci://ghcr.io/securecodebox/helm/amass -``` - -## Scanner Configuration - -The following security scan configuration example are based on the [Amass User Guide](https://github.com/owasp-amass/amass/blob/master/doc/user_guide.md#the-enum-subcommand), please take a look at the original documentation for more configuration examples. - -- The most basic use of the tool for subdomain enumeration: `amass enum -d example.com` -- Typical parameters for DNS enumeration: `amass enum -v -brute -min-for-recursive 2 -d example.com` - -Special command line options: - -- Enable generation of altered names `amass enum -alts -d example.com` -- Turn off recursive brute forcing `amass enum -brute -norecursive -d example.com` -- Domain names separated by commas (can be used multiple times) `amass enum -d example.com` - -## Requirements - -Kubernetes: `>=v1.11.0-0` - -## Values - -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| cascadingRules.enabled | bool | `false` | Enables or disables the installation of the default cascading rules for this scanner | -| imagePullSecrets | list | `[]` | Define imagePullSecrets when a private registry is used (see: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) | -| parser.affinity | object | `{}` | Optional affinity settings that control how the parser job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) | -| parser.env | list | `[]` | Optional environment variables mapped into each parseJob (see: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) | -| parser.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images | -| parser.image.repository | string | `"docker.io/securecodebox/parser-amass"` | Parser image repository | -| parser.image.tag | string | defaults to the charts version | Parser image tag | -| parser.nodeSelector | object | `{}` | Optional nodeSelector settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/) | -| parser.resources | object | `{ requests: { cpu: "200m", memory: "100Mi" }, limits: { cpu: "400m", memory: "200Mi" } }` | Optional resources lets you control resource limits and requests for the parser container. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | -| parser.scopeLimiterAliases | object | `{}` | Optional finding aliases to be used in the scopeLimiter. | -| parser.tolerations | list | `[]` | Optional tolerations settings that control how the parser job is scheduled (see: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) | -| parser.ttlSecondsAfterFinished | string | `nil` | seconds after which the Kubernetes job for the parser will be deleted. Requires the Kubernetes TTLAfterFinished controller: https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ | -| scanner.activeDeadlineSeconds | string | `nil` | There are situations where you want to fail a scan Job after some amount of time. To do so, set activeDeadlineSeconds to define an active deadline (in seconds) when considering a scan Job as failed. (see: https://kubernetes.io/docs/concepts/workloads/controllers/job/#job-termination-and-cleanup) | -| scanner.affinity | object | `{}` | Optional affinity settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) | -| scanner.backoffLimit | int | 3 | There are situations where you want to fail a scan Job after some amount of retries due to a logical error in configuration etc. To do so, set backoffLimit to specify the number of retries before considering a scan Job as failed. (see: https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-backoff-failure-policy) | -| scanner.env | list | `[]` | Optional environment variables mapped into each scanJob (see: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) | -| scanner.extraContainers | list | `[]` | Optional additional Containers started with each scanJob (see: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/) | -| scanner.extraVolumeMounts | list | `[{"mountPath":"/amass/output/config.ini","name":"amass-config","subPath":"config.ini"}]` | Optional VolumeMounts mapped into each scanJob (see: https://kubernetes.io/docs/concepts/storage/volumes/) | -| scanner.extraVolumes | list | `[{"configMap":{"name":"amass-config"},"name":"amass-config"}]` | Optional Volumes mapped into each scanJob (see: https://kubernetes.io/docs/concepts/storage/volumes/) | -| scanner.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images | -| scanner.image.repository | string | `"docker.io/securecodebox/scanner-amass"` | Container Image to run the scan | -| scanner.image.tag | string | `nil` | defaults to the charts appVersion | -| scanner.nameAppend | string | `nil` | append a string to the default scantype name. | -| scanner.nodeSelector | object | `{}` | Optional nodeSelector settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/) | -| scanner.podSecurityContext | object | `{}` | Optional securityContext set on scanner pod (see: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) | -| scanner.resources | object | `{}` | CPU/memory resource requests/limits (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/, https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/) | -| scanner.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["all"]},"privileged":false,"readOnlyRootFilesystem":false,"runAsNonRoot":true}` | Optional securityContext set on scanner container (see: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) | -| scanner.securityContext.allowPrivilegeEscalation | bool | `false` | Ensure that users privileges cannot be escalated | -| scanner.securityContext.capabilities.drop[0] | string | `"all"` | This drops all linux privileges from the container. | -| scanner.securityContext.privileged | bool | `false` | Ensures that the scanner container is not run in privileged mode | -| scanner.securityContext.readOnlyRootFilesystem | bool | `false` | Prevents write access to the containers file system | -| scanner.securityContext.runAsNonRoot | bool | `true` | Enforces that the scanner image is run as a non root user | -| scanner.suspend | bool | `false` | if set to true the scan job will be suspended after creation. You can then resume the job using `kubectl resume ` or using a job scheduler like kueue | -| scanner.tolerations | list | `[]` | Optional tolerations settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) | -| scanner.ttlSecondsAfterFinished | string | `nil` | seconds after which the Kubernetes job for the scanner will be deleted. Requires the Kubernetes TTLAfterFinished controller: https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ | - -## License -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) - -Code of secureCodeBox is licensed under the [Apache License 2.0][scb-license]. - -[scb-owasp]: https://www.owasp.org/index.php/OWASP_secureCodeBox -[scb-docs]: https://www.securecodebox.io/ -[scb-site]: https://www.securecodebox.io/ -[scb-github]: https://github.com/secureCodeBox/ -[scb-mastodon]: https://infosec.exchange/@secureCodeBox -[scb-slack]: https://owasp.org/slack/invite -[scb-license]: https://github.com/secureCodeBox/secureCodeBox/blob/master/LICENSE -[owasp_amass_project]: https://owasp.org/www-project-amass/ -[amass github]: https://github.com/OWASP/Amass -[amass user guide]: https://github.com/OWASP/Amass/blob/master/doc/user_guide.md diff --git a/scanners/amass/docs/README.ArtifactHub.md b/scanners/amass/docs/README.ArtifactHub.md deleted file mode 100644 index 2bfdd94baa..0000000000 --- a/scanners/amass/docs/README.ArtifactHub.md +++ /dev/null @@ -1,145 +0,0 @@ - - - -

- License Apache-2.0 - GitHub release (latest SemVer) - OWASP Lab Project - Artifact HUB - GitHub Repo stars - Mastodon Follower -

- -## What is OWASP secureCodeBox? - -

- secureCodeBox Logo -

- -_[OWASP secureCodeBox][scb-github]_ is an automated and scalable open source solution that can be used to integrate various *security vulnerability scanners* with a simple and lightweight interface. The _secureCodeBox_ mission is to support *DevSecOps* Teams to make it easy to automate security vulnerability testing in different scenarios. - -With the _secureCodeBox_ we provide a toolchain for continuous scanning of applications to find the low-hanging fruit issues early in the development process and free the resources of the penetration tester to concentrate on the major security issues. - -The secureCodeBox project is running on [Kubernetes](https://kubernetes.io/). To install it you need [Helm](https://helm.sh), a package manager for Kubernetes. It is also possible to start the different integrated security vulnerability scanners based on a docker infrastructure. - -### Quickstart with secureCodeBox on Kubernetes - -You can find resources to help you get started on our [documentation website](https://www.securecodebox.io) including instruction on how to [install the secureCodeBox project](https://www.securecodebox.io/docs/getting-started/installation) and guides to help you [run your first scans](https://www.securecodebox.io/docs/getting-started/first-scans) with it. - -## What is OWASP Amass? - -:::caution -Amass currently has a [known issue](https://github.com/owasp-amass/amass/issues/918) where the enumeration sometimes does not exit correctly and keeps running indefinitely. This is why we recommend using the option `-timeout MINUTES` mitigate the issue. The scan will then exit after the specified amount of minutes, and the findings should be correctly parsed. -::: - -The [OWASP Amass Project][owasp_amass_project] has developed a tool to help information security professionals perform network mapping of attack surfaces and perform external asset discovery using open source information gathering and active reconnaissance techniques. To learn more about the Amass scanner itself visit [OWASP Amass Project][owasp_amass_project] or [Amass GitHub]. - -## Deployment -The amass chart can be deployed via helm: - -```bash -# Install HelmChart (use -n to configure another namespace) -helm upgrade --install amass oci://ghcr.io/securecodebox/helm/amass -``` - -## Scanner Configuration - -The following security scan configuration example are based on the [Amass User Guide](https://github.com/owasp-amass/amass/blob/master/doc/user_guide.md#the-enum-subcommand), please take a look at the original documentation for more configuration examples. - -- The most basic use of the tool for subdomain enumeration: `amass enum -d example.com` -- Typical parameters for DNS enumeration: `amass enum -v -brute -min-for-recursive 2 -d example.com` - -Special command line options: - -- Enable generation of altered names `amass enum -alts -d example.com` -- Turn off recursive brute forcing `amass enum -brute -norecursive -d example.com` -- Domain names separated by commas (can be used multiple times) `amass enum -d example.com` - -## Requirements - -Kubernetes: `>=v1.11.0-0` - -## Values - -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| cascadingRules.enabled | bool | `false` | Enables or disables the installation of the default cascading rules for this scanner | -| imagePullSecrets | list | `[]` | Define imagePullSecrets when a private registry is used (see: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) | -| parser.affinity | object | `{}` | Optional affinity settings that control how the parser job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) | -| parser.env | list | `[]` | Optional environment variables mapped into each parseJob (see: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) | -| parser.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images | -| parser.image.repository | string | `"docker.io/securecodebox/parser-amass"` | Parser image repository | -| parser.image.tag | string | defaults to the charts version | Parser image tag | -| parser.nodeSelector | object | `{}` | Optional nodeSelector settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/) | -| parser.resources | object | `{ requests: { cpu: "200m", memory: "100Mi" }, limits: { cpu: "400m", memory: "200Mi" } }` | Optional resources lets you control resource limits and requests for the parser container. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | -| parser.scopeLimiterAliases | object | `{}` | Optional finding aliases to be used in the scopeLimiter. | -| parser.tolerations | list | `[]` | Optional tolerations settings that control how the parser job is scheduled (see: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) | -| parser.ttlSecondsAfterFinished | string | `nil` | seconds after which the Kubernetes job for the parser will be deleted. Requires the Kubernetes TTLAfterFinished controller: https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ | -| scanner.activeDeadlineSeconds | string | `nil` | There are situations where you want to fail a scan Job after some amount of time. To do so, set activeDeadlineSeconds to define an active deadline (in seconds) when considering a scan Job as failed. (see: https://kubernetes.io/docs/concepts/workloads/controllers/job/#job-termination-and-cleanup) | -| scanner.affinity | object | `{}` | Optional affinity settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) | -| scanner.backoffLimit | int | 3 | There are situations where you want to fail a scan Job after some amount of retries due to a logical error in configuration etc. To do so, set backoffLimit to specify the number of retries before considering a scan Job as failed. (see: https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-backoff-failure-policy) | -| scanner.env | list | `[]` | Optional environment variables mapped into each scanJob (see: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) | -| scanner.extraContainers | list | `[]` | Optional additional Containers started with each scanJob (see: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/) | -| scanner.extraVolumeMounts | list | `[{"mountPath":"/amass/output/config.ini","name":"amass-config","subPath":"config.ini"}]` | Optional VolumeMounts mapped into each scanJob (see: https://kubernetes.io/docs/concepts/storage/volumes/) | -| scanner.extraVolumes | list | `[{"configMap":{"name":"amass-config"},"name":"amass-config"}]` | Optional Volumes mapped into each scanJob (see: https://kubernetes.io/docs/concepts/storage/volumes/) | -| scanner.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images | -| scanner.image.repository | string | `"docker.io/securecodebox/scanner-amass"` | Container Image to run the scan | -| scanner.image.tag | string | `nil` | defaults to the charts appVersion | -| scanner.nameAppend | string | `nil` | append a string to the default scantype name. | -| scanner.nodeSelector | object | `{}` | Optional nodeSelector settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/) | -| scanner.podSecurityContext | object | `{}` | Optional securityContext set on scanner pod (see: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) | -| scanner.resources | object | `{}` | CPU/memory resource requests/limits (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/, https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/) | -| scanner.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["all"]},"privileged":false,"readOnlyRootFilesystem":false,"runAsNonRoot":true}` | Optional securityContext set on scanner container (see: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) | -| scanner.securityContext.allowPrivilegeEscalation | bool | `false` | Ensure that users privileges cannot be escalated | -| scanner.securityContext.capabilities.drop[0] | string | `"all"` | This drops all linux privileges from the container. | -| scanner.securityContext.privileged | bool | `false` | Ensures that the scanner container is not run in privileged mode | -| scanner.securityContext.readOnlyRootFilesystem | bool | `false` | Prevents write access to the containers file system | -| scanner.securityContext.runAsNonRoot | bool | `true` | Enforces that the scanner image is run as a non root user | -| scanner.suspend | bool | `false` | if set to true the scan job will be suspended after creation. You can then resume the job using `kubectl resume ` or using a job scheduler like kueue | -| scanner.tolerations | list | `[]` | Optional tolerations settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) | -| scanner.ttlSecondsAfterFinished | string | `nil` | seconds after which the Kubernetes job for the scanner will be deleted. Requires the Kubernetes TTLAfterFinished controller: https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ | - -## Contributing - -Contributions are welcome and extremely helpful 🙌 -Please have a look at [Contributing](./CONTRIBUTING.md) - -## Community - -You are welcome, please join us on... 👋 - -- [GitHub][scb-github] -- [OWASP Slack (Channel #project-securecodebox)][scb-slack] -- [Mastodon][scb-mastodon] - -secureCodeBox is an official [OWASP][scb-owasp] project. - -## License -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) - -Code of secureCodeBox is licensed under the [Apache License 2.0][scb-license]. - -[scb-owasp]: https://www.owasp.org/index.php/OWASP_secureCodeBox -[scb-docs]: https://www.securecodebox.io/ -[scb-site]: https://www.securecodebox.io/ -[scb-github]: https://github.com/secureCodeBox/ -[scb-mastodon]: https://infosec.exchange/@secureCodeBox -[scb-slack]: https://owasp.org/slack/invite -[scb-license]: https://github.com/secureCodeBox/secureCodeBox/blob/master/LICENSE -[owasp_amass_project]: https://owasp.org/www-project-amass/ -[amass github]: https://github.com/OWASP/Amass -[amass user guide]: https://github.com/OWASP/Amass/blob/master/doc/user_guide.md diff --git a/scanners/amass/docs/README.DockerHub-Parser.md b/scanners/amass/docs/README.DockerHub-Parser.md deleted file mode 100644 index 9709a3e48a..0000000000 --- a/scanners/amass/docs/README.DockerHub-Parser.md +++ /dev/null @@ -1,93 +0,0 @@ - - - -

- License Apache-2.0 - GitHub release (latest SemVer) - OWASP Lab Project - Artifact HUB - GitHub Repo stars - Mastodon Follower -

- -## What is OWASP secureCodeBox? - -

- secureCodeBox Logo -

- -_[OWASP secureCodeBox][scb-github]_ is an automated and scalable open source solution that can be used to integrate various *security vulnerability scanners* with a simple and lightweight interface. The _secureCodeBox_ mission is to support *DevSecOps* Teams to make it easy to automate security vulnerability testing in different scenarios. - -With the _secureCodeBox_ we provide a toolchain for continuous scanning of applications to find the low-hanging fruit issues early in the development process and free the resources of the penetration tester to concentrate on the major security issues. - -The secureCodeBox project is running on [Kubernetes](https://kubernetes.io/). To install it you need [Helm](https://helm.sh), a package manager for Kubernetes. It is also possible to start the different integrated security vulnerability scanners based on a docker infrastructure. - -### Quickstart with secureCodeBox on Kubernetes - -You can find resources to help you get started on our [documentation website](https://www.securecodebox.io) including instruction on how to [install the secureCodeBox project](https://www.securecodebox.io/docs/getting-started/installation) and guides to help you [run your first scans](https://www.securecodebox.io/docs/getting-started/first-scans) with it. - -## Notice -This image is a workaround for the official Amass docker image, older amass versions are regularly removed from the official docker registry, this is often breaks our builds. -To prevent this we create a new image based on the official one and push it to our docker registry. -Copyright 2017 Jeff Foley. All rights reserved. - -## Supported Tags -- `latest` (represents the latest stable release build) -- tagged releases, e.g. `3.0.0`, `2.9.0`, `2.8.0`, `2.7.0` - -## How to use this image -This `parser` image is intended to work in combination with the corresponding security scanner docker image to parse the `findings` results. For more information details please take a look at the documentation page: https://www.securecodebox.io/docs/scanners/Amass. - -```bash -docker pull securecodebox/parser-amass -``` - -## What is OWASP Amass? - -:::caution -Amass currently has a [known issue](https://github.com/owasp-amass/amass/issues/918) where the enumeration sometimes does not exit correctly and keeps running indefinitely. This is why we recommend using the option `-timeout MINUTES` mitigate the issue. The scan will then exit after the specified amount of minutes, and the findings should be correctly parsed. -::: - -The [OWASP Amass Project][owasp_amass_project] has developed a tool to help information security professionals perform network mapping of attack surfaces and perform external asset discovery using open source information gathering and active reconnaissance techniques. To learn more about the Amass scanner itself visit [OWASP Amass Project][owasp_amass_project] or [Amass GitHub]. - -## Community - -You are welcome, please join us on... 👋 - -- [GitHub][scb-github] -- [OWASP Slack (Channel #project-securecodebox)][scb-slack] -- [Mastodon][scb-mastodon] - -secureCodeBox is an official [OWASP][scb-owasp] project. - -## License -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) - -As with all Docker images, these likely also contain other software which may be under other licenses (such as Bash, etc from the base distribution, along with any direct or indirect dependencies of the primary software being contained). - -As for any pre-built image usage, it is the image user's responsibility to ensure that any use of this image complies with any relevant licenses for all software contained within. - -[scb-owasp]: https://www.owasp.org/index.php/OWASP_secureCodeBox -[scb-docs]: https://www.securecodebox.io/ -[scb-site]: https://www.securecodebox.io/ -[scb-github]: https://github.com/secureCodeBox/ -[scb-mastodon]: https://infosec.exchange/@secureCodeBox -[scb-slack]: https://owasp.org/slack/invite -[scb-license]: https://github.com/secureCodeBox/secureCodeBox/blob/master/LICENSE -[owasp_amass_project]: https://owasp.org/www-project-amass/ -[amass github]: https://github.com/OWASP/Amass -[amass user guide]: https://github.com/OWASP/Amass/blob/master/doc/user_guide.md diff --git a/scanners/amass/docs/README.DockerHub-Scanner.md b/scanners/amass/docs/README.DockerHub-Scanner.md deleted file mode 100644 index 7c96040a81..0000000000 --- a/scanners/amass/docs/README.DockerHub-Scanner.md +++ /dev/null @@ -1,106 +0,0 @@ - - - -

- License Apache-2.0 - GitHub release (latest SemVer) - OWASP Lab Project - Artifact HUB - GitHub Repo stars - Mastodon Follower -

- -## What is OWASP secureCodeBox? - -

- secureCodeBox Logo -

- -_[OWASP secureCodeBox][scb-github]_ is an automated and scalable open source solution that can be used to integrate various *security vulnerability scanners* with a simple and lightweight interface. The _secureCodeBox_ mission is to support *DevSecOps* Teams to make it easy to automate security vulnerability testing in different scenarios. - -With the _secureCodeBox_ we provide a toolchain for continuous scanning of applications to find the low-hanging fruit issues early in the development process and free the resources of the penetration tester to concentrate on the major security issues. - -The secureCodeBox project is running on [Kubernetes](https://kubernetes.io/). To install it you need [Helm](https://helm.sh), a package manager for Kubernetes. It is also possible to start the different integrated security vulnerability scanners based on a docker infrastructure. - -### Quickstart with secureCodeBox on Kubernetes - -You can find resources to help you get started on our [documentation website](https://www.securecodebox.io) including instruction on how to [install the secureCodeBox project](https://www.securecodebox.io/docs/getting-started/installation) and guides to help you [run your first scans](https://www.securecodebox.io/docs/getting-started/first-scans) with it. - -## Notice -This image is a workaround for the official Amass docker image, older amass versions are regularly removed from the official docker registry, this is often breaks our builds. -To prevent this we create a new image based on the official one and push it to our docker registry. -Copyright 2017 Jeff Foley. All rights reserved. - -## Supported Tags -- `latest` (represents the latest stable release build) -- tagged releases, e.g. `3.0.0`, `2.9.0`, `2.8.0`, `2.7.0` - -## How to use this image -This `scanner` image is intended to work in combination with the corresponding `parser` image to parse the scanner `findings` to generic secureCodeBox results. For more information details please take a look at the [project page][scb-docs] or [documentation page][https://www.securecodebox.io/docs/scanners/Amass]. - -```bash -docker pull securecodebox/scanner-amass -``` - -## What is OWASP Amass? - -:::caution -Amass currently has a [known issue](https://github.com/owasp-amass/amass/issues/918) where the enumeration sometimes does not exit correctly and keeps running indefinitely. This is why we recommend using the option `-timeout MINUTES` mitigate the issue. The scan will then exit after the specified amount of minutes, and the findings should be correctly parsed. -::: - -The [OWASP Amass Project][owasp_amass_project] has developed a tool to help information security professionals perform network mapping of attack surfaces and perform external asset discovery using open source information gathering and active reconnaissance techniques. To learn more about the Amass scanner itself visit [OWASP Amass Project][owasp_amass_project] or [Amass GitHub]. - -## Scanner Configuration - -The following security scan configuration example are based on the [Amass User Guide](https://github.com/owasp-amass/amass/blob/master/doc/user_guide.md#the-enum-subcommand), please take a look at the original documentation for more configuration examples. - -- The most basic use of the tool for subdomain enumeration: `amass enum -d example.com` -- Typical parameters for DNS enumeration: `amass enum -v -brute -min-for-recursive 2 -d example.com` - -Special command line options: - -- Enable generation of altered names `amass enum -alts -d example.com` -- Turn off recursive brute forcing `amass enum -brute -norecursive -d example.com` -- Domain names separated by commas (can be used multiple times) `amass enum -d example.com` - -## Community - -You are welcome, please join us on... 👋 - -- [GitHub][scb-github] -- [OWASP Slack (Channel #project-securecodebox)][scb-slack] -- [Mastodon][scb-mastodon] - -secureCodeBox is an official [OWASP][scb-owasp] project. - -## License -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) - -As with all Docker images, these likely also contain other software which may be under other licenses (such as Bash, etc from the base distribution, along with any direct or indirect dependencies of the primary software being contained). - -As for any pre-built image usage, it is the image user's responsibility to ensure that any use of this image complies with any relevant licenses for all software contained within. - -[scb-owasp]: https://www.owasp.org/index.php/OWASP_secureCodeBox -[scb-docs]: https://www.securecodebox.io/ -[scb-site]: https://www.securecodebox.io/ -[scb-github]: https://github.com/secureCodeBox/ -[scb-mastodon]: https://infosec.exchange/@secureCodeBox -[scb-slack]: https://owasp.org/slack/invite -[scb-license]: https://github.com/secureCodeBox/secureCodeBox/blob/master/LICENSE -[owasp_amass_project]: https://owasp.org/www-project-amass/ -[amass github]: https://github.com/OWASP/Amass -[amass user guide]: https://github.com/OWASP/Amass/blob/master/doc/user_guide.md diff --git a/scanners/amass/examples/secureCodeBox.io/scan.yaml b/scanners/amass/examples/secureCodeBox.io/scan.yaml deleted file mode 100644 index 2a570fbd42..0000000000 --- a/scanners/amass/examples/secureCodeBox.io/scan.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -apiVersion: "execution.securecodebox.io/v1" -kind: Scan -metadata: - name: "amass-securecodebox.io" - labels: - organization: "secureCodeBox" -spec: - scanType: "amass" - parameters: - - "-norecursive" - - "-d" - - "securecodebox.io" diff --git a/scanners/amass/parser/Dockerfile b/scanners/amass/parser/Dockerfile deleted file mode 100644 index 0dbef28c20..0000000000 --- a/scanners/amass/parser/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -ARG namespace -ARG baseImageTag -FROM node:22-alpine AS build -RUN mkdir -p /home/app -WORKDIR /home/app -COPY package.json package-lock.json ./ -RUN npm ci --omit=dev - -FROM ${namespace:-securecodebox}/parser-sdk-nodejs:${baseImageTag:-latest} -WORKDIR /home/app/parser-wrapper/parser/ -COPY --from=build --chown=root:root --chmod=755 /home/app/node_modules/ ./node_modules/ -COPY --chown=root:root --chmod=755 ./parser.js ./parser.js diff --git a/scanners/amass/parser/__snapshots__/parser.test.js.snap b/scanners/amass/parser/__snapshots__/parser.test.js.snap deleted file mode 100644 index 6fda32d6b5..0000000000 --- a/scanners/amass/parser/__snapshots__/parser.test.js.snap +++ /dev/null @@ -1,1551 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`parser parses example.com sqlite results database successfully 1`] = ` -[ - { - "attributes": { - "addresses": { - "asn": 15133, - "cidr": "93.184.216.0/24", - "desc": "EDGECAST - MCI Communications Services, Inc. d/b/a Verizon Business", - "ip": "93.184.216.34", - }, - "domain": "example.com", - "hostname": "example.com", - "ip_addresses": "93.184.216.34", - }, - "category": "Subdomain", - "description": "Found subdomain example.com", - "identified_at": null, - "location": "example.com", - "name": "example.com", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": 15133, - "cidr": "2606:2800:220::/48", - "desc": "EDGECAST - MCI Communications Services, Inc. d/b/a Verizon Business", - "ip": "2606:2800:220:1:248:1893:25c8:1946", - }, - "domain": "example.com", - "hostname": "example.com", - "ip_addresses": "2606:2800:220:1:248:1893:25c8:1946", - }, - "category": "Subdomain", - "description": "Found subdomain example.com", - "identified_at": null, - "location": "example.com", - "name": "example.com", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "example.com", - "hostname": "iana-servers.net", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain iana-servers.net", - "identified_at": null, - "location": "iana-servers.net", - "name": "iana-servers.net", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": 26710, - "cidr": "199.43.133.0/24", - "desc": "ICANN-ANYCASTED-SERVICES - ICANN", - "ip": "199.43.133.53", - }, - "domain": "example.com", - "hostname": "b.iana-servers.net", - "ip_addresses": "199.43.133.53", - }, - "category": "Subdomain", - "description": "Found subdomain b.iana-servers.net", - "identified_at": null, - "location": "b.iana-servers.net", - "name": "b.iana-servers.net", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": 26710, - "cidr": "2001:500:8d::/48", - "desc": "ICANN-ANYCASTED-SERVICES - ICANN", - "ip": "2001:500:8d::53", - }, - "domain": "example.com", - "hostname": "b.iana-servers.net", - "ip_addresses": "2001:500:8d::53", - }, - "category": "Subdomain", - "description": "Found subdomain b.iana-servers.net", - "identified_at": null, - "location": "b.iana-servers.net", - "name": "b.iana-servers.net", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": 26710, - "cidr": "199.43.135.0/24", - "desc": "ICANN-ANYCASTED-SERVICES - ICANN", - "ip": "199.43.135.53", - }, - "domain": "example.com", - "hostname": "a.iana-servers.net", - "ip_addresses": "199.43.135.53", - }, - "category": "Subdomain", - "description": "Found subdomain a.iana-servers.net", - "identified_at": null, - "location": "a.iana-servers.net", - "name": "a.iana-servers.net", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": 26710, - "cidr": "2001:500:8f::/48", - "desc": "ICANN-ANYCASTED-SERVICES - ICANN", - "ip": "2001:500:8f::53", - }, - "domain": "example.com", - "hostname": "a.iana-servers.net", - "ip_addresses": "2001:500:8f::53", - }, - "category": "Subdomain", - "description": "Found subdomain a.iana-servers.net", - "identified_at": null, - "location": "a.iana-servers.net", - "name": "a.iana-servers.net", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": 15133, - "cidr": "93.184.216.0/24", - "desc": "EDGECAST - MCI Communications Services, Inc. d/b/a Verizon Business", - "ip": "93.184.216.34", - }, - "domain": "example.com", - "hostname": "www.example.com", - "ip_addresses": "93.184.216.34", - }, - "category": "Subdomain", - "description": "Found subdomain www.example.com", - "identified_at": null, - "location": "www.example.com", - "name": "www.example.com", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": 15133, - "cidr": "2606:2800:220::/48", - "desc": "EDGECAST - MCI Communications Services, Inc. d/b/a Verizon Business", - "ip": "2606:2800:220:1:248:1893:25c8:1946", - }, - "domain": "example.com", - "hostname": "www.example.com", - "ip_addresses": "2606:2800:220:1:248:1893:25c8:1946", - }, - "category": "Subdomain", - "description": "Found subdomain www.example.com", - "identified_at": null, - "location": "www.example.com", - "name": "www.example.com", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, -] -`; - -exports[`parser parses sqlite results database with empty relations table successfully 1`] = ` -[ - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain owasp.org", - "identified_at": null, - "location": "owasp.org", - "name": "owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "wiki.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain wiki.owasp.org", - "identified_at": null, - "location": "wiki.owasp.org", - "name": "wiki.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "calltobattle.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain calltobattle.owasp.org", - "identified_at": null, - "location": "calltobattle.owasp.org", - "name": "calltobattle.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "sl.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain sl.owasp.org", - "identified_at": null, - "location": "sl.owasp.org", - "name": "sl.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "kerala.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain kerala.owasp.org", - "identified_at": null, - "location": "kerala.owasp.org", - "name": "kerala.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "www.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain www.owasp.org", - "identified_at": null, - "location": "www.owasp.org", - "name": "www.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "calendar.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain calendar.owasp.org", - "identified_at": null, - "location": "calendar.owasp.org", - "name": "calendar.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "members.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain members.owasp.org", - "identified_at": null, - "location": "members.owasp.org", - "name": "members.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "lightning.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain lightning.owasp.org", - "identified_at": null, - "location": "lightning.owasp.org", - "name": "lightning.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "mail.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain mail.owasp.org", - "identified_at": null, - "location": "mail.owasp.org", - "name": "mail.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "thanniversary.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain thanniversary.owasp.org", - "identified_at": null, - "location": "thanniversary.owasp.org", - "name": "thanniversary.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "cheatsheetseries.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain cheatsheetseries.owasp.org", - "identified_at": null, - "location": "cheatsheetseries.owasp.org", - "name": "cheatsheetseries.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "secureflag.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain secureflag.owasp.org", - "identified_at": null, - "location": "secureflag.owasp.org", - "name": "secureflag.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "videos.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain videos.owasp.org", - "identified_at": null, - "location": "videos.owasp.org", - "name": "videos.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "www2.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain www2.owasp.org", - "identified_at": null, - "location": "www2.owasp.org", - "name": "www2.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "dev.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain dev.owasp.org", - "identified_at": null, - "location": "dev.owasp.org", - "name": "dev.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "contact.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain contact.owasp.org", - "identified_at": null, - "location": "contact.owasp.org", - "name": "contact.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "brainbreak.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain brainbreak.owasp.org", - "identified_at": null, - "location": "brainbreak.owasp.org", - "name": "brainbreak.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "gapps.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain gapps.owasp.org", - "identified_at": null, - "location": "gapps.owasp.org", - "name": "gapps.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "ocms.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain ocms.owasp.org", - "identified_at": null, - "location": "ocms.owasp.org", - "name": "ocms.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "training.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain training.owasp.org", - "identified_at": null, - "location": "training.owasp.org", - "name": "training.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "austin.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain austin.owasp.org", - "identified_at": null, - "location": "austin.owasp.org", - "name": "austin.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "name-virt-host.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain name-virt-host.owasp.org", - "identified_at": null, - "location": "name-virt-host.owasp.org", - "name": "name-virt-host.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "lists.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain lists.owasp.org", - "identified_at": null, - "location": "lists.owasp.org", - "name": "lists.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "devsecops.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain devsecops.owasp.org", - "identified_at": null, - "location": "devsecops.owasp.org", - "name": "devsecops.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "giving.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain giving.owasp.org", - "identified_at": null, - "location": "giving.owasp.org", - "name": "giving.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "dsomm.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain dsomm.owasp.org", - "identified_at": null, - "location": "dsomm.owasp.org", - "name": "dsomm.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "mas.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain mas.owasp.org", - "identified_at": null, - "location": "mas.owasp.org", - "name": "mas.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "securecodingdojo.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain securecodingdojo.owasp.org", - "identified_at": null, - "location": "securecodingdojo.owasp.org", - "name": "securecodingdojo.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "scvs.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain scvs.owasp.org", - "identified_at": null, - "location": "scvs.owasp.org", - "name": "scvs.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "docs.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain docs.owasp.org", - "identified_at": null, - "location": "docs.owasp.org", - "name": "docs.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "groups.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain groups.owasp.org", - "identified_at": null, - "location": "groups.owasp.org", - "name": "groups.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "new-wiki.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain new-wiki.owasp.org", - "identified_at": null, - "location": "new-wiki.owasp.org", - "name": "new-wiki.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "mu.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain mu.owasp.org", - "identified_at": null, - "location": "mu.owasp.org", - "name": "mu.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "www.lists.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain www.lists.owasp.org", - "identified_at": null, - "location": "www.lists.owasp.org", - "name": "www.lists.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "tsd.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain tsd.owasp.org", - "identified_at": null, - "location": "tsd.owasp.org", - "name": "tsd.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "www.ocms.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain www.ocms.owasp.org", - "identified_at": null, - "location": "www.ocms.owasp.org", - "name": "www.ocms.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "cheesemonkey.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain cheesemonkey.owasp.org", - "identified_at": null, - "location": "cheesemonkey.owasp.org", - "name": "cheesemonkey.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "tempcali.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain tempcali.owasp.org", - "identified_at": null, - "location": "tempcali.owasp.org", - "name": "tempcali.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "talk.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain talk.owasp.org", - "identified_at": null, - "location": "talk.owasp.org", - "name": "talk.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "haroldtest.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain haroldtest.owasp.org", - "identified_at": null, - "location": "haroldtest.owasp.org", - "name": "haroldtest.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "update-wiki.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain update-wiki.owasp.org", - "identified_at": null, - "location": "update-wiki.owasp.org", - "name": "update-wiki.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "dsandbox.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain dsandbox.owasp.org", - "identified_at": null, - "location": "dsandbox.owasp.org", - "name": "dsandbox.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "discourse.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain discourse.owasp.org", - "identified_at": null, - "location": "discourse.owasp.org", - "name": "discourse.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "ads.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain ads.owasp.org", - "identified_at": null, - "location": "ads.owasp.org", - "name": "ads.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "5c4171004230818351034.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain 5c4171004230818351034.owasp.org", - "identified_at": null, - "location": "5c4171004230818351034.owasp.org", - "name": "5c4171004230818351034.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "admin.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain admin.owasp.org", - "identified_at": null, - "location": "admin.owasp.org", - "name": "admin.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "ftp.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain ftp.owasp.org", - "identified_at": null, - "location": "ftp.owasp.org", - "name": "ftp.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "forum.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain forum.owasp.org", - "identified_at": null, - "location": "forum.owasp.org", - "name": "forum.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "esvnjfkee.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain esvnjfkee.owasp.org", - "identified_at": null, - "location": "esvnjfkee.owasp.org", - "name": "esvnjfkee.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "wwww.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain wwww.owasp.org", - "identified_at": null, - "location": "wwww.owasp.org", - "name": "wwww.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "www.my.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain www.my.owasp.org", - "identified_at": null, - "location": "www.my.owasp.org", - "name": "www.my.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "ww.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain ww.owasp.org", - "identified_at": null, - "location": "ww.owasp.org", - "name": "ww.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "webmail.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain webmail.owasp.org", - "identified_at": null, - "location": "webmail.owasp.org", - "name": "webmail.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "webgoat.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain webgoat.owasp.org", - "identified_at": null, - "location": "webgoat.owasp.org", - "name": "webgoat.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "stin.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain stin.owasp.org", - "identified_at": null, - "location": "stin.owasp.org", - "name": "stin.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "registration.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain registration.owasp.org", - "identified_at": null, - "location": "registration.owasp.org", - "name": "registration.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "phpsec.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain phpsec.owasp.org", - "identified_at": null, - "location": "phpsec.owasp.org", - "name": "phpsec.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "owasp4.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain owasp4.owasp.org", - "identified_at": null, - "location": "owasp4.owasp.org", - "name": "owasp4.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "old.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain old.owasp.org", - "identified_at": null, - "location": "old.owasp.org", - "name": "old.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "my.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain my.owasp.org", - "identified_at": null, - "location": "my.owasp.org", - "name": "my.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "ml1.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain ml1.owasp.org", - "identified_at": null, - "location": "ml1.owasp.org", - "name": "ml1.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "ml1lists.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain ml1lists.owasp.org", - "identified_at": null, - "location": "ml1lists.owasp.org", - "name": "ml1lists.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "lessons.webgoat.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain lessons.webgoat.owasp.org", - "identified_at": null, - "location": "lessons.webgoat.owasp.org", - "name": "lessons.webgoat.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "jobs.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain jobs.owasp.org", - "identified_at": null, - "location": "jobs.owasp.org", - "name": "jobs.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "es.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain es.owasp.org", - "identified_at": null, - "location": "es.owasp.org", - "name": "es.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "blogs.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain blogs.owasp.org", - "identified_at": null, - "location": "blogs.owasp.org", - "name": "blogs.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, - { - "attributes": { - "addresses": { - "asn": null, - "cidr": null, - "desc": null, - "ip": null, - }, - "domain": "owasp.org", - "hostname": "beta.owasp.org", - "ip_addresses": null, - }, - "category": "Subdomain", - "description": "Found subdomain beta.owasp.org", - "identified_at": null, - "location": "beta.owasp.org", - "name": "beta.owasp.org", - "osi_layer": "NETWORK", - "severity": "INFORMATIONAL", - }, -] -`; diff --git a/scanners/amass/parser/__testFiles__/emptyRelations.sqlite b/scanners/amass/parser/__testFiles__/emptyRelations.sqlite deleted file mode 100644 index 7c1ea6187e..0000000000 Binary files a/scanners/amass/parser/__testFiles__/emptyRelations.sqlite and /dev/null differ diff --git a/scanners/amass/parser/__testFiles__/emptyTables.sqlite b/scanners/amass/parser/__testFiles__/emptyTables.sqlite deleted file mode 100644 index 60f5523246..0000000000 Binary files a/scanners/amass/parser/__testFiles__/emptyTables.sqlite and /dev/null differ diff --git a/scanners/amass/parser/__testFiles__/example.com.sqlite b/scanners/amass/parser/__testFiles__/example.com.sqlite deleted file mode 100644 index 879dc86942..0000000000 Binary files a/scanners/amass/parser/__testFiles__/example.com.sqlite and /dev/null differ diff --git a/scanners/amass/parser/__testFiles__/noTables.sqlite b/scanners/amass/parser/__testFiles__/noTables.sqlite deleted file mode 100644 index f0016baef7..0000000000 Binary files a/scanners/amass/parser/__testFiles__/noTables.sqlite and /dev/null differ diff --git a/scanners/amass/parser/package-lock.json b/scanners/amass/parser/package-lock.json deleted file mode 100644 index aeae45de77..0000000000 --- a/scanners/amass/parser/package-lock.json +++ /dev/null @@ -1,1382 +0,0 @@ -{ - "name": "@securecodebox/parser-amass", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@securecodebox/parser-amass", - "version": "1.0.0", - "license": "Apache-2.0", - "dependencies": { - "sqlite3": "^5.1.7" - }, - "devDependencies": {} - }, - "node_modules/@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "optional": true - }, - "node_modules/@npmcli/fs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", - "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", - "optional": true, - "dependencies": { - "@gar/promisify": "^1.0.1", - "semver": "^7.3.5" - } - }, - "node_modules/@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "deprecated": "This functionality has been moved to @npmcli/fs", - "optional": true, - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "optional": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "optional": true - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "optional": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/agentkeepalive": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", - "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", - "optional": true, - "dependencies": { - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "optional": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "optional": true - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "optional": true - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "license": "MIT", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "license": "MIT", - "optional": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "optional": true, - "dependencies": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "optional": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "optional": true, - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "optional": true - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "optional": true - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "optional": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "optional": true - }, - "node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "optional": true - }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "optional": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "optional": true - }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "license": "(MIT OR WTFPL)", - "engines": { - "node": ">=6" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "license": "MIT" - }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "license": "MIT" - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "optional": true - }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "license": "MIT" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "optional": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "optional": true - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "optional": true - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "optional": true - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "optional": true, - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "optional": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "optional": true, - "dependencies": { - "ms": "^2.0.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "optional": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "optional": true - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "optional": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "license": "ISC" - }, - "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", - "license": "MIT", - "optional": true, - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "optional": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "optional": true - }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "license": "MIT", - "optional": true - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-fetch-happen": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", - "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", - "optional": true, - "dependencies": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.2.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^6.0.0", - "minipass": "^3.1.3", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^1.3.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.2", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^6.0.0", - "ssri": "^8.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "optional": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "optional": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-fetch": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", - "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", - "optional": true, - "dependencies": { - "minipass": "^3.1.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "optionalDependencies": { - "encoding": "^0.1.12" - } - }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "optional": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "optional": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "optional": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "license": "MIT" - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true - }, - "node_modules/napi-build-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", - "license": "MIT" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "optional": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-abi": { - "version": "3.75.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz", - "integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==", - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "license": "MIT" - }, - "node_modules/node-gyp": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", - "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", - "optional": true, - "dependencies": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^9.1.0", - "nopt": "^5.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": ">= 10.12.0" - } - }, - "node_modules/node-gyp/node_modules/are-we-there-yet": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", - "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", - "optional": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/node-gyp/node_modules/gauge": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", - "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", - "optional": true, - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/node-gyp/node_modules/npmlog": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", - "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", - "optional": true, - "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "optional": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "optional": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/prebuild-install": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^2.0.0", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "optional": true - }, - "node_modules/promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "optional": true, - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pump": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", - "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "optional": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "optional": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "optional": true - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "optional": true - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "optional": true - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "optional": true, - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.5.tgz", - "integrity": "sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==", - "license": "MIT", - "optional": true, - "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", - "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", - "optional": true, - "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "license": "BSD-3-Clause", - "optional": true - }, - "node_modules/sqlite3": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz", - "integrity": "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "bindings": "^1.5.0", - "node-addon-api": "^7.0.0", - "prebuild-install": "^7.1.1", - "tar": "^6.1.11" - }, - "optionalDependencies": { - "node-gyp": "8.x" - }, - "peerDependencies": { - "node-gyp": "8.x" - }, - "peerDependenciesMeta": { - "node-gyp": { - "optional": true - } - } - }, - "node_modules/ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "optional": true, - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "optional": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "optional": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar-fs": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", - "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", - "license": "MIT", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "license": "ISC" - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "optional": true, - "dependencies": { - "unique-slug": "^2.0.0" - } - }, - "node_modules/unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "optional": true, - "dependencies": { - "imurmurhash": "^0.1.4" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "optional": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "optional": true, - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } -} diff --git a/scanners/amass/parser/package-lock.json.license b/scanners/amass/parser/package-lock.json.license deleted file mode 100644 index 3034c0d74b..0000000000 --- a/scanners/amass/parser/package-lock.json.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: the secureCodeBox authors - -SPDX-License-Identifier: Apache-2.0 \ No newline at end of file diff --git a/scanners/amass/parser/package.json b/scanners/amass/parser/package.json deleted file mode 100644 index 45c118406f..0000000000 --- a/scanners/amass/parser/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "@securecodebox/parser-amass", - "version": "1.0.0", - "description": "Parses result files for the type: 'amass-sqlite'", - "main": "", - "scripts": {}, - "keywords": [], - "author": "iteratec GmbH", - "license": "Apache-2.0", - "dependencies": { - "sqlite3": "^5.1.7" - }, - "devDependencies": {} -} \ No newline at end of file diff --git a/scanners/amass/parser/package.json.license b/scanners/amass/parser/package.json.license deleted file mode 100644 index 3034c0d74b..0000000000 --- a/scanners/amass/parser/package.json.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: the secureCodeBox authors - -SPDX-License-Identifier: Apache-2.0 \ No newline at end of file diff --git a/scanners/amass/parser/parser.js b/scanners/amass/parser/parser.js deleted file mode 100644 index f60164d0aa..0000000000 --- a/scanners/amass/parser/parser.js +++ /dev/null @@ -1,130 +0,0 @@ -// SPDX-FileCopyrightText: the secureCodeBox authors -// -// SPDX-License-Identifier: Apache-2.0 - -import sqlite from "sqlite3"; -import { writeFile } from "node:fs/promises"; -import { join } from "node:path"; -import { tmpdir } from "node:os"; - -async function checkIfTableExists(db) { - const query = `select count(*) from sqlite_master m where m.name="assets" OR m.name="relations"`; - const [row] = await queryAll(db, query); - return row["count(*)"] === 2; -} - -function queryAll(db, query) { - return new Promise((resolve, reject) => { - db.all(query, [], (err, rows) => { - if (err) { - reject(err); - return; - } - resolve(rows); - }); - }); -} - -async function openDatabase(fileContent) { - const tempFilePath = join(tmpdir(), "temp-sqlite" + ".sqlite"); - // Write the content to a temporary file - await writeFile(tempFilePath, fileContent); - - return await new Promise((resolve, reject) => { - const db = new sqlite.Database( - tempFilePath, - sqlite.OPEN_READONLY, - (err) => { - if (err) { - reject(err.message); - return; - } - }, - ); - resolve(db); - }); -} - -function closeDatabase(db) { - return new Promise((resolve, reject) => { - db.close((err) => { - resolve(); - if (err) { - reject(err); - } - }); - }); -} - -export async function parse(fileContent) { - const db = await openDatabase(fileContent); - const tableExists = await checkIfTableExists(db); - if (!tableExists) return []; - - const query = ` - WITH relation_chain AS ( - SELECT - fqdn.content AS subdomain, - ips.content AS ip, - cidr.content AS cidr, - asn.id AS asn_id, - asn.content AS asn - FROM assets fqdn - - LEFT JOIN relations r1 ON fqdn.id = r1.from_asset_id AND (r1.type = 'a_record' OR r1.type = 'aaaa_record') - LEFT JOIN assets ips ON r1.to_asset_id = ips.id - - LEFT JOIN relations r2 ON ips.id = r2.to_asset_id AND r2.type = 'contains' - LEFT JOIN assets cidr ON r2.from_asset_id = cidr.id - - LEFT JOIN relations r3 ON cidr.id = r3.to_asset_id AND r3.type = 'announces' - LEFT JOIN assets asn ON r3.from_asset_id = asn.id - - WHERE fqdn.type = 'FQDN' - ) - SELECT - rc.subdomain, - rc.ip, - rc.cidr, - rc.asn, - a.content AS managed_by, - (SELECT content FROM assets WHERE id = 1) AS domain - FROM relation_chain rc - LEFT JOIN relations r ON rc.asn_id = r.from_asset_id AND r.type = 'managed_by' - LEFT JOIN assets a ON r.to_asset_id = a.id;`; - - const rows = await queryAll(db, query); - - await closeDatabase(db); - - return rows.map((row) => { - // Parse the stringified JSON values - const domainObj = JSON.parse(row.domain); - const subdomainObj = JSON.parse(row.subdomain); - const ipObj = JSON.parse(row.ip); - const cidrObj = JSON.parse(row.cidr); - const asnObj = JSON.parse(row.asn); - const managedByObj = JSON.parse(row.managed_by); - - return { - name: subdomainObj.name, - identified_at: null, - description: `Found subdomain ${subdomainObj.name}`, - category: "Subdomain", - location: subdomainObj.name, - osi_layer: "NETWORK", - severity: "INFORMATIONAL", - attributes: { - addresses: { - ip: ipObj?.address || null, - cidr: cidrObj?.cidr || null, - asn: asnObj?.number || null, - desc: managedByObj?.name || null, - }, - domain: domainObj?.name || null, - hostname: subdomainObj?.name || null, - ip_addresses: ipObj?.address || null, - }, - }; - }); -} diff --git a/scanners/amass/parser/parser.test.js b/scanners/amass/parser/parser.test.js deleted file mode 100644 index cfc3e5d02b..0000000000 --- a/scanners/amass/parser/parser.test.js +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-FileCopyrightText: the secureCodeBox authors -// -// SPDX-License-Identifier: Apache-2.0 - -import { readFile } from "node:fs/promises"; -import { validateParser } from "@securecodebox/parser-sdk-nodejs/parser-utils"; - -import { parse } from "./parser"; - -test("parser parses example.com sqlite results database successfully", async () => { - const fileContent = await readFile( - import.meta.dirname + "/__testFiles__/example.com.sqlite", - ); - - const findings = await parse(fileContent); - await expect(validateParser(findings)).resolves.toBeUndefined(); - expect(findings).toMatchSnapshot(); -}); - -test("parser parses sqlite results database with empty tables successfully", async () => { - const fileContent = await readFile( - import.meta.dirname + "/__testFiles__/emptyTables.sqlite", - ); - - const findings = await parse(fileContent); - await expect(validateParser(findings)).resolves.toBeUndefined(); - expect(findings).toEqual([]); -}); - -test("parser parses sqlite results database with no tables successfully", async () => { - const fileContent = await readFile( - import.meta.dirname + "/__testFiles__/noTables.sqlite", - ); - - const findings = await parse(fileContent); - await expect(validateParser(findings)).resolves.toBeUndefined(); - expect(findings).toEqual([]); -}); - -test("parser parses sqlite results database with empty relations table successfully", async () => { - const fileContent = await readFile( - import.meta.dirname + "/__testFiles__/emptyRelations.sqlite", - ); - - const findings = await parse(fileContent); - await expect(validateParser(findings)).resolves.toBeUndefined(); - expect(findings).toMatchSnapshot(); -}); diff --git a/scanners/amass/scanner/Dockerfile b/scanners/amass/scanner/Dockerfile deleted file mode 100644 index 78d17e1ddc..0000000000 --- a/scanners/amass/scanner/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# Older amass versions are regularly removed from the official docker registry, this is often breaks our builds. -# To prevent this we create a new image based on the official one and push it to our docker registry. - -ARG scannerVersion -FROM caffix/amass:${scannerVersion} -# The amass image uses the user "user" with the id 1000, we set it here as a numeric value to allow runAsNonRoot -USER 1000 -ENTRYPOINT ["/bin/amass"] diff --git a/scanners/amass/templates/amass-parse-definition.yaml b/scanners/amass/templates/amass-parse-definition.yaml deleted file mode 100644 index 09222ef3b4..0000000000 --- a/scanners/amass/templates/amass-parse-definition.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -apiVersion: "execution.securecodebox.io/v1" -kind: ParseDefinition -metadata: - name: "amass-sqlite" -spec: - image: "{{ .Values.parser.image.repository }}:{{ .Values.parser.image.tag | default .Chart.Version }}" - imagePullPolicy: {{ .Values.parser.image.pullPolicy }} - ttlSecondsAfterFinished: {{ .Values.parser.ttlSecondsAfterFinished }} - env: - {{- toYaml .Values.parser.env | nindent 4 }} - scopeLimiterAliases: - {{- toYaml .Values.parser.scopeLimiterAliases | nindent 4 }} - affinity: - {{- toYaml .Values.parser.affinity | nindent 4 }} - tolerations: - {{- toYaml .Values.parser.tolerations | nindent 4 }} - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.parser.resources }} - resources: - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.parser.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 4 }} - {{- end }} - contentType: Binary - - volumes: - - name: temp-storage - emptyDir: {} # This will create an empty directory as volume. - volumeMounts: - - name: temp-storage - mountPath: /tmp/ # Mounting to /tmp in the container. Overrides the read-only /tmp diff --git a/scanners/amass/templates/amass-scan-type.yaml b/scanners/amass/templates/amass-scan-type.yaml deleted file mode 100644 index 311c7f6e96..0000000000 --- a/scanners/amass/templates/amass-scan-type.yaml +++ /dev/null @@ -1,435 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -apiVersion: "execution.securecodebox.io/v1" -kind: ScanType -metadata: - name: "amass{{ .Values.scanner.nameAppend | default ""}}" -spec: - extractResults: - type: amass-sqlite - location: "/home/securecodebox/amass.sqlite" - jobTemplate: - spec: - suspend: {{ .Values.scanner.suspend | default false }} - {{- if .Values.scanner.ttlSecondsAfterFinished }} - ttlSecondsAfterFinished: {{ .Values.scanner.ttlSecondsAfterFinished }} - {{- end }} - backoffLimit: {{ .Values.scanner.backoffLimit }} - {{- if .Values.scanner.activeDeadlineSeconds }} - activeDeadlineSeconds: {{ .Values.scanner.activeDeadlineSeconds }} - {{- end }} - template: - spec: - restartPolicy: OnFailure - affinity: - {{- toYaml .Values.scanner.affinity | nindent 12 }} - tolerations: - {{- toYaml .Values.scanner.tolerations | nindent 12 }} - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 12 }} - {{- end }} - securityContext: - {{- toYaml .Values.scanner.podSecurityContext | nindent 12 }} - containers: - - name: amass - image: "{{ .Values.scanner.image.repository }}:{{ .Values.scanner.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.scanner.image.pullPolicy }} - command: - - "amass" - - "enum" - - "-dir" - - "/home/securecodebox/" - resources: - {{- toYaml .Values.scanner.resources | nindent 16 }} - securityContext: - {{- toYaml .Values.scanner.securityContext | nindent 16 }} - env: - {{- toYaml .Values.scanner.env | nindent 16 }} - volumeMounts: - {{- toYaml .Values.scanner.extraVolumeMounts | nindent 16 }} - {{- if .Values.scanner.extraContainers }} - {{- toYaml .Values.scanner.extraContainers | nindent 12 }} - {{- end }} - volumes: - {{- toYaml .Values.scanner.extraVolumes | nindent 12 }} - {{- with .Values.scanner.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 12 }} - {{- end }} ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: amass-config -data: - config.ini: |- - # Copyright © by Jeff Foley 2017-2022. All rights reserved. - # Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. - # SPDX-License-Identifier: Apache-2.0 - - # Should results only be collected passively and without DNS resolution? Not recommended. - #mode = passive - # Would you like to use active techniques that communicate directly with the discovered assets, - # such as pulling TLS certificates from discovered IP addresses and attempting DNS zone transfers? - #mode = active - - # The directory that stores the Cayley graph database and other output files - # The default for Linux systems is: $HOME/.config/amass - #output_directory = amass - - # Another location (directory) where the user can provide ADS scripts to the engine. - #scripts_directory = - - # The maximum number of DNS queries that can be performed concurrently during the enumeration. - #maximum_dns_queries = 20000 - - # DNS resolvers used globally by the amass package. - #[resolvers] - #resolver = 1.1.1.1 ; Cloudflare - #resolver = 8.8.8.8 ; Google - #resolver = 64.6.64.6 ; Verisign - #resolver = 74.82.42.42 ; Hurricane Electric - #resolver = 1.0.0.1 ; Cloudflare Secondary - #resolver = 8.8.4.4 ; Google Secondary - #resolver = 64.6.65.6 ; Verisign Secondary - #resolver = 77.88.8.8 ; Yandex.DNS Secondary - - [scope] - # The network infrastructure settings expand scope, not restrict the scope. - # Single IP address or range (e.g. a.b.c.10-245) - #address = 192.168.1.1 - #cidr = 192.168.1.0/24 - #asn = 26808 - port = 80 - port = 443 - #port = 8080 - #port = 8443 - - # Root domain names used in the enumeration. The findings are limited by the root domain names provided. - #[scope.domains] - #domain = owasp.org - #domain = appsecusa.org - #domain = appsec.eu - #domain = appsec-labs.com - - # Are there any subdomains that are out of scope? - #[scope.blacklisted] - #subdomain = education.appsec-labs.com - #subdomain = 2012.appsecusa.org - - # The graph database discovered DNS names, associated network infrastructure, results from data sources, etc. - # This information is then used in future enumerations and analysis of the discoveries. - #[graphdbs] - # postgres://[username:password@]host[:port]/database-name?sslmode=disable of the PostgreSQL - # database and credentials. Sslmode is optional, and can be disable, require, verify-ca, or verify-full. - #[graphdbs.postgres] - #primary = false ; Specify which graph database is the primary db, or the local database will be selected. - #url = "postgres://[username:password@]host[:port]/database-name?sslmode=disable" - #options="connect_timeout=10" - - # MqSQL database and credentials URL format: - # [username:password@]tcp(host[:3306])/database-name?timeout=10s - #[graphdbs.mysql] - #url = [username:password@]tcp(host[:3306])/database-name?timeout=10s - - # Settings related to DNS name brute forcing. - #[bruteforce] - #enabled = true - #recursive = true - # Number of discoveries made in a subdomain before performing recursive brute forcing: Default is 1. - #minimum_for_recursive = 1 - #wordlist_file = /usr/share/wordlists/all.txt - #wordlist_file = /usr/share/wordlists/all.txt # multiple lists can be used - - # Would you like to permute resolved names? - #[alterations] - #enabled = true - # edit_distance specifies the number of times a primitive edit operation will be - # performed on a name sample during fuzzy label searching. - #edit_distance = 1 ; Setting this to zero will disable this expensive feature. - #flip_words = true # test-dev.owasp.org -> test-prod.owasp.org - #flip_numbers = true # test1.owasp.org -> test2.owasp.org - #add_words = true # test.owasp.org -> test-dev.owasp.org - #add_numbers = true # test.owasp.org -> test1.owasp.org - # Multiple lists can be used. - #wordlist_file = /usr/share/wordlists/all.txt - #wordlist_file = /usr/share/wordlists/all.txt - - [data_sources] - # When set, this time-to-live is the minimum value applied to all data source caching. - minimum_ttl = 1440 ; One day - - # Are there any data sources that should be disabled? - #[data_sources.disabled] - #data_source = Ask - #data_source = Bing - - # Provide data source configuration information. - # See the following format: - #[data_sources.SOURCENAME] ; The SOURCENAME must match the name in the data source implementation. - #ttl = 4320 ; Time-to-live value sets the number of minutes that the responses are cached. - # Unique identifier for this set of SOURCENAME credentials. - # Multiple sets of credentials can be provided and will be randomly selected. - #[data_sources.SOURCENAME.CredentialSetID] - #apikey = ; Each data source uses potentially different keys for authentication. - #secret = ; See the examples below for each data source. - #username = - #password = - - # https://passivedns.cn (Contact) - #[data_sources.360PassiveDNS] - #[data_sources.360PassiveDNS.Credentials] - #apikey = - - # https://ahrefs.com (Paid) - #[data_sources.Ahrefs] - #ttl = 4320 - #[data_sources.Ahrefs.Credentials] - #apikey = - - # https://otx.alienvault.com (Free) - #[data_sources.AlienVault] - #[data_sources.AlienVault.Credentials] - #apikey = - - # https://app.binaryedge.com (Paid/Free-trial) - #[data_sources.BinaryEdge] - #ttl = 10080 - #[data_sources.BinaryEdge.Credentials] - #apikey = - - # https://tls.bufferover.run/dns?q=.example.com (Paid/Free) - #[data_sources.BufferOver] - #[data_sources.BufferOver.Credentials] - #apikey = - - # https://builtwith.com (Paid/Free-trial) - #[data_sources.BuiltWith] - #ttl = 10080 - #[data_sources.BuiltWith.Credentials] - #apikey = - - # https://c99.nl (Paid) - #[data_sources.C99] - #ttl = 4320 - #[data_sources.C99.account1] - #apikey = - #[data_sources.C99.account2] - #apikey = - - # https://censys.io (Paid/Free-trial) - #[data_sources.Censys] - #ttl = 10080 - #[data_sources.Censys.Credentials] - #apikey = - #secret = - - # https://chaos.projectdiscovery.io (Invite-Only) - #[data_sources.Chaos] - #ttl = 4320 - #[data_sources.Chaos.Credentials] - #apikey = - - # https://cloudflare.com (Free) - # Cloudflare apikey is the API token with dns_records and zone read permission - #[data_sources.Cloudflare] - #[data_sources.Cloudflare.Credentials] - #apikey = - - # https://circl.lu (Contact) - #[data_sources.CIRCL] - #[data_sources.CIRCL.Credentials] - #username = - #password = - - # https://dnsdb.info (Paid) - #[data_sources.DNSDB] - #ttl = 4320 - #[data_sources.DNSDB.Credentials] - #apikey = - - # https://dnslytics.com (Paid) - #[data_sources.DNSlytics] - #[data_sources.DNSlytics.Credentials] - #apikey = - - # https://dnsrepo.noc.org (Paid) - #[data_sources.DNSRepo] - #[data_sources.DNSRepo.Credentials] - #apikey = - - # https://detectify.com (Paid) - #[data_sources.Detectify] - #[data_sources.Detectify.Credentials] - #apikey = - - # https://developer.facebook.com (Free) - # Look here for how to obtain the Facebook credentials: - # https://goldplugins.com/documentation/wp-social-pro-documentation/how-to-get-an-app-id-and-secret-key-from-facebook/ - #[data_sources.FacebookCT] - #ttl = 4320 - #[data_sources.FacebookCT.app1] - #apikey = - #secret = - #[data_sources.FacebookCT.app2] - #apikey = - #secret = - - # https://fofa.so (Paid) - #[data_sources.FOFA] - #ttl = 10080 - #[data_sources.FOFA.Credentials] - #username = - #apikey = - - # https://github.com (Free) - #[data_sources.GitHub] - #ttl = 4320 - #[data_sources.GitHub.accountname] - #apikey = - - # https://gitlab.com (Freemium) - #[data_sources.GitLab] - #[data_sources.GitLab.free] - #apikey = - #[data_sources.GitLab.premium] - #apikey = - - # https://hackertarget.com (Paid/Free) - # HackerTarget can be used without an API key, but the key allows better results - #[data_sources.HackerTarget] - #ttl = 1440 - #[data_sources.HackerTarget.Credentials] - #apikey = - - # https://hunter.io (Paid/Free-trial) - #[data_sources.Hunter] - #[data_sources.Hunter.Credentials] - #apikey = - - #[data_sources.IntelX] - #[data_sources.IntelX.Credentials] - #apikey = - - # https://ipdata.co (Free) - #[data_sources.IPdata] - #[data_sources.IPdata.Credentials] - #apikey = - - # https://ipinfo.io (Paid/Free-trial) - #[data_sources.IPinfo] - #[data_sources.IPinfo.Credentials] - #apikey = - - # https://leakix.net/ (Free) - #[data_sources.LeakIX] - #[data_sources.LeakIX.Credentials] - #apikey = - - # https://networksdb.io (Paid/Free-trial) - #[data_sources.NetworksDB] - #[data_sources.NetworksDB.Credentials] - #apikey = - - # https://onyphe.io (Free) - #[data_sources.ONYPHE] - #ttl = 10080 - #[data_sources.ONYPHE.Credentials] - #apikey = - - # https://passivetotal.com (Paid/Free-trial) - #[data_sources.PassiveTotal] - #ttl = 10080 - #[data_sources.PassiveTotal.Credentials] - #username = - #apikey = - - # https://pentest-tools.com (Paid) - #[data_sources.PentestTools] - #ttl = 10080 - #[data_sources.PentestTools.Credentials] - #apikey = - - # https://quake.360.cn (Paid) - #[data_sources.Quake] - #ttl = 4320 - #[data_sources.Quake.Credentials] - #apikey = - - # https://securitytrails.com (Paid/Free-trial) - #[data_sources.SecurityTrails] - #ttl = 1440 - #[data_sources.SecurityTrails.Credentials] - #apikey = - - # https://shodan.io (Paid/Free-trial) - #[data_sources.Shodan] - #ttl = 10080 - #[data_sources.Shodan.Credentials] - #apikey = - - # https://spamhaus.com (Free) - #[data_sources.Spamhaus] - #ttl = 1440 - #[data_sources.Spamhaus.Credentials] - #username = - #password = - - # https://spyse.com (Paid/Free-trial) - #[data_sources.Spyse] - #ttl = 4320 - #[data_sources.Spyse.Credentials] - #apikey = - - # https://threatbook.cn (Paid) - #[data_sources.ThreatBook] - #[data_sources.ThreatBook.account1] - #apikey= - - # https://developer.twitter.com (Free) - # Provide your Twitter App Consumer API key and Consumer API secret key - #[data_sources.Twitter] - #[data_sources.Twitter.account1] - #apikey = - #secret = - #[data_sources.Twitter.account2] - #apikey = - #secret = - - # https://umbrella.cisco.com (Paid-Enterprise) - # The apikey must be an API access token created through the Investigate management UI - #[data_sources.Umbrella] - #[data_sources.Umbrella.Credentials] - #apikey = - - # https://urlscan.io (Paid/Free-trial) - # URLScan can be used without an API key, but the key allows new submissions to be made - #[data_sources.URLScan] - #[data_sources.URLScan.Credentials] - #apikey = - - # https://virustotal.com (Paid/Free-trial) - #[data_sources.VirusTotal] - #ttl = 10080 - #[data_sources.VirusTotal.Credentials] - #apikey = - - # https://whoisxmlapi.com (Paid/Free-trial) - #[data_sources.WhoisXMLAPI] - #[data_sources.WhoisXMLAPI.Credentials] - #apikey = - - # https://zetalytics.com (Paid/Invite-Only) - #[data_sources.ZETAlytics] - #ttl = 1440 - #[data_sources.ZETAlytics.Credentials] - #apikey = - - #[data_sources.ZoomEye] - #ttl = 1440 - #[data_sources.ZoomEye.Credentials] - #username = - #password = \ No newline at end of file diff --git a/scanners/amass/tests/__snapshot__/scanner_test.yaml.snap b/scanners/amass/tests/__snapshot__/scanner_test.yaml.snap deleted file mode 100644 index 093877e9f3..0000000000 --- a/scanners/amass/tests/__snapshot__/scanner_test.yaml.snap +++ /dev/null @@ -1,93 +0,0 @@ -matches the snapshot: - 1: | - apiVersion: execution.securecodebox.io/v1 - kind: ParseDefinition - metadata: - name: amass-sqlite - spec: - affinity: - foo: bar - contentType: Binary - env: - - name: foo - value: bar - image: docker.io/securecodebox/parser-amass:0.0.0 - imagePullPolicy: IfNotPresent - imagePullSecrets: - - name: foo - resources: - foo: bar - scopeLimiterAliases: - foo: bar - tolerations: - - foo: bar - ttlSecondsAfterFinished: null - volumeMounts: - - mountPath: /tmp/ - name: temp-storage - volumes: - - emptyDir: {} - name: temp-storage - 2: | - apiVersion: execution.securecodebox.io/v1 - kind: ScanType - metadata: - name: amassfoo - spec: - extractResults: - location: /home/securecodebox/amass.sqlite - type: amass-sqlite - jobTemplate: - spec: - backoffLimit: 3 - suspend: false - template: - spec: - affinity: - foo: bar - containers: - - command: - - amass - - enum - - -dir - - /home/securecodebox/ - env: - - name: foo - value: bar - image: docker.io/securecodebox/scanner-amass:0.0.0 - imagePullPolicy: IfNotPresent - name: amass - resources: - foo: bar - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - all - privileged: false - readOnlyRootFilesystem: false - runAsNonRoot: true - volumeMounts: - - mountPath: /amass/output/config.ini - name: amass-config - subPath: config.ini - - image: bar - name: foo - imagePullSecrets: - - name: foo - restartPolicy: OnFailure - securityContext: - fsGroup: 1234 - tolerations: - - foo: bar - volumes: - - configMap: - name: amass-config - name: amass-config - 3: | - apiVersion: v1 - data: - config.ini: "# Copyright © by Jeff Foley 2017-2022. All rights reserved.\n# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.\n# SPDX-License-Identifier: Apache-2.0\n\n# Should results only be collected passively and without DNS resolution? Not recommended.\n#mode = passive\n# Would you like to use active techniques that communicate directly with the discovered assets, \n# such as pulling TLS certificates from discovered IP addresses and attempting DNS zone transfers?\n#mode = active\n\n# The directory that stores the Cayley graph database and other output files\n# The default for Linux systems is: $HOME/.config/amass\n#output_directory = amass\n\n# Another location (directory) where the user can provide ADS scripts to the engine.\n#scripts_directory = \n\n# The maximum number of DNS queries that can be performed concurrently during the enumeration.\n#maximum_dns_queries = 20000\n\n# DNS resolvers used globally by the amass package.\n#[resolvers]\n#resolver = 1.1.1.1 ; Cloudflare\n#resolver = 8.8.8.8 ; Google\n#resolver = 64.6.64.6 ; Verisign\n#resolver = 74.82.42.42 ; Hurricane Electric\n#resolver = 1.0.0.1 ; Cloudflare Secondary\n#resolver = 8.8.4.4 ; Google Secondary\n#resolver = 64.6.65.6 ; Verisign Secondary\n#resolver = 77.88.8.8 ; Yandex.DNS Secondary\n\n[scope]\n# The network infrastructure settings expand scope, not restrict the scope.\n# Single IP address or range (e.g. a.b.c.10-245)\n#address = 192.168.1.1\n#cidr = 192.168.1.0/24\n#asn = 26808\nport = 80\nport = 443\n#port = 8080\n#port = 8443\n\n# Root domain names used in the enumeration. The findings are limited by the root domain names provided.\n#[scope.domains]\n#domain = owasp.org\n#domain = appsecusa.org\n#domain = appsec.eu\n#domain = appsec-labs.com\n\n# Are there any subdomains that are out of scope?\n#[scope.blacklisted]\n#subdomain = education.appsec-labs.com\n#subdomain = 2012.appsecusa.org\n\n# The graph database discovered DNS names, associated network infrastructure, results from data sources, etc.\n# This information is then used in future enumerations and analysis of the discoveries.\n#[graphdbs]\n# postgres://[username:password@]host[:port]/database-name?sslmode=disable of the PostgreSQL \n# database and credentials. Sslmode is optional, and can be disable, require, verify-ca, or verify-full.\n#[graphdbs.postgres]\n#primary = false ; Specify which graph database is the primary db, or the local database will be selected.\n#url = \"postgres://[username:password@]host[:port]/database-name?sslmode=disable\"\n#options=\"connect_timeout=10\"\n\n# MqSQL database and credentials URL format:\n# [username:password@]tcp(host[:3306])/database-name?timeout=10s\n#[graphdbs.mysql]\n#url = [username:password@]tcp(host[:3306])/database-name?timeout=10s\n\n# Settings related to DNS name brute forcing.\n#[bruteforce]\n#enabled = true\n#recursive = true\n# Number of discoveries made in a subdomain before performing recursive brute forcing: Default is 1.\n#minimum_for_recursive = 1\n#wordlist_file = /usr/share/wordlists/all.txt\n#wordlist_file = /usr/share/wordlists/all.txt # multiple lists can be used\n\n# Would you like to permute resolved names?\n#[alterations]\n#enabled = true\n# edit_distance specifies the number of times a primitive edit operation will be\n# performed on a name sample during fuzzy label searching.\n#edit_distance = 1 ; Setting this to zero will disable this expensive feature.\n#flip_words = true # test-dev.owasp.org -> test-prod.owasp.org\n#flip_numbers = true # test1.owasp.org -> test2.owasp.org\n#add_words = true # test.owasp.org -> test-dev.owasp.org\n#add_numbers = true # test.owasp.org -> test1.owasp.org\n# Multiple lists can be used.\n#wordlist_file = /usr/share/wordlists/all.txt\n#wordlist_file = /usr/share/wordlists/all.txt\n\n[data_sources]\n# When set, this time-to-live is the minimum value applied to all data source caching.\nminimum_ttl = 1440 ; One day\n\n# Are there any data sources that should be disabled?\n#[data_sources.disabled]\n#data_source = Ask\n#data_source = Bing\n\n# Provide data source configuration information.\n# See the following format:\n#[data_sources.SOURCENAME] ; The SOURCENAME must match the name in the data source implementation.\n#ttl = 4320 ; Time-to-live value sets the number of minutes that the responses are cached.\n# Unique identifier for this set of SOURCENAME credentials.\n# Multiple sets of credentials can be provided and will be randomly selected.\n#[data_sources.SOURCENAME.CredentialSetID]\n#apikey = ; Each data source uses potentially different keys for authentication.\n#secret = ; See the examples below for each data source.\n#username =\n#password =\n\n# https://passivedns.cn (Contact)\n#[data_sources.360PassiveDNS]\n#[data_sources.360PassiveDNS.Credentials]\n#apikey =\n\n# https://ahrefs.com (Paid)\n#[data_sources.Ahrefs]\n#ttl = 4320\n#[data_sources.Ahrefs.Credentials]\n#apikey =\n\n# https://otx.alienvault.com (Free)\n#[data_sources.AlienVault]\n#[data_sources.AlienVault.Credentials]\n#apikey =\n\n# https://app.binaryedge.com (Paid/Free-trial)\n#[data_sources.BinaryEdge]\n#ttl = 10080\n#[data_sources.BinaryEdge.Credentials]\n#apikey =\n\n# https://tls.bufferover.run/dns?q=.example.com (Paid/Free)\n#[data_sources.BufferOver]\n#[data_sources.BufferOver.Credentials]\n#apikey =\n\n# https://builtwith.com (Paid/Free-trial)\n#[data_sources.BuiltWith]\n#ttl = 10080\n#[data_sources.BuiltWith.Credentials]\n#apikey =\n\n# https://c99.nl (Paid)\n#[data_sources.C99]\n#ttl = 4320\n#[data_sources.C99.account1]\n#apikey =\n#[data_sources.C99.account2]\n#apikey =\n\n# https://censys.io (Paid/Free-trial)\n#[data_sources.Censys]\n#ttl = 10080\n#[data_sources.Censys.Credentials]\n#apikey =\n#secret =\n\n# https://chaos.projectdiscovery.io (Invite-Only)\n#[data_sources.Chaos]\n#ttl = 4320\n#[data_sources.Chaos.Credentials]\n#apikey =\n\n# https://cloudflare.com (Free)\n# Cloudflare apikey is the API token with dns_records and zone read permission\n#[data_sources.Cloudflare]\n#[data_sources.Cloudflare.Credentials]\n#apikey =\n\n# https://circl.lu (Contact)\n#[data_sources.CIRCL]\n#[data_sources.CIRCL.Credentials]\n#username =\n#password =\n\n# https://dnsdb.info (Paid)\n#[data_sources.DNSDB]\n#ttl = 4320\n#[data_sources.DNSDB.Credentials]\n#apikey =\n\n# https://dnslytics.com (Paid)\n#[data_sources.DNSlytics]\n#[data_sources.DNSlytics.Credentials]\n#apikey =\n\n# https://dnsrepo.noc.org (Paid)\n#[data_sources.DNSRepo]\n#[data_sources.DNSRepo.Credentials]\n#apikey =\n\n# https://detectify.com (Paid)\n#[data_sources.Detectify]\n#[data_sources.Detectify.Credentials]\n#apikey =\n\n# https://developer.facebook.com (Free)\n# Look here for how to obtain the Facebook credentials:\n# https://goldplugins.com/documentation/wp-social-pro-documentation/how-to-get-an-app-id-and-secret-key-from-facebook/\n#[data_sources.FacebookCT]\n#ttl = 4320\n#[data_sources.FacebookCT.app1]\n#apikey =\n#secret =\n#[data_sources.FacebookCT.app2]\n#apikey =\n#secret =\n\n# https://fofa.so (Paid)\n#[data_sources.FOFA]\n#ttl = 10080\n#[data_sources.FOFA.Credentials]\n#username =\n#apikey =\n\n# https://github.com (Free)\n#[data_sources.GitHub]\n#ttl = 4320\n#[data_sources.GitHub.accountname]\n#apikey =\n\n# https://gitlab.com (Freemium)\n#[data_sources.GitLab]\n#[data_sources.GitLab.free]\n#apikey =\n#[data_sources.GitLab.premium]\n#apikey =\n\n# https://hackertarget.com (Paid/Free)\n# HackerTarget can be used without an API key, but the key allows better results\n#[data_sources.HackerTarget]\n#ttl = 1440\n#[data_sources.HackerTarget.Credentials]\n#apikey =\n\n# https://hunter.io (Paid/Free-trial)\n#[data_sources.Hunter]\n#[data_sources.Hunter.Credentials]\n#apikey =\n\n#[data_sources.IntelX]\n#[data_sources.IntelX.Credentials]\n#apikey =\n\n# https://ipdata.co (Free)\n#[data_sources.IPdata]\n#[data_sources.IPdata.Credentials]\n#apikey =\n\n# https://ipinfo.io (Paid/Free-trial)\n#[data_sources.IPinfo]\n#[data_sources.IPinfo.Credentials]\n#apikey =\n\n# https://leakix.net/ (Free)\n#[data_sources.LeakIX]\n#[data_sources.LeakIX.Credentials]\n#apikey = \n\n# https://networksdb.io (Paid/Free-trial)\n#[data_sources.NetworksDB]\n#[data_sources.NetworksDB.Credentials]\n#apikey =\n\n# https://onyphe.io (Free)\n#[data_sources.ONYPHE]\n#ttl = 10080\n#[data_sources.ONYPHE.Credentials]\n#apikey =\n\n# https://passivetotal.com (Paid/Free-trial)\n#[data_sources.PassiveTotal]\n#ttl = 10080\n#[data_sources.PassiveTotal.Credentials]\n#username =\n#apikey =\n\n# https://pentest-tools.com (Paid)\n#[data_sources.PentestTools]\n#ttl = 10080\n#[data_sources.PentestTools.Credentials]\n#apikey =\n\n# https://quake.360.cn (Paid)\n#[data_sources.Quake]\n#ttl = 4320\n#[data_sources.Quake.Credentials]\n#apikey =\n\n# https://securitytrails.com (Paid/Free-trial)\n#[data_sources.SecurityTrails]\n#ttl = 1440\n#[data_sources.SecurityTrails.Credentials]\n#apikey =\n\n# https://shodan.io (Paid/Free-trial)\n#[data_sources.Shodan]\n#ttl = 10080\n#[data_sources.Shodan.Credentials]\n#apikey =\n\n# https://spamhaus.com (Free)\n#[data_sources.Spamhaus]\n#ttl = 1440\n#[data_sources.Spamhaus.Credentials]\n#username =\n#password =\n\n# https://spyse.com (Paid/Free-trial)\n#[data_sources.Spyse]\n#ttl = 4320\n#[data_sources.Spyse.Credentials]\n#apikey =\n\n# https://threatbook.cn (Paid)\n#[data_sources.ThreatBook]\n#[data_sources.ThreatBook.account1]\n#apikey=\n\n# https://developer.twitter.com (Free)\n# Provide your Twitter App Consumer API key and Consumer API secret key\n#[data_sources.Twitter]\n#[data_sources.Twitter.account1]\n#apikey =\n#secret =\n#[data_sources.Twitter.account2]\n#apikey =\n#secret =\n\n# https://umbrella.cisco.com (Paid-Enterprise)\n# The apikey must be an API access token created through the Investigate management UI\n#[data_sources.Umbrella]\n#[data_sources.Umbrella.Credentials]\n#apikey =\n\n# https://urlscan.io (Paid/Free-trial)\n# URLScan can be used without an API key, but the key allows new submissions to be made\n#[data_sources.URLScan]\n#[data_sources.URLScan.Credentials]\n#apikey =\n\n# https://virustotal.com (Paid/Free-trial)\n#[data_sources.VirusTotal]\n#ttl = 10080\n#[data_sources.VirusTotal.Credentials]\n#apikey =\n\n# https://whoisxmlapi.com (Paid/Free-trial)\n#[data_sources.WhoisXMLAPI]\n#[data_sources.WhoisXMLAPI.Credentials]\n#apikey = \n\n# https://zetalytics.com (Paid/Invite-Only)\n#[data_sources.ZETAlytics]\n#ttl = 1440\n#[data_sources.ZETAlytics.Credentials]\n#apikey =\n\n#[data_sources.ZoomEye]\n#ttl = 1440\n#[data_sources.ZoomEye.Credentials]\n#username = \n#password = " - kind: ConfigMap - metadata: - name: amass-config diff --git a/scanners/amass/tests/scanner_test.yaml b/scanners/amass/tests/scanner_test.yaml deleted file mode 100644 index c5b3b49c3a..0000000000 --- a/scanners/amass/tests/scanner_test.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -suite: Full Snapshot - -tests: - - it: matches the snapshot - chart: - version: 0.0.0 - appVersion: 0.0.0 - set: - cascadingRules.enabled: true - imagePullSecrets: [{name: foo}] - parser: - env: [{name: foo, value: bar}] - scopeLimiterAliases: {foo: bar} - affinity: {foo: bar} - tolerations: [{foo: bar}] - resources: {foo: bar} - scanner: - nameAppend: foo - resources: {foo: bar} - env: [{name: foo, value: bar}] - extraContainers: [{name: foo, image: bar}] - podSecurityContext: {fsGroup: 1234} - affinity: {foo: bar} - tolerations: [{foo: bar}] - asserts: - - matchSnapshot: {} diff --git a/scanners/cmseek/.helm-docs.gotmpl b/scanners/cmseek/.helm-docs.gotmpl deleted file mode 100644 index 98e6410b35..0000000000 --- a/scanners/cmseek/.helm-docs.gotmpl +++ /dev/null @@ -1,54 +0,0 @@ -{{- /* -SPDX-FileCopyrightText: the secureCodeBox authors - -SPDX-License-Identifier: Apache-2.0 -*/ -}} - -{{- define "extra.docsSection" -}} ---- -title: "CMSeeK" -category: "scanner" -type: "CMS" -state: "released" -appVersion: "{{ template "chart.appVersion" . }}" -usecase: "Automation of the process of detecting the Joomla CMS and its core vulnerabilities" ---- -{{- end }} - -{{- define "extra.dockerDeploymentSection" -}} -## Supported Tags -- `latest` (represents the latest stable release build) -- tagged releases, e.g. `{{ template "chart.appVersion" . }}` -{{- end }} - -{{- define "extra.chartAboutSection" -}} -## What is CMSeeK? -CMSeeK is an open source penetration testing tool to automate the process of detecting various types of CMS and its installed extensions. -Only the Joomla CMS is supported by secureCodeBox. CMSeeK has a database with known vulnerabilities. - -To learn more about the CMSeeK scanner itself, visit the CMSeeK GitHub repository [here](https://github.com/Tuhinshubhra/CMSeeK). -{{- end }} - -{{- define "extra.scannerConfigurationSection" -}} -## Scanner Configuration - -The CMSeeK targets are specified with the `-u` parameter. The target should be a URL. - -Additional CMSeeK scan features can be configured via the parameter attribute. - -Some useful example parameters listed below: - -- `-u URL, --url URL` : Target Url. -- `--follow-redirect` : Follows all/any redirect(s). -- `--no-redirect` : skips all redirects and tests the input target(s) -- `-r, --random-agent`: Use a random user agent. -- `--googlebot`: Use Google bot user agent. -- `--user-agent USER_AGENT`: Specify a custom user agent - -{{- end }} - -{{- define "extra.chartConfigurationSection" -}} -{{- end }} - -{{- define "extra.scannerLinksSection" -}} -{{- end }} \ No newline at end of file diff --git a/scanners/cmseek/.helmignore b/scanners/cmseek/.helmignore deleted file mode 100644 index 1b2144b9bb..0000000000 --- a/scanners/cmseek/.helmignore +++ /dev/null @@ -1,40 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ -# Node.js files -node_modules/* -package.json -package-lock.json -src/* -config/* -Dockerfile -.dockerignore -*.tar -parser/* -scanner/* -integration-tests/* -examples/* -docs/* -Makefile diff --git a/scanners/cmseek/Taskfile.yaml b/scanners/cmseek/Taskfile.yaml deleted file mode 100644 index eba6d685de..0000000000 --- a/scanners/cmseek/Taskfile.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -version: "3.44.0" - -includes: - scanner: - taskfile: ../Taskfile.yaml - flatten: true - excludes: - - predeploy - vars: - scannerName: cmseek - -tasks: - predeploy: - deps: - - demo-targets:deploy:old-joomla - cmds: [] diff --git a/scanners/cmseek/cascading-rules/scan-joomla.yaml b/scanners/cmseek/cascading-rules/scan-joomla.yaml deleted file mode 100644 index 09756f2745..0000000000 --- a/scanners/cmseek/cascading-rules/scan-joomla.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -apiVersion: "cascading.securecodebox.io/v1" -kind: CascadingRule -metadata: - name: "cmseek-cascade" - labels: - securecodebox.io/invasive: non-invasive - securecodebox.io/intensive: medium -spec: - matches: - anyOf: - - category: "WEB APPLICATION" - attributes: - MetaGenerator: "Joomla! - Open Source Content Management" - scanSpec: - scanType: "cmseek" - parameters: - - "-u" - - "{{{location}}}" # Runs a cmseek scan upon the 'location' parameter in whatweb findings diff --git a/scanners/cmseek/examples/demo-old-joomla/findings.yaml b/scanners/cmseek/examples/demo-old-joomla/findings.yaml deleted file mode 100644 index 012ac46eb9..0000000000 --- a/scanners/cmseek/examples/demo-old-joomla/findings.yaml +++ /dev/null @@ -1,61 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -[ - { - "name": "PHPMailer Remote Code Execution Vulnerability", - "description": "Vulnerability of type PHPMailer Remote Code Execution Vulnerability found", - "category": "Vulnerability", - "location": "http://old-joomla.demo-targets.svc.cluster.local", - "osi_layer": "APPLICATION", - "severity": "HIGH", - "attributes": - { - "joomla_version": "3.6.5", - "references": - [ - "CVE : CVE-2016-10033", - "https://www.rapid7.com/db/modules/exploit/multi/http/phpmailer_arg_injection", - "https://github.com/opsxcq/exploit-CVE-2016-10033", - "EDB : https://www.exploit-db.com/exploits/40969/", - ], - }, - "id": "f41eeb1c-142e-46f2-96ae-01c9f7ca1aa7", - "parsed_at": "2021-09-28T15:06:29.225Z", - }, - { - "name": "PPHPMailer Incomplete Fix Remote Code Execution Vulnerability", - "description": "Vulnerability of type PPHPMailer Incomplete Fix Remote Code Execution Vulnerability found", - "category": "Vulnerability", - "location": "http://old-joomla.demo-targets.svc.cluster.local", - "osi_layer": "APPLICATION", - "severity": "HIGH", - "attributes": - { - "joomla_version": "3.6.5", - "references": - [ - "CVE : CVE-2016-10045", - "https://www.rapid7.com/db/modules/exploit/multi/http/phpmailer_arg_injection", - "EDB : https://www.exploit-db.com/exploits/40969/", - ], - }, - "id": "ef8852d1-719b-4a4d-8cd6-d818fffb6fd2", - "parsed_at": "2021-09-28T15:06:29.225Z", - }, - { - "name": "Backup files", - "description": "Visible Backup files found", - "category": "Visible internal files", - "location": "http://old-joomla.demo-targets.svc.cluster.local", - "osi_layer": "APPLICATION", - "severity": "INFORMATIONAL", - "attributes": - { - "joomla_backup_files": "http://old-joomla.demo-targets.svc.cluster.local/administrator,", - }, - "id": "021b92a7-0c24-4f3c-b4b9-217e3a2e1ce9", - "parsed_at": "2021-09-28T15:06:29.225Z", - }, -] diff --git a/scanners/cmseek/examples/demo-old-joomla/scan.yaml b/scanners/cmseek/examples/demo-old-joomla/scan.yaml deleted file mode 100644 index e797910e78..0000000000 --- a/scanners/cmseek/examples/demo-old-joomla/scan.yaml +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -apiVersion: "execution.securecodebox.io/v1" -kind: Scan -metadata: - name: cmseek-example -spec: - scanType: "cmseek" - parameters: - - "-u" - - "old-joomla.demo-targets.svc.cluster.local" # Change to the website you want to scan - - "--no-redirect" diff --git a/scanners/cmseek/integration-tests/cmseek.test.js b/scanners/cmseek/integration-tests/cmseek.test.js deleted file mode 100644 index e56b2dbf21..0000000000 --- a/scanners/cmseek/integration-tests/cmseek.test.js +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-FileCopyrightText: the secureCodeBox authors -// -// SPDX-License-Identifier: Apache-2.0 - -import { scan } from "../../../tests/integration/helpers.js"; - -test.skip( - "cmseek scans old-joomla for vulnerabilities without redirection", - async () => { - const { categories, severities, count } = await scan( - "cmseek-old-joomla", - "cmseek", - ["-u", "old-joomla.demo-targets.svc", "--no-redirect"], - 90, - ); - - expect(count).toBe(3); - expect(categories).toMatchInlineSnapshot(` - { - "Visible internal files": 1, - "Vulnerability": 2, - } - `); - expect(severities).toMatchInlineSnapshot(` - { - "high": 2, - "informational": 1, - } - `); - }, - { - timeout: 3 * 60 * 1000, - }, -); - -test.skip( - "cmseek scans old-joomla for vulnerabilities with redirection", - async () => { - const { categories, severities, count } = await scan( - "cmseek-old-joomla", - "cmseek", - ["-u", "old-joomla.demo-targets.svc", "--follow-redirect"], - 90, - ); - - expect(count).toBe(1); - expect(categories).toMatchInlineSnapshot(` - { - "Visible internal files": 1, - } - `); - expect(severities).toMatchInlineSnapshot(` - { - "informational": 1, - } - `); - }, - { - timeout: 3 * 60 * 1000, - }, -); - -test( - "Invalid argument should be marked as errored", - async () => { - await expect( - scan("cmseek-invalid-arg", "cmseek", ["--invalidArg", "example.com"], 90), - ).rejects.toThrow( - 'Scan failed with description "Failed to run the Scan Container, check k8s Job and its logs for more details"', - ); - }, - { - timeout: 3 * 60 * 1000, - }, -); diff --git a/scanners/cmseek/parser/__snapshots__/parser.test.js.snap b/scanners/cmseek/parser/__snapshots__/parser.test.js.snap deleted file mode 100644 index 61f924ef20..0000000000 --- a/scanners/cmseek/parser/__snapshots__/parser.test.js.snap +++ /dev/null @@ -1,157 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`parser parses result of Joomla scan with core vulnerabilities successfully 1`] = ` -[ - { - "attributes": { - "joomla_version": "3.6.5", - "references": [ - "CVE : CVE-2016-10033", - "https://www.rapid7.com/db/modules/exploit/multi/http/phpmailer_arg_injection", - "https://github.com/opsxcq/exploit-CVE-2016-10033", - "EDB : https://www.exploit-db.com/exploits/40969/", - ], - }, - "category": "Vulnerability", - "description": "Vulnerability of type PHPMailer Remote Code Execution Vulnerability found", - "identified_at": "2021-09-22T10:29:01.721Z", - "location": "http://172.26.0.3/", - "name": "PHPMailer Remote Code Execution Vulnerability", - "osi_layer": "APPLICATION", - "references": [ - { - "type": "URL", - "value": "https://www.rapid7.com/db/modules/exploit/multi/http/phpmailer_arg_injection", - }, - { - "type": "URL", - "value": "https://github.com/opsxcq/exploit-CVE-2016-10033", - }, - { - "type": "URL", - "value": "https://www.exploit-db.com/exploits/40969/", - }, - { - "type": "CVE", - "value": "CVE-2016-10033", - }, - { - "type": "URL", - "value": "https://www.cve.org/CVERecord?id=CVE-2016-10033", - }, - ], - "severity": "HIGH", - }, - { - "attributes": { - "joomla_version": "3.6.5", - "references": [ - "CVE : CVE-2016-10045", - "https://www.rapid7.com/db/modules/exploit/multi/http/phpmailer_arg_injection", - "EDB : https://www.exploit-db.com/exploits/40969/", - ], - }, - "category": "Vulnerability", - "description": "Vulnerability of type PPHPMailer Incomplete Fix Remote Code Execution Vulnerability found", - "identified_at": "2021-09-22T10:29:01.721Z", - "location": "http://172.26.0.3/", - "name": "PPHPMailer Incomplete Fix Remote Code Execution Vulnerability", - "osi_layer": "APPLICATION", - "references": [ - { - "type": "URL", - "value": "https://www.rapid7.com/db/modules/exploit/multi/http/phpmailer_arg_injection", - }, - { - "type": "URL", - "value": "https://www.exploit-db.com/exploits/40969/", - }, - { - "type": "CVE", - "value": "CVE-2016-10045", - }, - { - "type": "URL", - "value": "https://www.cve.org/CVERecord?id=CVE-2016-10045", - }, - ], - "severity": "HIGH", - }, - { - "attributes": { - "joomla_version": "3.6.5", - "references": [ - "https://www.rapid7.com/db/modules/exploit/multi/http/phpmailer_arg_injection", - "EDB : https://www.exploit-db.com/exploits/40969/", - ], - }, - "category": "Vulnerability", - "description": "Vulnerability of type PPHPMailer Incomplete Fix Remote Code Execution Vulnerability **without CVE** found", - "identified_at": "2021-09-22T10:29:01.721Z", - "location": "http://172.26.0.3/", - "name": "PPHPMailer Incomplete Fix Remote Code Execution Vulnerability **without CVE**", - "osi_layer": "APPLICATION", - "references": [ - { - "type": "URL", - "value": "https://www.rapid7.com/db/modules/exploit/multi/http/phpmailer_arg_injection", - }, - { - "type": "URL", - "value": "https://www.exploit-db.com/exploits/40969/", - }, - ], - "severity": "HIGH", - }, - { - "attributes": { - "joomla_version": "3.6.5", - "references": [], - }, - "category": "Vulnerability", - "description": "Vulnerability of type PPHPMailer Incomplete Fix Remote Code Execution Vulnerability **without references** found", - "identified_at": "2021-09-22T10:29:01.721Z", - "location": "http://172.26.0.3/", - "name": "PPHPMailer Incomplete Fix Remote Code Execution Vulnerability **without references**", - "osi_layer": "APPLICATION", - "references": null, - "severity": "HIGH", - }, - { - "attributes": { - "joomla_backup_files": [ - "http://172.26.0.3/1.save", - "http://172.26.0.3/1.tar.gz", - "http://172.26.0.3/1.rar", - "http://172.26.0.3/1.tar", - "http://172.26.0.3/1.zip", - "http://172.26.0.3/1.txt", - "http://172.26.0.3/1.tgz", - "http://172.26.0.3/1.tar.bz2", - "http://172.26.0.3/1.gz", - "http://172.26.0.3/1.tmp", - ], - }, - "category": "Visible internal files", - "description": "Visible Backup files found", - "identified_at": "2021-09-22T10:29:01.721Z", - "location": "http://172.26.0.3/", - "name": "Backup files", - "osi_layer": "APPLICATION", - "severity": "INFORMATIONAL", - }, - { - "category": "Security Misconfiguration", - "description": "Debug mode is enabled on the site", - "identified_at": "2021-09-22T10:29:01.721Z", - "location": "http://172.26.0.3/", - "name": "Debug mode", - "osi_layer": "APPLICATION", - "severity": "MEDIUM", - }, -] -`; - -exports[`parser parses result of Joomla scan without core vulnerabilities successfully 1`] = `[]`; - -exports[`parser parses result of non-Joomla scan successfully 1`] = `[]`; diff --git a/scanners/cmseek/parser/__testFiles__/joomla_with_core_vulns.json b/scanners/cmseek/parser/__testFiles__/joomla_with_core_vulns.json deleted file mode 100644 index f0bf5c71b1..0000000000 --- a/scanners/cmseek/parser/__testFiles__/joomla_with_core_vulns.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "cms_id": "joom", - "cms_name": "joomla", - "cms_url": "https://joomla.org", - "detection_param": "header", - "joomla_backup_files": [ - "http://172.26.0.3/1.save", - "http://172.26.0.3/1.tar.gz", - "http://172.26.0.3/1.rar", - "http://172.26.0.3/1.tar", - "http://172.26.0.3/1.zip", - "http://172.26.0.3/1.txt", - "http://172.26.0.3/1.tgz", - "http://172.26.0.3/1.tar.bz2", - "http://172.26.0.3/1.gz", - "http://172.26.0.3/1.tmp" - ], - "joomla_debug_mode": "enabled", - "joomla_readme_file": "http://172.26.0.3/README.txt", - "joomla_version": "3.6.5", - "last_scanned": "2021-09-22 10:29:01.721009", - "url": "http://172.26.0.3/", - "vulnerabilities": [ - { - "name": "PHPMailer Remote Code Execution Vulnerability", - "references": [ - "CVE : CVE-2016-10033", - "https://www.rapid7.com/db/modules/exploit/multi/http/phpmailer_arg_injection", - "https://github.com/opsxcq/exploit-CVE-2016-10033", - "EDB : https://www.exploit-db.com/exploits/40969/" - ] - }, - { - "name": "PPHPMailer Incomplete Fix Remote Code Execution Vulnerability", - "references": [ - "CVE : CVE-2016-10045", - "https://www.rapid7.com/db/modules/exploit/multi/http/phpmailer_arg_injection", - "EDB : https://www.exploit-db.com/exploits/40969/" - ] - }, - { - "name": "PPHPMailer Incomplete Fix Remote Code Execution Vulnerability **without CVE**", - "references": [ - "https://www.rapid7.com/db/modules/exploit/multi/http/phpmailer_arg_injection", - "EDB : https://www.exploit-db.com/exploits/40969/" - ] - }, - { - "name": "PPHPMailer Incomplete Fix Remote Code Execution Vulnerability **without references**", - "references": [ - ] - } - - ], - "vulnerabilities_count": "4" -} \ No newline at end of file diff --git a/scanners/cmseek/parser/__testFiles__/joomla_without_core_vulns.json b/scanners/cmseek/parser/__testFiles__/joomla_without_core_vulns.json deleted file mode 100644 index 045b098180..0000000000 --- a/scanners/cmseek/parser/__testFiles__/joomla_without_core_vulns.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "cms_id": "joom", - "cms_name": "joomla", - "cms_url": "https://joomla.org", - "detection_param": "header", - "joomla_debug_mode": "disabled", - "last_scanned": "2021-09-21 15:12:44.412355", - "url": "http://172.26.0.3/", - "vulnerabilities_count": "0" -} \ No newline at end of file diff --git a/scanners/cmseek/parser/__testFiles__/joomla_without_core_vulns.json.license b/scanners/cmseek/parser/__testFiles__/joomla_without_core_vulns.json.license deleted file mode 100644 index 3034c0d74b..0000000000 --- a/scanners/cmseek/parser/__testFiles__/joomla_without_core_vulns.json.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: the secureCodeBox authors - -SPDX-License-Identifier: Apache-2.0 \ No newline at end of file diff --git a/scanners/cmseek/parser/__testFiles__/not_joomla.json b/scanners/cmseek/parser/__testFiles__/not_joomla.json deleted file mode 100644 index 9ecbd39f2a..0000000000 --- a/scanners/cmseek/parser/__testFiles__/not_joomla.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "cms_id": "dru", - "cms_name": "Drupal", - "cms_url": "https://drupal.org", - "detection_param": "header", - "last_scanned": "2021-09-21 15:12:20.871380", - "url": "http://172.26.0.3/" -} \ No newline at end of file diff --git a/scanners/cmseek/parser/__testFiles__/not_joomla.json.license b/scanners/cmseek/parser/__testFiles__/not_joomla.json.license deleted file mode 100644 index 3034c0d74b..0000000000 --- a/scanners/cmseek/parser/__testFiles__/not_joomla.json.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: the secureCodeBox authors - -SPDX-License-Identifier: Apache-2.0 \ No newline at end of file diff --git a/scanners/cmseek/parser/__testFiles__/test-empty-report.json b/scanners/cmseek/parser/__testFiles__/test-empty-report.json deleted file mode 100644 index fe51488c70..0000000000 --- a/scanners/cmseek/parser/__testFiles__/test-empty-report.json +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/scanners/cmseek/parser/parser.js b/scanners/cmseek/parser/parser.js deleted file mode 100644 index efc01ae239..0000000000 --- a/scanners/cmseek/parser/parser.js +++ /dev/null @@ -1,111 +0,0 @@ -// SPDX-FileCopyrightText: the secureCodeBox authors -// -// SPDX-License-Identifier: Apache-2.0 - -export async function parse(findings) { - let results = []; - // Making sure the CMS is Joomla - if (findings.cms_id != "joom") { - return results; - } - // Check if debug mode is enabled ; if yes add finding - let parsed_debug_mode_enabled = []; - - // I ran into an issue where the time coverted to ISO String was dependant from the timezone of the machine running the test. - // This means that if GitHub Actions CI time and local time are different the test will fail. - // To fix this we need to enforce the timezone in the date string. - // cmseek uses the timezone of the machine running the scan, so it will be different machine to machine (or cloud service). - // https://github.com/Tuhinshubhra/CMSeeK/blob/ce085fee1b5f48db7412911e399bb2c771e73a0f/cmseekdb/basic.py#L296 - // For simplicity UTC time is enforced, and that is by adding a Z to the end of the date string. - const last_scanned = new Date(findings.last_scanned + "Z").toISOString(); - if (findings.joomla_debug_mode == "enabled") { - parsed_debug_mode_enabled = { - name: "Debug mode", - identified_at: last_scanned, - description: `Debug mode is enabled on the site`, - category: "Security Misconfiguration", - location: findings.url, - osi_layer: "APPLICATION", - severity: "MEDIUM", - }; - } - - // Check if backup files are open; if yes add finding - let parsed_backupFiles = []; - if ("joomla_backup_files" in findings) { - parsed_backupFiles = { - name: "Backup files", - identified_at: last_scanned, - description: `Visible Backup files found`, - category: "Visible internal files", - location: findings.url, - osi_layer: "APPLICATION", - severity: "INFORMATIONAL", - attributes: { - joomla_backup_files: findings.joomla_backup_files, - }, - }; - } - // Check if any core vulnerabilities exist; if yes list findings - let parsed_vulnerabilities = []; - if (findings.vulnerabilities_count > 0) { - parsed_vulnerabilities = findings.vulnerabilities.map((vuln) => { - // Fetch CVE from vulnerability references - const cve = fetchCVE(vuln.references); - const separator = " : "; - - // Create CVE reference object if CVE exists - const cve_reference = cve - ? [ - { type: "CVE", value: cve }, - { type: "URL", value: `https://www.cve.org/CVERecord?id=${cve}` }, - ] - : []; // Empty array if no CVE exists - - // Create URL reference objects from the vulnerability references - const urls_references = vuln.references - .filter((ref) => ref.includes("http")) - .map((ref) => ({ - type: "URL", - // Extract the URL if the reference includes the separator, otherwise use the whole reference - value: ref.includes(separator) ? ref.split(separator)[1].trim() : ref, - })); - - // Combine URL and CVE references, and filter out any empty reference - const references = [...urls_references, ...cve_reference].filter( - (r) => r, - ); - - // Return the parsed vulnerability object - return { - name: vuln.name, - identified_at: last_scanned, - description: `Vulnerability of type ${vuln.name} found`, - category: "Vulnerability", - location: findings.url, - osi_layer: "APPLICATION", - severity: "HIGH", - references: references.length > 0 ? references : null, - attributes: { - joomla_version: findings.joomla_version, - references: vuln.references, - }, - }; - }); - } - // concat all parsed results - return parsed_vulnerabilities - .concat(parsed_backupFiles) - .concat(parsed_debug_mode_enabled); -} -// Helper function to fetch CVE from references -// it is assumed that the reference is in the format "CVE : CVE-XXXX-XXXX" -function fetchCVE(references) { - for (const reference of references) { - if (reference.includes("CVE :")) { - const cve = reference.split("CVE : ")[1].trim(); - return cve; - } - } - return null; -} diff --git a/scanners/cmseek/parser/parser.test.js b/scanners/cmseek/parser/parser.test.js deleted file mode 100644 index 0fdfb29448..0000000000 --- a/scanners/cmseek/parser/parser.test.js +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-FileCopyrightText: the secureCodeBox authors -// -// SPDX-License-Identifier: Apache-2.0 - -import { readFile } from "fs/promises"; - -import { parse } from "./parser"; - -import { validateParser } from "@securecodebox/parser-sdk-nodejs/parser-utils"; - -test("parser parses result of Joomla scan with core vulnerabilities successfully", async () => { - const fileContent = await readFile( - import.meta.dirname + "/__testFiles__/joomla_with_core_vulns.json", - { - encoding: "utf8", - }, - ); - - const findings = await parse(JSON.parse(fileContent)); - await expect(validateParser(findings)).resolves.toBeUndefined(); - expect(findings).toMatchSnapshot(); -}); - -test("parser parses result of Joomla scan without core vulnerabilities successfully", async () => { - const fileContent = await readFile( - import.meta.dirname + "/__testFiles__/joomla_without_core_vulns.json", - { - encoding: "utf8", - }, - ); - - const findings = await parse(JSON.parse(fileContent)); - await expect(validateParser(findings)).resolves.toBeUndefined(); - expect(findings).toMatchSnapshot(); -}); - -test("parser parses result of non-Joomla scan successfully", async () => { - const fileContent = await readFile( - import.meta.dirname + "/__testFiles__/not_joomla.json", - { - encoding: "utf8", - }, - ); - - const findings = await parse(JSON.parse(fileContent)); - await expect(validateParser(findings)).resolves.toBeUndefined(); - expect(findings).toMatchSnapshot(); -}); - -test("should properly parse empty cmseek json file", async () => { - const jsonContent = await readFile( - import.meta.dirname + "/__testFiles__/test-empty-report.json", - { - encoding: "utf8", - }, - ); - const findings = await parse(jsonContent); - await expect(validateParser(findings)).resolves.toBeUndefined(); - expect(findings).toMatchInlineSnapshot(`[]`); -}); diff --git a/scanners/cmseek/scanner/Dockerfile b/scanners/cmseek/scanner/Dockerfile deleted file mode 100644 index 9c7ed5b9ae..0000000000 --- a/scanners/cmseek/scanner/Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -# Base Image -FROM python:3.9-alpine AS base -ARG scannerVersion -# Install git and Clone Repo -RUN apk add git \ - && git clone https://github.com/Tuhinshubhra/CMSeeK.git --depth 1 --branch $scannerVersion \ - && cd CMSeeK \ - && rm -r .git - -# Runtime Image -FROM python:3.9-alpine AS runtime - -# Create cmseek user/group and give access -RUN addgroup --system --gid 1001 cmseek && adduser cmseek --system --uid 1001 --ingroup cmseek -COPY --from=base --chown=1001:1001 /CMSeeK /home/cmseek/ -COPY --chown=1001:1001 wrapper.sh /home/cmseek/ - -# Create folder for scan output -RUN mkdir /home/securecodebox/ && chown -R cmseek:cmseek /home/securecodebox/ - -# Switch to cmseek user -USER 1001 -WORKDIR /home/cmseek/ - -# Create folder required by the scanner -RUN mkdir /home/cmseek/Result - -# Install cmseek python requirements -RUN python3 -m pip install -r requirements.txt - -ENTRYPOINT [ "sh", "/home/cmseek/wrapper.sh" ] diff --git a/scanners/cmseek/scanner/wrapper.sh b/scanners/cmseek/scanner/wrapper.sh deleted file mode 100644 index 9f6789b9a1..0000000000 --- a/scanners/cmseek/scanner/wrapper.sh +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -python3 /home/cmseek/cmseek.py "$@" - -# Find how many files with the JSON extension in Result folder are. -lines=$(find /home/cmseek/Result/ -type f -name "*.json" | wc -l) - -#The cmseek scanner names the folder where the result is, the target url. That is why it's replaced with a wildcard here. -if [ $lines -eq 1 ]; then - mv /home/cmseek/Result/*/cms.json /home/securecodebox/cmseek.json -fi diff --git a/scanners/cmseek/tests/__snapshot__/scanner_test.yaml.snap b/scanners/cmseek/tests/__snapshot__/scanner_test.yaml.snap deleted file mode 100644 index 758f959b59..0000000000 --- a/scanners/cmseek/tests/__snapshot__/scanner_test.yaml.snap +++ /dev/null @@ -1,90 +0,0 @@ -matches the snapshot: - 1: | - apiVersion: cascading.securecodebox.io/v1 - kind: CascadingRule - metadata: - labels: - securecodebox.io/intensive: medium - securecodebox.io/invasive: non-invasive - name: cmseek-cascade - spec: - matches: - anyOf: - - attributes: - MetaGenerator: Joomla! - Open Source Content Management - category: WEB APPLICATION - scanSpec: - parameters: - - -u - - '{{{location}}}' - scanType: cmseek - 2: | - apiVersion: execution.securecodebox.io/v1 - kind: ParseDefinition - metadata: - name: cmseek-json - spec: - affinity: - foo: bar - env: - - name: foo - value: bar - image: docker.io/securecodebox/parser-cmseek:0.0.0 - imagePullPolicy: IfNotPresent - imagePullSecrets: - - name: foo - resources: - foo: bar - scopeLimiterAliases: - foo: bar - tolerations: - - foo: bar - ttlSecondsAfterFinished: null - 3: | - apiVersion: execution.securecodebox.io/v1 - kind: ScanType - metadata: - name: cmseekfoo - spec: - extractResults: - location: /home/securecodebox/cmseek.json - type: cmseek-json - jobTemplate: - spec: - backoffLimit: 3 - suspend: false - template: - spec: - affinity: - foo: bar - containers: - - command: - - sh - - /home/cmseek/wrapper.sh - env: - - name: foo - value: bar - image: docker.io/securecodebox/scanner-cmseek:0.0.0 - imagePullPolicy: IfNotPresent - name: cmseek - resources: - foo: bar - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - all - privileged: false - readOnlyRootFilesystem: false - runAsNonRoot: true - volumeMounts: [] - - image: bar - name: foo - imagePullSecrets: - - name: foo - restartPolicy: Never - securityContext: - fsGroup: 1234 - tolerations: - - foo: bar - volumes: [] diff --git a/scanners/cmseek/tests/scanner_test.yaml b/scanners/cmseek/tests/scanner_test.yaml deleted file mode 100644 index c5b3b49c3a..0000000000 --- a/scanners/cmseek/tests/scanner_test.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -suite: Full Snapshot - -tests: - - it: matches the snapshot - chart: - version: 0.0.0 - appVersion: 0.0.0 - set: - cascadingRules.enabled: true - imagePullSecrets: [{name: foo}] - parser: - env: [{name: foo, value: bar}] - scopeLimiterAliases: {foo: bar} - affinity: {foo: bar} - tolerations: [{foo: bar}] - resources: {foo: bar} - scanner: - nameAppend: foo - resources: {foo: bar} - env: [{name: foo, value: bar}] - extraContainers: [{name: foo, image: bar}] - podSecurityContext: {fsGroup: 1234} - affinity: {foo: bar} - tolerations: [{foo: bar}] - asserts: - - matchSnapshot: {} diff --git a/scanners/cmseek/values.yaml b/scanners/cmseek/values.yaml deleted file mode 100644 index 3d8d5ec19c..0000000000 --- a/scanners/cmseek/values.yaml +++ /dev/null @@ -1,114 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 -# -- Define imagePullSecrets when a private registry is used (see: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) -imagePullSecrets: [] - -parser: - image: - # parser.image.repository -- Parser image repository - repository: docker.io/securecodebox/parser-cmseek - # parser.image.tag -- Parser image tag - # @default -- defaults to the charts version - tag: null - # -- Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images - pullPolicy: IfNotPresent - - # parser.ttlSecondsAfterFinished -- seconds after which the Kubernetes job for the parser will be deleted. Requires the Kubernetes TTLAfterFinished controller: https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ - ttlSecondsAfterFinished: null - # parser.env -- Optional environment variables mapped into each parseJob (see: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) - env: [] - - # parser.scopeLimiterAliases -- Optional finding aliases to be used in the scopeLimiter. - scopeLimiterAliases: {} - - # parser.nodeSelector -- Optional nodeSelector settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/) - nodeSelector: {} - - # parser.affinity -- Optional affinity settings that control how the parser job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) - affinity: {} - - # parser.tolerations -- Optional tolerations settings that control how the parser job is scheduled (see: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) - tolerations: [] - - # -- Optional resources lets you control resource limits and requests for the parser container. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - # @default -- `{ requests: { cpu: "200m", memory: "100Mi" }, limits: { cpu: "400m", memory: "200Mi" } }` - resources: {} - -scanner: - image: - # scanner.image.repository -- Container Image to run the scan - repository: docker.io/securecodebox/scanner-cmseek - # scanner.image.tag -- defaults to the charts appVersion - tag: null - # -- Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images - pullPolicy: IfNotPresent - - # scanner.nameAppend -- append a string to the default scantype name. - nameAppend: null - - # -- seconds after which the Kubernetes job for the scanner will be deleted. Requires the Kubernetes TTLAfterFinished controller: https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ - ttlSecondsAfterFinished: null - # -- There are situations where you want to fail a scan Job after some amount of time. To do so, set activeDeadlineSeconds to define an active deadline (in seconds) when considering a scan Job as failed. (see: https://kubernetes.io/docs/concepts/workloads/controllers/job/#job-termination-and-cleanup) - activeDeadlineSeconds: null - # -- There are situations where you want to fail a scan Job after some amount of retries due to a logical error in configuration etc. To do so, set backoffLimit to specify the number of retries before considering a scan Job as failed. (see: https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-backoff-failure-policy) - # @default -- 3 - backoffLimit: 3 - - # scanner.resources -- CPU/memory resource requests/limits (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/, https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/) - resources: {} - # resources: - # requests: - # memory: "256Mi" - # cpu: "250m" - # limits: - # memory: "512Mi" - # cpu: "500m" - - # scanner.env -- Optional environment variables mapped into each scanJob (see: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) - env: [] - - # scanner.extraVolumes -- Optional Volumes mapped into each scanJob (see: https://kubernetes.io/docs/concepts/storage/volumes/) - extraVolumes: [] - - # scanner.extraVolumeMounts -- Optional VolumeMounts mapped into each scanJob (see: https://kubernetes.io/docs/concepts/storage/volumes/) - extraVolumeMounts: [] - - # scanner.extraContainers -- Optional additional Containers started with each scanJob (see: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/) - extraContainers: [] - - # scanner.podSecurityContext -- Optional securityContext set on scanner pod (see: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) - podSecurityContext: - {} - # fsGroup: 2000 - - # scanner.securityContext -- Optional securityContext set on scanner container (see: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) - securityContext: - # scanner.securityContext.runAsNonRoot -- Enforces that the scanner image is run as a non root user - runAsNonRoot: true - # scanner.securityContext.readOnlyRootFilesystem -- Prevents write access to the containers file system - readOnlyRootFilesystem: false - # scanner.securityContext.allowPrivilegeEscalation -- Ensure that users privileges cannot be escalated - allowPrivilegeEscalation: false - # scanner.securityContext.privileged -- Ensures that the scanner container is not run in privileged mode - privileged: false - capabilities: - drop: - # scanner.securityContext.capabilities.drop[0] -- This drops all linux privileges from the container. - - all - - # scanner.nodeSelector -- Optional nodeSelector settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/) - nodeSelector: {} - - # scanner.affinity -- Optional affinity settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) - affinity: {} - - # scanner.tolerations -- Optional tolerations settings that control how the scanner job is scheduled (see: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) - tolerations: [] - - # -- if set to true the scan job will be suspended after creation. You can then resume the job using `kubectl resume ` or using a job scheduler like kueue - suspend: false - -cascadingRules: - # cascadingRules.enabled -- Enables or disables the installation of the default cascading rules for this scanner - enabled: false diff --git a/scanners/ffuf/parser/parser.test.js b/scanners/ffuf/parser/parser.test.js index a00a0eb604..14802095d8 100644 --- a/scanners/ffuf/parser/parser.test.js +++ b/scanners/ffuf/parser/parser.test.js @@ -16,7 +16,7 @@ test("should properly parse ffuf json file", async () => { ); const findings = await parse(fileContent); // validate findings - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(` [ { @@ -81,7 +81,7 @@ test("should properly parse ffuf json file wih multiple fuzz keyword inputs", as const findings = await parse(fileContent); // validate findings - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(` [ { @@ -122,7 +122,7 @@ test("should properly parse ffuf json file with postdata", async () => { ); const findings = await parse(fileContent); // validate findings - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(` [ { @@ -162,7 +162,7 @@ test("should properly parse empty json file", async () => { }); const findings = await parse(fileContent); // validate findings - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(`[]`); }); @@ -175,7 +175,7 @@ test("should properly parse juice-shop findings json file", async () => { ); const findings = await parse(fileContent); // validate findings - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(` [ { @@ -241,27 +241,27 @@ test("should properly parse zero findings json file", async () => { ); const findings = await parse(fileContent); // validate findings - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(`[]`); }); test("should properly parse empty string", async () => { const findings = await parse(""); // validate findings - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(`[]`); }); test("should properly parse null", async () => { const findings = await parse(null); // validate findings - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(`[]`); }); test("should properly parse undefined", async () => { const findings = await parse(undefined); // validate findings - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(`[]`); }); diff --git a/scanners/ffuf/scanner/Dockerfile b/scanners/ffuf/scanner/Dockerfile index cf06ccb103..cebb7fb391 100644 --- a/scanners/ffuf/scanner/Dockerfile +++ b/scanners/ffuf/scanner/Dockerfile @@ -2,9 +2,9 @@ # # SPDX-License-Identifier: Apache-2.0 -FROM --platform=$BUILDPLATFORM golang:1.24-alpine AS builder +FROM --platform=$BUILDPLATFORM golang:1.25-alpine AS builder ARG scannerVersion -RUN GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=0 go install github.com/ffuf/ffuf/v2@$scannerVersion +RUN GOOS="$TARGETOS" GOARCH="$TARGETARCH" CGO_ENABLED=0 go install github.com/ffuf/ffuf/v2@$scannerVersion RUN mkdir -p /home/ffuf/.config/ffuf RUN mkdir -p /home/ffuf/.config/ffuf/scraper diff --git a/scanners/git-repo-scanner/.helm-docs.gotmpl b/scanners/git-repo-scanner/.helm-docs.gotmpl index 430ba846e5..285100b5bd 100644 --- a/scanners/git-repo-scanner/.helm-docs.gotmpl +++ b/scanners/git-repo-scanner/.helm-docs.gotmpl @@ -25,7 +25,7 @@ usecase: "Discover Git repositories" {{- define "extra.chartAboutSection" -}} ## What is Git-Repo-Scanner? -Git-Repo-Scanner is a small Python script which discovers repositories on GitHub or GitLab. The main purpose of this scanner +Git-Repo-Scanner is a small Go project which discovers repositories on GitHub or GitLab. The main purpose of this scanner is to provide a cascading input for the [gitleaks](https://www.securecodebox.io/docs/scanners/gitleaks) and [semgrep](https://www.securecodebox.io/docs/scanners/semgrep) scanners. {{- end }} @@ -36,9 +36,9 @@ The scanner options can be divided into two groups for Gitlab and GitHub. You ca repository type with the option: ```bash ---git-type github +--git-type GitHub or ---git-type Gitlab +--git-type GitLab ``` #### GitHub diff --git a/scanners/git-repo-scanner/README.md b/scanners/git-repo-scanner/README.md index 1415a9501a..115ea5a5e3 100644 --- a/scanners/git-repo-scanner/README.md +++ b/scanners/git-repo-scanner/README.md @@ -35,7 +35,7 @@ Otherwise your changes will be reverted/overwritten automatically due to the bui ## What is Git-Repo-Scanner? -Git-Repo-Scanner is a small Python script which discovers repositories on GitHub or GitLab. The main purpose of this scanner +Git-Repo-Scanner is a small Go project which discovers repositories on GitHub or GitLab. The main purpose of this scanner is to provide a cascading input for the [gitleaks](https://www.securecodebox.io/docs/scanners/gitleaks) and [semgrep](https://www.securecodebox.io/docs/scanners/semgrep) scanners. ## Deployment @@ -52,9 +52,9 @@ The scanner options can be divided into two groups for Gitlab and GitHub. You ca repository type with the option: ```bash ---git-type github +--git-type GitHub or ---git-type Gitlab +--git-type GitLab ``` #### GitHub diff --git a/scanners/git-repo-scanner/Taskfile.yaml b/scanners/git-repo-scanner/Taskfile.yaml index a7b2ce668b..aa7524c73f 100644 --- a/scanners/git-repo-scanner/Taskfile.yaml +++ b/scanners/git-repo-scanner/Taskfile.yaml @@ -8,7 +8,15 @@ includes: scanner: taskfile: ../Taskfile.yaml flatten: true + excludes: [test:unit] vars: scannerName: git-repo-scanner -tasks: {} +tasks: + test:unit: + desc: Run unit tests for git-repo-scanner + deps: + - test:setup + cmds: + - bun test {{ .TASKFILE_DIR }}/parser/ + - cd {{ .TASKFILE_DIR }}/scanner && go test ./... diff --git a/scanners/git-repo-scanner/docs/README.ArtifactHub.md b/scanners/git-repo-scanner/docs/README.ArtifactHub.md index b97cfb120a..7745c02819 100644 --- a/scanners/git-repo-scanner/docs/README.ArtifactHub.md +++ b/scanners/git-repo-scanner/docs/README.ArtifactHub.md @@ -42,7 +42,7 @@ You can find resources to help you get started on our [documentation website](ht ## What is Git-Repo-Scanner? -Git-Repo-Scanner is a small Python script which discovers repositories on GitHub or GitLab. The main purpose of this scanner +Git-Repo-Scanner is a small Go project which discovers repositories on GitHub or GitLab. The main purpose of this scanner is to provide a cascading input for the [gitleaks](https://www.securecodebox.io/docs/scanners/gitleaks) and [semgrep](https://www.securecodebox.io/docs/scanners/semgrep) scanners. ## Deployment @@ -59,9 +59,9 @@ The scanner options can be divided into two groups for Gitlab and GitHub. You ca repository type with the option: ```bash ---git-type github +--git-type GitHub or ---git-type Gitlab +--git-type GitLab ``` #### GitHub diff --git a/scanners/git-repo-scanner/docs/README.DockerHub-Parser.md b/scanners/git-repo-scanner/docs/README.DockerHub-Parser.md index 4d47351943..f22f6a2f0a 100644 --- a/scanners/git-repo-scanner/docs/README.DockerHub-Parser.md +++ b/scanners/git-repo-scanner/docs/README.DockerHub-Parser.md @@ -53,7 +53,7 @@ docker pull securecodebox/parser-git-repo-scanner ## What is Git-Repo-Scanner? -Git-Repo-Scanner is a small Python script which discovers repositories on GitHub or GitLab. The main purpose of this scanner +Git-Repo-Scanner is a small Go project which discovers repositories on GitHub or GitLab. The main purpose of this scanner is to provide a cascading input for the [gitleaks](https://www.securecodebox.io/docs/scanners/gitleaks) and [semgrep](https://www.securecodebox.io/docs/scanners/semgrep) scanners. ## Community diff --git a/scanners/git-repo-scanner/docs/README.DockerHub-Scanner.md b/scanners/git-repo-scanner/docs/README.DockerHub-Scanner.md index b3d288b888..f086c0891a 100644 --- a/scanners/git-repo-scanner/docs/README.DockerHub-Scanner.md +++ b/scanners/git-repo-scanner/docs/README.DockerHub-Scanner.md @@ -53,7 +53,7 @@ docker pull securecodebox/scanner-git-repo-scanner ## What is Git-Repo-Scanner? -Git-Repo-Scanner is a small Python script which discovers repositories on GitHub or GitLab. The main purpose of this scanner +Git-Repo-Scanner is a small Go project which discovers repositories on GitHub or GitLab. The main purpose of this scanner is to provide a cascading input for the [gitleaks](https://www.securecodebox.io/docs/scanners/gitleaks) and [semgrep](https://www.securecodebox.io/docs/scanners/semgrep) scanners. ## Scanner Configuration @@ -62,9 +62,9 @@ The scanner options can be divided into two groups for Gitlab and GitHub. You ca repository type with the option: ```bash ---git-type github +--git-type GitHub or ---git-type Gitlab +--git-type GitLab ``` #### GitHub diff --git a/scanners/git-repo-scanner/examples/github-secureCodeBox-scan/findings.yaml b/scanners/git-repo-scanner/examples/github-secureCodeBox-scan/findings.yaml index ab51e98e35..485e03b5ec 100644 --- a/scanners/git-repo-scanner/examples/github-secureCodeBox-scan/findings.yaml +++ b/scanners/git-repo-scanner/examples/github-secureCodeBox-scan/findings.yaml @@ -11,11 +11,14 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "144957631", - "web_url": "https://github.com/secureCodeBox/ansible-role-securecodebox-openshift", + "archived": true, + "created_at": "2018-08-16T08:11:15Z", "full_name": "secureCodeBox/ansible-role-securecodebox-openshift", - "owner_type": "Organization", + "id": "144957631", + "last_activity_at": "2023-01-28T10:22:09Z", "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", "topics": [ "openshift", @@ -24,11 +27,8 @@ "security-tools", "security", ], - "owner_name": "secureCodeBox", - "created_at": "2018-08-16T08:11:15Z", - "last_activity_at": "2021-02-26T14:43:24Z", "visibility": "public", - "archived": true, + "web_url": "https://github.com/secureCodeBox/ansible-role-securecodebox-openshift", }, }, { @@ -39,11 +39,14 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "142870794", - "web_url": "https://github.com/secureCodeBox/integration-pipeline-jenkins-examples", + "archived": true, + "created_at": "2018-07-30T12:13:41Z", "full_name": "secureCodeBox/integration-pipeline-jenkins-examples", - "owner_type": "Organization", + "id": "142870794", + "last_activity_at": "2023-01-28T10:22:08Z", "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", "topics": [ "security", @@ -53,11 +56,8 @@ "jenkinsfile", "demo", ], - "owner_name": "secureCodeBox", - "created_at": "2018-07-30T12:13:41Z", - "last_activity_at": "2021-02-26T14:42:45Z", "visibility": "public", - "archived": true, + "web_url": "https://github.com/secureCodeBox/integration-pipeline-jenkins-examples", }, }, { @@ -68,17 +68,17 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "214418800", - "web_url": "https://github.com/secureCodeBox/swagger-petstore-openshift", + "archived": false, + "created_at": "2019-10-11T11:28:15Z", "full_name": "secureCodeBox/swagger-petstore-openshift", - "owner_type": "Organization", + "id": "214418800", + "last_activity_at": "2019-10-11T11:37:41Z", "owner_id": "34573705", - "topics": [], "owner_name": "secureCodeBox", - "created_at": "2019-10-11T11:28:15Z", - "last_activity_at": "2019-10-11T11:37:41Z", + "owner_type": "Organization", + "topics": [], "visibility": "public", - "archived": false, + "web_url": "https://github.com/secureCodeBox/swagger-petstore-openshift", }, }, { @@ -89,17 +89,17 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "180568880", - "web_url": "https://github.com/secureCodeBox/ruby-scanner-scaffolding", + "archived": true, + "created_at": "2019-04-10T11:39:04Z", "full_name": "secureCodeBox/ruby-scanner-scaffolding", - "owner_type": "Organization", + "id": "180568880", + "last_activity_at": "2023-01-28T10:22:10Z", "owner_id": "34573705", - "topics": [], "owner_name": "secureCodeBox", - "created_at": "2019-04-10T11:39:04Z", - "last_activity_at": "2021-02-26T14:42:14Z", + "owner_type": "Organization", + "topics": [], "visibility": "public", - "archived": true, + "web_url": "https://github.com/secureCodeBox/ruby-scanner-scaffolding", }, }, { @@ -110,17 +110,17 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "141462466", - "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-amass", + "archived": true, + "created_at": "2018-07-18T16:38:18Z", "full_name": "secureCodeBox/scanner-infrastructure-amass", - "owner_type": "Organization", + "id": "141462466", + "last_activity_at": "2023-06-22T01:51:32Z", "owner_id": "34573705", - "topics": [], "owner_name": "secureCodeBox", - "created_at": "2018-07-18T16:38:18Z", - "last_activity_at": "2021-02-26T14:41:40Z", + "owner_type": "Organization", + "topics": [], "visibility": "public", - "archived": true, + "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-amass", }, }, { @@ -131,17 +131,17 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "251007807", - "web_url": "https://github.com/secureCodeBox/zap-extensions", + "archived": false, + "created_at": "2020-03-29T10:40:12Z", "full_name": "secureCodeBox/zap-extensions", - "owner_type": "Organization", + "id": "251007807", + "last_activity_at": "2020-03-29T10:40:13Z", "owner_id": "34573705", - "topics": [], "owner_name": "secureCodeBox", - "created_at": "2020-03-29T10:40:12Z", - "last_activity_at": "2020-03-29T10:40:13Z", + "owner_type": "Organization", + "topics": [], "visibility": "public", - "archived": false, + "web_url": "https://github.com/secureCodeBox/zap-extensions", }, }, { @@ -152,17 +152,17 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "171298120", - "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-ssh", + "archived": true, + "created_at": "2019-02-18T14:23:57Z", "full_name": "secureCodeBox/scanner-infrastructure-ssh", - "owner_type": "Organization", + "id": "171298120", + "last_activity_at": "2023-01-28T10:22:09Z", "owner_id": "34573705", - "topics": [], "owner_name": "secureCodeBox", - "created_at": "2019-02-18T14:23:57Z", - "last_activity_at": "2021-02-26T14:40:57Z", + "owner_type": "Organization", + "topics": [], "visibility": "public", - "archived": true, + "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-ssh", }, }, { @@ -173,11 +173,14 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "128396681", - "web_url": "https://github.com/secureCodeBox/scanner-webserver-nikto", + "archived": true, + "created_at": "2018-04-06T13:13:14Z", "full_name": "secureCodeBox/scanner-webserver-nikto", - "owner_type": "Organization", + "id": "128396681", + "last_activity_at": "2024-08-10T17:59:05Z", "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", "topics": [ "nikto", @@ -187,11 +190,8 @@ "security-tools", "microservice", ], - "owner_name": "secureCodeBox", - "created_at": "2018-04-06T13:13:14Z", - "last_activity_at": "2021-02-26T14:40:31Z", "visibility": "public", - "archived": true, + "web_url": "https://github.com/secureCodeBox/scanner-webserver-nikto", }, }, { @@ -202,11 +202,14 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "134673181", - "web_url": "https://github.com/secureCodeBox/scanner-webapplication-arachni", + "archived": true, + "created_at": "2018-05-24T06:47:00Z", "full_name": "secureCodeBox/scanner-webapplication-arachni", - "owner_type": "Organization", + "id": "134673181", + "last_activity_at": "2023-03-29T14:00:28Z", "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", "topics": [ "arachni", @@ -216,11 +219,8 @@ "security-tools", "microservice", ], - "owner_name": "secureCodeBox", - "created_at": "2018-05-24T06:47:00Z", - "last_activity_at": "2021-02-26T14:40:03Z", "visibility": "public", - "archived": true, + "web_url": "https://github.com/secureCodeBox/scanner-webapplication-arachni", }, }, { @@ -231,17 +231,17 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "180543766", - "web_url": "https://github.com/secureCodeBox/scanner-cms-wpscan", + "archived": true, + "created_at": "2019-04-10T09:03:38Z", "full_name": "secureCodeBox/scanner-cms-wpscan", - "owner_type": "Organization", + "id": "180543766", + "last_activity_at": "2023-04-25T07:15:25Z", "owner_id": "34573705", - "topics": [], "owner_name": "secureCodeBox", - "created_at": "2019-04-10T09:03:38Z", - "last_activity_at": "2021-02-26T14:39:25Z", + "owner_type": "Organization", + "topics": [], "visibility": "public", - "archived": true, + "web_url": "https://github.com/secureCodeBox/scanner-cms-wpscan", }, }, { @@ -252,11 +252,14 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "124402117", - "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-nmap", + "archived": true, + "created_at": "2018-03-08T14:20:36Z", "full_name": "secureCodeBox/scanner-infrastructure-nmap", - "owner_type": "Organization", + "id": "124402117", + "last_activity_at": "2025-04-08T19:31:01Z", "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", "topics": [ "nmap", @@ -266,11 +269,8 @@ "security-tools", "microservice", ], - "owner_name": "secureCodeBox", - "created_at": "2018-03-08T14:20:36Z", - "last_activity_at": "2021-06-11T21:49:14Z", "visibility": "public", - "archived": true, + "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-nmap", }, }, { @@ -281,11 +281,14 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "133507929", - "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-sslyze", + "archived": true, + "created_at": "2018-05-15T11:43:11Z", "full_name": "secureCodeBox/scanner-infrastructure-sslyze", - "owner_type": "Organization", + "id": "133507929", + "last_activity_at": "2023-01-28T10:22:08Z", "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", "topics": [ "sslyze", @@ -295,11 +298,8 @@ "security-tools", "microservice", ], - "owner_name": "secureCodeBox", - "created_at": "2018-05-15T11:43:11Z", - "last_activity_at": "2021-02-26T14:38:12Z", "visibility": "public", - "archived": true, + "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-sslyze", }, }, { @@ -310,17 +310,17 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "223956455", - "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-ncrack", + "archived": true, + "created_at": "2019-11-25T13:34:16Z", "full_name": "secureCodeBox/scanner-infrastructure-ncrack", - "owner_type": "Organization", + "id": "223956455", + "last_activity_at": "2023-01-28T10:22:10Z", "owner_id": "34573705", - "topics": [], "owner_name": "secureCodeBox", - "created_at": "2019-11-25T13:34:16Z", - "last_activity_at": "2021-02-26T14:37:34Z", + "owner_type": "Organization", + "topics": [], "visibility": "public", - "archived": true, + "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-ncrack", }, }, { @@ -331,17 +331,17 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "277835641", - "web_url": "https://github.com/secureCodeBox/zaproxy", + "archived": false, + "created_at": "2020-07-07T14:14:16Z", "full_name": "secureCodeBox/zaproxy", - "owner_type": "Organization", + "id": "277835641", + "last_activity_at": "2024-01-30T22:45:22Z", "owner_id": "34573705", - "topics": [], "owner_name": "secureCodeBox", - "created_at": "2020-07-07T14:14:16Z", - "last_activity_at": "2020-07-07T14:14:18Z", + "owner_type": "Organization", + "topics": [], "visibility": "public", - "archived": false, + "web_url": "https://github.com/secureCodeBox/zaproxy", }, }, { @@ -352,11 +352,14 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "249731346", - "web_url": "https://github.com/secureCodeBox/secureCodeBox-v2", + "archived": true, + "created_at": "2020-03-24T14:33:08Z", "full_name": "secureCodeBox/secureCodeBox-v2", - "owner_type": "Organization", + "id": "249731346", + "last_activity_at": "2024-01-30T22:40:47Z", "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", "topics": [ "securecodebox", @@ -367,11 +370,8 @@ "scanning", "hacktoberfest", ], - "owner_name": "secureCodeBox", - "created_at": "2020-03-24T14:33:08Z", - "last_activity_at": "2020-11-05T15:40:55Z", "visibility": "public", - "archived": true, + "web_url": "https://github.com/secureCodeBox/secureCodeBox-v2", }, }, { @@ -382,38 +382,17 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "203588805", - "web_url": "https://github.com/secureCodeBox/securecodebox.github.io", - "full_name": "secureCodeBox/securecodebox.github.io", - "owner_type": "Organization", + "archived": true, + "created_at": "2018-03-20T15:48:39Z", + "full_name": "secureCodeBox/nodejs-scanner-scaffolding", + "id": "126042943", + "last_activity_at": "2023-01-28T10:22:08Z", "owner_id": "34573705", - "topics": [], "owner_name": "secureCodeBox", - "created_at": "2019-08-21T13:21:09Z", - "last_activity_at": "2020-10-16T11:40:25Z", - "visibility": "public", - "archived": false, - }, - }, - { - "name": "GitHub Repo", - "description": "A GitHub repository", - "category": "Git Repository", - "osi_layer": "APPLICATION", - "severity": "INFORMATIONAL", - "attributes": - { - "id": "126042943", - "web_url": "https://github.com/secureCodeBox/nodejs-scanner-scaffolding", - "full_name": "secureCodeBox/nodejs-scanner-scaffolding", "owner_type": "Organization", - "owner_id": "34573705", "topics": [], - "owner_name": "secureCodeBox", - "created_at": "2018-03-20T15:48:39Z", - "last_activity_at": "2021-02-26T14:36:53Z", "visibility": "public", - "archived": true, + "web_url": "https://github.com/secureCodeBox/nodejs-scanner-scaffolding", }, }, { @@ -424,11 +403,14 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "128920739", - "web_url": "https://github.com/secureCodeBox/scanner-webapplication-zap", + "archived": true, + "created_at": "2018-04-10T11:17:29Z", "full_name": "secureCodeBox/scanner-webapplication-zap", - "owner_type": "Organization", + "id": "128920739", + "last_activity_at": "2024-10-03T05:13:23Z", "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", "topics": [ "zap", @@ -438,11 +420,8 @@ "security-tools", "microservice", ], - "owner_name": "secureCodeBox", - "created_at": "2018-04-10T11:17:29Z", - "last_activity_at": "2021-02-26T14:36:02Z", "visibility": "public", - "archived": true, + "web_url": "https://github.com/secureCodeBox/scanner-webapplication-zap", }, }, { @@ -453,17 +432,17 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "123422137", - "web_url": "https://github.com/secureCodeBox/engine", + "archived": true, + "created_at": "2018-03-01T10:50:05Z", "full_name": "secureCodeBox/engine", - "owner_type": "Organization", + "id": "123422137", + "last_activity_at": "2023-01-28T10:22:08Z", "owner_id": "34573705", - "topics": [], "owner_name": "secureCodeBox", - "created_at": "2018-03-01T10:50:05Z", - "last_activity_at": "2021-02-26T14:35:25Z", + "owner_type": "Organization", + "topics": [], "visibility": "public", - "archived": true, + "web_url": "https://github.com/secureCodeBox/engine", }, }, { @@ -474,17 +453,17 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "327336031", - "web_url": "https://github.com/secureCodeBox/gitleaks", - "full_name": "secureCodeBox/gitleaks", - "owner_type": "Organization", + "archived": false, + "created_at": "2020-10-12T09:58:26Z", + "full_name": "secureCodeBox/kubeaudit", + "id": "303349727", + "last_activity_at": "2024-01-30T22:38:13Z", "owner_id": "34573705", - "topics": [], "owner_name": "secureCodeBox", - "created_at": "2021-01-06T14:27:46Z", - "last_activity_at": "2021-03-06T20:23:36Z", + "owner_type": "Organization", + "topics": [], "visibility": "public", - "archived": false, + "web_url": "https://github.com/secureCodeBox/kubeaudit", }, }, { @@ -495,17 +474,17 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "357207085", - "web_url": "https://github.com/secureCodeBox/django-DefectDojo", + "archived": false, + "created_at": "2021-04-12T13:36:31Z", "full_name": "secureCodeBox/django-DefectDojo", - "owner_type": "Organization", + "id": "357207085", + "last_activity_at": "2024-01-30T22:35:01Z", "owner_id": "34573705", - "topics": [], "owner_name": "secureCodeBox", - "created_at": "2021-04-12T13:36:31Z", - "last_activity_at": "2021-12-14T14:46:54Z", + "owner_type": "Organization", + "topics": [], "visibility": "public", - "archived": false, + "web_url": "https://github.com/secureCodeBox/django-DefectDojo", }, }, { @@ -516,17 +495,17 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "204701677", - "web_url": "https://github.com/secureCodeBox/ssh_scan", + "archived": false, + "created_at": "2019-08-27T12:46:48Z", "full_name": "secureCodeBox/ssh_scan", - "owner_type": "Organization", + "id": "204701677", + "last_activity_at": "2022-01-25T02:32:59Z", "owner_id": "34573705", - "topics": [], "owner_name": "secureCodeBox", - "created_at": "2019-08-27T12:46:48Z", - "last_activity_at": "2021-06-22T12:11:47Z", + "owner_type": "Organization", + "topics": [], "visibility": "public", - "archived": false, + "web_url": "https://github.com/secureCodeBox/ssh_scan", }, }, { @@ -537,17 +516,17 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "222679857", - "web_url": "https://github.com/secureCodeBox/nikto", + "archived": false, + "created_at": "2019-11-19T11:25:21Z", "full_name": "secureCodeBox/nikto", - "owner_type": "Organization", + "id": "222679857", + "last_activity_at": "2021-08-25T14:24:37Z", "owner_id": "34573705", - "topics": [], "owner_name": "secureCodeBox", - "created_at": "2019-11-19T11:25:21Z", - "last_activity_at": "2021-08-25T14:24:37Z", + "owner_type": "Organization", + "topics": [], "visibility": "public", - "archived": false, + "web_url": "https://github.com/secureCodeBox/nikto", }, }, { @@ -558,17 +537,17 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "409468006", - "web_url": "https://github.com/secureCodeBox/sslyze", + "archived": false, + "created_at": "2021-09-23T06:03:50Z", "full_name": "secureCodeBox/sslyze", - "owner_type": "Organization", + "id": "409468006", + "last_activity_at": "2021-09-23T06:03:51Z", "owner_id": "34573705", - "topics": [], "owner_name": "secureCodeBox", - "created_at": "2021-09-23T06:03:50Z", - "last_activity_at": "2021-09-23T06:03:51Z", + "owner_type": "Organization", + "topics": [], "visibility": "public", - "archived": false, + "web_url": "https://github.com/secureCodeBox/sslyze", }, }, { @@ -579,25 +558,60 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "327269915", - "web_url": "https://github.com/secureCodeBox/defectdojo-client-java", - "full_name": "secureCodeBox/defectdojo-client-java", + "archived": false, + "created_at": "2019-08-21T13:21:09Z", + "full_name": "secureCodeBox/securecodebox.github.io", + "id": "203588805", + "last_activity_at": "2022-04-19T13:33:36Z", + "owner_id": "34573705", + "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/securecodebox.github.io", + }, + }, + { + "name": "GitHub Repo", + "description": "A GitHub repository", + "category": "Git Repository", + "osi_layer": "APPLICATION", + "severity": "INFORMATIONAL", + "attributes": + { + "archived": true, + "created_at": "2020-09-02T13:39:10Z", + "full_name": "secureCodeBox/documentation", + "id": "292293538", + "last_activity_at": "2024-01-20T09:04:19Z", "owner_id": "34573705", - "topics": - [ - "defectdojo", - "owasp", - "client-library", - "java", - "gradle", - "hacktoberfest", - ], "owner_name": "secureCodeBox", - "created_at": "2021-01-06T09:59:17Z", - "last_activity_at": "2021-10-20T08:45:43Z", + "owner_type": "Organization", + "topics": + ["securecodebox", "docusaurus", "documentation", "hacktoberfest"], "visibility": "public", + "web_url": "https://github.com/secureCodeBox/documentation", + }, + }, + { + "name": "GitHub Repo", + "description": "A GitHub repository", + "category": "Git Repository", + "osi_layer": "APPLICATION", + "severity": "INFORMATIONAL", + "attributes": + { "archived": false, + "created_at": "2023-03-21T19:51:07Z", + "full_name": "secureCodeBox/www-community", + "id": "617150115", + "last_activity_at": "2024-03-14T15:30:35Z", + "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/www-community", }, }, { @@ -608,17 +622,80 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "288212154", - "web_url": "https://github.com/secureCodeBox/telemetry", - "full_name": "secureCodeBox/telemetry", + "archived": false, + "created_at": "2023-10-13T14:15:48Z", + "full_name": "secureCodeBox/landscape", + "id": "704559693", + "last_activity_at": "2024-07-11T19:08:33Z", + "owner_id": "34573705", + "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/landscape", + }, + }, + { + "name": "GitHub Repo", + "description": "A GitHub repository", + "category": "Git Repository", + "osi_layer": "APPLICATION", + "severity": "INFORMATIONAL", + "attributes": + { + "archived": false, + "created_at": "2024-08-09T14:48:36Z", + "full_name": "secureCodeBox/DevSecOps-MaturityModel", + "id": "840369455", + "last_activity_at": "2024-08-09T14:48:36Z", "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/DevSecOps-MaturityModel", + }, + }, + { + "name": "GitHub Repo", + "description": "A GitHub repository", + "category": "Git Repository", + "osi_layer": "APPLICATION", + "severity": "INFORMATIONAL", + "attributes": + { + "archived": false, + "created_at": "2021-01-06T14:27:46Z", + "full_name": "secureCodeBox/gitleaks", + "id": "327336031", + "last_activity_at": "2024-01-30T22:39:59Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2020-08-17T15:09:19Z", - "last_activity_at": "2021-12-06T14:24:34Z", + "owner_type": "Organization", + "topics": [], "visibility": "public", + "web_url": "https://github.com/secureCodeBox/gitleaks", + }, + }, + { + "name": "GitHub Repo", + "description": "A GitHub repository", + "category": "Git Repository", + "osi_layer": "APPLICATION", + "severity": "INFORMATIONAL", + "attributes": + { "archived": false, + "created_at": "2025-04-18T19:36:30Z", + "full_name": "secureCodeBox/scb-cascades-demo", + "id": "968815564", + "last_activity_at": "2025-04-24T11:47:52Z", + "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/scb-cascades-demo", }, }, { @@ -629,18 +706,67 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "292293538", - "web_url": "https://github.com/secureCodeBox/documentation", - "full_name": "secureCodeBox/documentation", + "archived": false, + "created_at": "2024-12-29T17:07:02Z", + "full_name": "secureCodeBox/scan-throttler", + "id": "909750535", + "last_activity_at": "2025-08-19T14:02:18Z", + "owner_id": "34573705", + "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/scan-throttler", + }, + }, + { + "name": "GitHub Repo", + "description": "A GitHub repository", + "category": "Git Repository", + "osi_layer": "APPLICATION", + "severity": "INFORMATIONAL", + "attributes": + { + "archived": false, + "created_at": "2021-01-06T09:59:17Z", + "full_name": "secureCodeBox/defectdojo-client-java", + "id": "327269915", + "last_activity_at": "2025-10-20T08:29:33Z", "owner_id": "34573705", - "topics": - ["securecodebox", "docusaurus", "documentation", "hacktoberfest"], "owner_name": "secureCodeBox", - "created_at": "2020-09-02T13:39:10Z", - "last_activity_at": "2021-12-15T13:55:43Z", + "owner_type": "Organization", + "topics": + [ + "defectdojo", + "owasp", + "client-library", + "java", + "gradle", + "hacktoberfest", + ], "visibility": "public", + "web_url": "https://github.com/secureCodeBox/defectdojo-client-java", + }, + }, + { + "name": "GitHub Repo", + "description": "A GitHub repository", + "category": "Git Repository", + "osi_layer": "APPLICATION", + "severity": "INFORMATIONAL", + "attributes": + { "archived": false, + "created_at": "2020-08-17T15:09:19Z", + "full_name": "secureCodeBox/telemetry", + "id": "288212154", + "last_activity_at": "2025-11-20T07:43:05Z", + "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/telemetry", }, }, { @@ -651,11 +777,14 @@ "severity": "INFORMATIONAL", "attributes": { - "id": "80711933", - "web_url": "https://github.com/secureCodeBox/secureCodeBox", + "archived": false, + "created_at": "2017-02-02T09:48:05Z", "full_name": "secureCodeBox/secureCodeBox", - "owner_type": "Organization", + "id": "80711933", + "last_activity_at": "2025-11-24T10:04:46Z", "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", "topics": [ "security", @@ -667,14 +796,11 @@ "kubernetes", "kubernetes-operator", "owasp", - "owasp-zap", "hacktoberfest", + "zaproxy", ], - "owner_name": "secureCodeBox", - "created_at": "2017-02-02T09:48:05Z", - "last_activity_at": "2021-12-21T09:48:07Z", "visibility": "public", - "archived": false, + "web_url": "https://github.com/secureCodeBox/secureCodeBox", }, }, ] diff --git a/scanners/git-repo-scanner/integration-tests/git-repo-scanner.test.js b/scanners/git-repo-scanner/integration-tests/git-repo-scanner.test.js index 7815274085..1dcccb8e0f 100644 --- a/scanners/git-repo-scanner/integration-tests/git-repo-scanner.test.js +++ b/scanners/git-repo-scanner/integration-tests/git-repo-scanner.test.js @@ -8,12 +8,11 @@ test.skip( "git-repo-scanner should find at least 1 repository in the GitHub secureCodeBox organisation", async () => { // This integration tests runs about 30min because of the GitHub Public API call rate limit. - // If you want to speed up you need to add an valid access token like: ['--git-type', 'github', '--organization', 'secureCodeBox', '--access-token', '23476VALID2345TOKEN'], + // If you want to speed up you need to add an valid access token like: ['--git-type', 'GitHub', '--organization', 'secureCodeBox', '--access-token', '23476VALID2345TOKEN'], const { count } = await scan( "git-repo-scanner-dummy-scan", "git-repo-scanner", ["--git-type", "github", "--organization", "secureCodeBox"], - 90, ); // There must be >= 28 Repositories found in the GitHub secureCodeBox organisation. expect(count).toBeGreaterThanOrEqual(28); diff --git a/scanners/git-repo-scanner/parser/__testFiles__/git-scanner-test-findings.json b/scanners/git-repo-scanner/parser/__testFiles__/git-scanner-test-findings.json index 435b7428f7..6ca11b3fa5 100644 --- a/scanners/git-repo-scanner/parser/__testFiles__/git-scanner-test-findings.json +++ b/scanners/git-repo-scanner/parser/__testFiles__/git-scanner-test-findings.json @@ -6,15 +6,23 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 80711933, - "web_url": "https://github.com/secureCodeBox/secureCodeBox", - "full_name": "secureCodeBox/secureCodeBox", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": true, + "created_at": "2018-08-16T08:11:15Z", + "full_name": "secureCodeBox/ansible-role-securecodebox-openshift", + "id": "144957631", + "last_activity_at": "2023-01-28T10:22:09Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2017-02-02T09:48:05Z", - "last_activity_at": "2020-10-23T08:59:27Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [ + "openshift", + "ansible-role", + "ansible", + "security-tools", + "security" + ], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/ansible-role-securecodebox-openshift" } }, { @@ -24,15 +32,24 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 123422137, - "web_url": "https://github.com/secureCodeBox/engine", - "full_name": "secureCodeBox/engine", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": true, + "created_at": "2018-07-30T12:13:41Z", + "full_name": "secureCodeBox/integration-pipeline-jenkins-examples", + "id": "142870794", + "last_activity_at": "2023-01-28T10:22:08Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2018-03-01T10:50:05Z", - "last_activity_at": "2020-10-07T08:07:32Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [ + "security", + "security-automation", + "security-testing", + "jenkins-pipeline", + "jenkinsfile", + "demo" + ], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/integration-pipeline-jenkins-examples" } }, { @@ -42,15 +59,17 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 124402117, - "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-nmap", - "full_name": "secureCodeBox/scanner-infrastructure-nmap", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": false, + "created_at": "2019-10-11T11:28:15Z", + "full_name": "secureCodeBox/swagger-petstore-openshift", + "id": "214418800", + "last_activity_at": "2019-10-11T11:37:41Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2018-03-08T14:20:36Z", - "last_activity_at": "2020-09-14T15:40:40Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/swagger-petstore-openshift" } }, { @@ -60,15 +79,17 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 126042943, - "web_url": "https://github.com/secureCodeBox/nodejs-scanner-scaffolding", - "full_name": "secureCodeBox/nodejs-scanner-scaffolding", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": true, + "created_at": "2019-04-10T11:39:04Z", + "full_name": "secureCodeBox/ruby-scanner-scaffolding", + "id": "180568880", + "last_activity_at": "2023-01-28T10:22:10Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2018-03-20T15:48:39Z", - "last_activity_at": "2020-07-16T10:37:40Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/ruby-scanner-scaffolding" } }, { @@ -78,15 +99,17 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 128396681, - "web_url": "https://github.com/secureCodeBox/scanner-webserver-nikto", - "full_name": "secureCodeBox/scanner-webserver-nikto", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": true, + "created_at": "2018-07-18T16:38:18Z", + "full_name": "secureCodeBox/scanner-infrastructure-amass", + "id": "141462466", + "last_activity_at": "2023-06-22T01:51:32Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2018-04-06T13:13:14Z", - "last_activity_at": "2020-06-25T10:11:41Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-amass" } }, { @@ -96,15 +119,17 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 128920739, - "web_url": "https://github.com/secureCodeBox/scanner-webapplication-zap", - "full_name": "secureCodeBox/scanner-webapplication-zap", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": false, + "created_at": "2020-03-29T10:40:12Z", + "full_name": "secureCodeBox/zap-extensions", + "id": "251007807", + "last_activity_at": "2020-03-29T10:40:13Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2018-04-10T11:17:29Z", - "last_activity_at": "2020-10-07T14:05:09Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/zap-extensions" } }, { @@ -114,15 +139,44 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 133507929, - "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-sslyze", - "full_name": "secureCodeBox/scanner-infrastructure-sslyze", + "archived": true, + "created_at": "2019-02-18T14:23:57Z", + "full_name": "secureCodeBox/scanner-infrastructure-ssh", + "id": "171298120", + "last_activity_at": "2023-01-28T10:22:09Z", + "owner_id": "34573705", + "owner_name": "secureCodeBox", "owner_type": "Organization", - "owner_id": 34573705, + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-ssh" + } + }, + { + "name": "GitHub Repo", + "description": "A GitHub repository", + "category": "Git Repository", + "osi_layer": "APPLICATION", + "severity": "INFORMATIONAL", + "attributes": { + "archived": true, + "created_at": "2018-04-06T13:13:14Z", + "full_name": "secureCodeBox/scanner-webserver-nikto", + "id": "128396681", + "last_activity_at": "2024-08-10T17:59:05Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2018-05-15T11:43:11Z", - "last_activity_at": "2020-07-16T10:52:54Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [ + "nikto", + "security", + "security-scanner", + "security-automation", + "security-tools", + "microservice" + ], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/scanner-webserver-nikto" } }, { @@ -132,15 +186,24 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 134673181, - "web_url": "https://github.com/secureCodeBox/scanner-webapplication-arachni", + "archived": true, + "created_at": "2018-05-24T06:47:00Z", "full_name": "secureCodeBox/scanner-webapplication-arachni", - "owner_type": "Organization", - "owner_id": 34573705, + "id": "134673181", + "last_activity_at": "2023-03-29T14:00:28Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2018-05-24T06:47:00Z", - "last_activity_at": "2020-10-10T10:29:42Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [ + "arachni", + "security", + "security-scanner", + "security-automation", + "security-tools", + "microservice" + ], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/scanner-webapplication-arachni" } }, { @@ -150,15 +213,17 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 141462466, - "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-amass", - "full_name": "secureCodeBox/scanner-infrastructure-amass", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": true, + "created_at": "2019-04-10T09:03:38Z", + "full_name": "secureCodeBox/scanner-cms-wpscan", + "id": "180543766", + "last_activity_at": "2023-04-25T07:15:25Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2018-07-18T16:38:18Z", - "last_activity_at": "2020-03-17T18:59:35Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/scanner-cms-wpscan" } }, { @@ -168,15 +233,24 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 142870794, - "web_url": "https://github.com/secureCodeBox/integration-pipeline-jenkins-examples", - "full_name": "secureCodeBox/integration-pipeline-jenkins-examples", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": true, + "created_at": "2018-03-08T14:20:36Z", + "full_name": "secureCodeBox/scanner-infrastructure-nmap", + "id": "124402117", + "last_activity_at": "2025-04-08T19:31:01Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2018-07-30T12:13:41Z", - "last_activity_at": "2020-09-27T18:59:24Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [ + "nmap", + "security", + "security-scanner", + "security-automation", + "security-tools", + "microservice" + ], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-nmap" } }, { @@ -186,15 +260,24 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 144957631, - "web_url": "https://github.com/secureCodeBox/ansible-role-securecodebox-openshift", - "full_name": "secureCodeBox/ansible-role-securecodebox-openshift", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": true, + "created_at": "2018-05-15T11:43:11Z", + "full_name": "secureCodeBox/scanner-infrastructure-sslyze", + "id": "133507929", + "last_activity_at": "2023-01-28T10:22:08Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2018-08-16T08:11:15Z", - "last_activity_at": "2019-04-17T13:36:12Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [ + "sslyze", + "security", + "security-scanner", + "security-automation", + "security-tools", + "microservice" + ], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-sslyze" } }, { @@ -204,15 +287,17 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 161506648, - "web_url": "https://github.com/secureCodeBox/django-DefectDojo", - "full_name": "secureCodeBox/django-DefectDojo", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": true, + "created_at": "2019-11-25T13:34:16Z", + "full_name": "secureCodeBox/scanner-infrastructure-ncrack", + "id": "223956455", + "last_activity_at": "2023-01-28T10:22:10Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2018-12-12T15:21:02Z", - "last_activity_at": "2019-01-09T08:41:31Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-ncrack" } }, { @@ -222,15 +307,17 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 171298120, - "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-ssh", - "full_name": "secureCodeBox/scanner-infrastructure-ssh", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": false, + "created_at": "2020-07-07T14:14:16Z", + "full_name": "secureCodeBox/zaproxy", + "id": "277835641", + "last_activity_at": "2024-01-30T22:45:22Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2019-02-18T14:23:57Z", - "last_activity_at": "2020-06-25T10:11:16Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/zaproxy" } }, { @@ -240,15 +327,25 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 180543766, - "web_url": "https://github.com/secureCodeBox/scanner-cms-wpscan", - "full_name": "secureCodeBox/scanner-cms-wpscan", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": true, + "created_at": "2020-03-24T14:33:08Z", + "full_name": "secureCodeBox/secureCodeBox-v2", + "id": "249731346", + "last_activity_at": "2024-01-30T22:40:47Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2019-04-10T09:03:38Z", - "last_activity_at": "2020-06-25T10:12:29Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [ + "securecodebox", + "security-tools", + "penetration-testers", + "devsecops", + "kubernetes-operator", + "scanning", + "hacktoberfest" + ], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/secureCodeBox-v2" } }, { @@ -258,15 +355,17 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 180568880, - "web_url": "https://github.com/secureCodeBox/ruby-scanner-scaffolding", - "full_name": "secureCodeBox/ruby-scanner-scaffolding", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": true, + "created_at": "2018-03-20T15:48:39Z", + "full_name": "secureCodeBox/nodejs-scanner-scaffolding", + "id": "126042943", + "last_activity_at": "2023-01-28T10:22:08Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2019-04-10T11:39:04Z", - "last_activity_at": "2020-03-11T14:20:03Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/nodejs-scanner-scaffolding" } }, { @@ -276,15 +375,24 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 203588805, - "web_url": "https://github.com/secureCodeBox/securecodebox.github.io", - "full_name": "secureCodeBox/securecodebox.github.io", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": true, + "created_at": "2018-04-10T11:17:29Z", + "full_name": "secureCodeBox/scanner-webapplication-zap", + "id": "128920739", + "last_activity_at": "2024-10-03T05:13:23Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2019-08-21T13:21:09Z", - "last_activity_at": "2020-10-16T11:40:25Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [ + "zap", + "security", + "security-scanner", + "security-automation", + "security-tools", + "microservice" + ], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/scanner-webapplication-zap" } }, { @@ -294,15 +402,17 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 204489733, - "web_url": "https://github.com/secureCodeBox/gatsby-gh-pages-action", - "full_name": "secureCodeBox/gatsby-gh-pages-action", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": true, + "created_at": "2018-03-01T10:50:05Z", + "full_name": "secureCodeBox/engine", + "id": "123422137", + "last_activity_at": "2023-01-28T10:22:08Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2019-08-26T14:11:02Z", - "last_activity_at": "2019-08-26T14:11:05Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/engine" } }, { @@ -312,15 +422,17 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 204701677, - "web_url": "https://github.com/secureCodeBox/ssh_scan", - "full_name": "secureCodeBox/ssh_scan", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": false, + "created_at": "2020-10-12T09:58:26Z", + "full_name": "secureCodeBox/kubeaudit", + "id": "303349727", + "last_activity_at": "2024-01-30T22:38:13Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2019-08-27T12:46:48Z", - "last_activity_at": "2019-08-27T12:53:11Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/kubeaudit" } }, { @@ -330,15 +442,37 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 214418800, - "web_url": "https://github.com/secureCodeBox/swagger-petstore-openshift", - "full_name": "secureCodeBox/swagger-petstore-openshift", + "archived": false, + "created_at": "2021-04-12T13:36:31Z", + "full_name": "secureCodeBox/django-DefectDojo", + "id": "357207085", + "last_activity_at": "2024-01-30T22:35:01Z", + "owner_id": "34573705", + "owner_name": "secureCodeBox", "owner_type": "Organization", - "owner_id": 34573705, + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/django-DefectDojo" + } + }, + { + "name": "GitHub Repo", + "description": "A GitHub repository", + "category": "Git Repository", + "osi_layer": "APPLICATION", + "severity": "INFORMATIONAL", + "attributes": { + "archived": false, + "created_at": "2019-08-27T12:46:48Z", + "full_name": "secureCodeBox/ssh_scan", + "id": "204701677", + "last_activity_at": "2022-01-25T02:32:59Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2019-10-11T11:28:15Z", - "last_activity_at": "2019-10-11T11:37:41Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/ssh_scan" } }, { @@ -348,15 +482,17 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 222679857, - "web_url": "https://github.com/secureCodeBox/nikto", + "archived": false, + "created_at": "2019-11-19T11:25:21Z", "full_name": "secureCodeBox/nikto", - "owner_type": "Organization", - "owner_id": 34573705, + "id": "222679857", + "last_activity_at": "2021-08-25T14:24:37Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2019-11-19T11:25:21Z", - "last_activity_at": "2020-03-21T12:43:04Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/nikto" } }, { @@ -366,15 +502,17 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 223956455, - "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-ncrack", - "full_name": "secureCodeBox/scanner-infrastructure-ncrack", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": false, + "created_at": "2021-09-23T06:03:50Z", + "full_name": "secureCodeBox/sslyze", + "id": "409468006", + "last_activity_at": "2021-09-23T06:03:51Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2019-11-25T13:34:16Z", - "last_activity_at": "2020-07-19T11:16:33Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/sslyze" } }, { @@ -384,15 +522,17 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 249731346, - "web_url": "https://github.com/secureCodeBox/secureCodeBox-v2", - "full_name": "secureCodeBox/secureCodeBox-v2", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": false, + "created_at": "2019-08-21T13:21:09Z", + "full_name": "secureCodeBox/securecodebox.github.io", + "id": "203588805", + "last_activity_at": "2022-04-19T13:33:36Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2020-03-24T14:33:08Z", - "last_activity_at": "2020-10-22T08:39:01Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/securecodebox.github.io" } }, { @@ -402,15 +542,22 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 251007807, - "web_url": "https://github.com/secureCodeBox/zap-extensions", - "full_name": "secureCodeBox/zap-extensions", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": true, + "created_at": "2020-09-02T13:39:10Z", + "full_name": "secureCodeBox/documentation", + "id": "292293538", + "last_activity_at": "2024-01-20T09:04:19Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2020-03-29T10:40:12Z", - "last_activity_at": "2020-03-29T10:40:13Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [ + "securecodebox", + "docusaurus", + "documentation", + "hacktoberfest" + ], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/documentation" } }, { @@ -420,15 +567,17 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 277835641, - "web_url": "https://github.com/secureCodeBox/zaproxy", - "full_name": "secureCodeBox/zaproxy", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": false, + "created_at": "2023-03-21T19:51:07Z", + "full_name": "secureCodeBox/www-community", + "id": "617150115", + "last_activity_at": "2024-03-14T15:30:35Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2020-07-07T14:14:16Z", - "last_activity_at": "2020-07-07T14:14:18Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/www-community" } }, { @@ -438,15 +587,17 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 285890805, - "web_url": "https://github.com/secureCodeBox/static-export", - "full_name": "secureCodeBox/static-export", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": false, + "created_at": "2023-10-13T14:15:48Z", + "full_name": "secureCodeBox/landscape", + "id": "704559693", + "last_activity_at": "2024-07-11T19:08:33Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2020-08-07T17:58:52Z", - "last_activity_at": "2020-08-12T12:53:05Z", - "visibility": "private" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/landscape" } }, { @@ -456,15 +607,17 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 288212154, - "web_url": "https://github.com/secureCodeBox/telemetry", - "full_name": "secureCodeBox/telemetry", - "owner_type": "Organization", - "owner_id": 34573705, + "archived": false, + "created_at": "2024-08-09T14:48:36Z", + "full_name": "secureCodeBox/DevSecOps-MaturityModel", + "id": "840369455", + "last_activity_at": "2024-08-09T14:48:36Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2020-08-17T15:09:19Z", - "last_activity_at": "2020-09-01T10:08:23Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/DevSecOps-MaturityModel" } }, { @@ -474,15 +627,37 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 292293538, - "web_url": "https://github.com/secureCodeBox/documentation", - "full_name": "secureCodeBox/documentation", + "archived": false, + "created_at": "2021-01-06T14:27:46Z", + "full_name": "secureCodeBox/gitleaks", + "id": "327336031", + "last_activity_at": "2024-01-30T22:39:59Z", + "owner_id": "34573705", + "owner_name": "secureCodeBox", "owner_type": "Organization", - "owner_id": 34573705, + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/gitleaks" + } + }, + { + "name": "GitHub Repo", + "description": "A GitHub repository", + "category": "Git Repository", + "osi_layer": "APPLICATION", + "severity": "INFORMATIONAL", + "attributes": { + "archived": false, + "created_at": "2025-04-18T19:36:30Z", + "full_name": "secureCodeBox/scb-cascades-demo", + "id": "968815564", + "last_activity_at": "2025-04-24T11:47:52Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2020-09-02T13:39:10Z", - "last_activity_at": "2020-10-21T14:28:35Z", - "visibility": "public" + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/scb-cascades-demo" } }, { @@ -492,15 +667,44 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 292573194, - "web_url": "https://github.com/secureCodeBox/ui", - "full_name": "secureCodeBox/ui", + "archived": false, + "created_at": "2024-12-29T17:07:02Z", + "full_name": "secureCodeBox/scan-throttler", + "id": "909750535", + "last_activity_at": "2025-08-19T14:02:18Z", + "owner_id": "34573705", + "owner_name": "secureCodeBox", "owner_type": "Organization", - "owner_id": 34573705, + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/scan-throttler" + } + }, + { + "name": "GitHub Repo", + "description": "A GitHub repository", + "category": "Git Repository", + "osi_layer": "APPLICATION", + "severity": "INFORMATIONAL", + "attributes": { + "archived": false, + "created_at": "2021-01-06T09:59:17Z", + "full_name": "secureCodeBox/defectdojo-client-java", + "id": "327269915", + "last_activity_at": "2025-10-20T08:29:33Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2020-09-03T13:08:22Z", - "last_activity_at": "2020-10-07T14:38:02Z", - "visibility": "private" + "owner_type": "Organization", + "topics": [ + "defectdojo", + "owasp", + "client-library", + "java", + "gradle", + "hacktoberfest" + ], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/defectdojo-client-java" } }, { @@ -510,15 +714,49 @@ "osi_layer": "APPLICATION", "severity": "INFORMATIONAL", "attributes": { - "id": 299249650, - "web_url": "https://github.com/secureCodeBox/internal", - "full_name": "secureCodeBox/internal", + "archived": false, + "created_at": "2020-08-17T15:09:19Z", + "full_name": "secureCodeBox/telemetry", + "id": "288212154", + "last_activity_at": "2025-11-20T07:43:05Z", + "owner_id": "34573705", + "owner_name": "secureCodeBox", "owner_type": "Organization", - "owner_id": 34573705, + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/telemetry" + } + }, + { + "name": "GitHub Repo", + "description": "A GitHub repository", + "category": "Git Repository", + "osi_layer": "APPLICATION", + "severity": "INFORMATIONAL", + "attributes": { + "archived": false, + "created_at": "2017-02-02T09:48:05Z", + "full_name": "secureCodeBox/secureCodeBox", + "id": "80711933", + "last_activity_at": "2025-11-24T10:04:46Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", - "created_at": "2020-09-28T08:58:53Z", - "last_activity_at": "2020-10-21T15:11:56Z", - "visibility": "private" + "owner_type": "Organization", + "topics": [ + "security", + "security-automation", + "security-tools", + "security-testing", + "securecodebox", + "devsecops", + "kubernetes", + "kubernetes-operator", + "owasp", + "hacktoberfest", + "zaproxy" + ], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/secureCodeBox" } } ] diff --git a/scanners/git-repo-scanner/parser/parser.test.js b/scanners/git-repo-scanner/parser/parser.test.js index 3180436f75..5b54ada567 100644 --- a/scanners/git-repo-scanner/parser/parser.test.js +++ b/scanners/git-repo-scanner/parser/parser.test.js @@ -15,7 +15,7 @@ test("should properly parse empty json file", async () => { }, ); const findings = await parse(fileContent); - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(`[]`); }); @@ -27,20 +27,28 @@ test("should properly parse git-scanner json file", async () => { }, ); const findings = await parse(fileContent); - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(` [ { "attributes": { - "created_at": "2017-02-02T09:48:05Z", - "full_name": "secureCodeBox/secureCodeBox", - "id": 80711933, - "last_activity_at": "2020-10-23T08:59:27Z", - "owner_id": 34573705, + "archived": true, + "created_at": "2018-08-16T08:11:15Z", + "full_name": "secureCodeBox/ansible-role-securecodebox-openshift", + "id": "144957631", + "last_activity_at": "2023-01-28T10:22:09Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [ + "openshift", + "ansible-role", + "ansible", + "security-tools", + "security", + ], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/secureCodeBox", + "web_url": "https://github.com/secureCodeBox/ansible-role-securecodebox-openshift", }, "category": "Git Repository", "description": "A GitHub repository", @@ -50,15 +58,24 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2018-03-01T10:50:05Z", - "full_name": "secureCodeBox/engine", - "id": 123422137, - "last_activity_at": "2020-10-07T08:07:32Z", - "owner_id": 34573705, + "archived": true, + "created_at": "2018-07-30T12:13:41Z", + "full_name": "secureCodeBox/integration-pipeline-jenkins-examples", + "id": "142870794", + "last_activity_at": "2023-01-28T10:22:08Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [ + "security", + "security-automation", + "security-testing", + "jenkins-pipeline", + "jenkinsfile", + "demo", + ], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/engine", + "web_url": "https://github.com/secureCodeBox/integration-pipeline-jenkins-examples", }, "category": "Git Repository", "description": "A GitHub repository", @@ -68,15 +85,17 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2018-03-08T14:20:36Z", - "full_name": "secureCodeBox/scanner-infrastructure-nmap", - "id": 124402117, - "last_activity_at": "2020-09-14T15:40:40Z", - "owner_id": 34573705, + "archived": false, + "created_at": "2019-10-11T11:28:15Z", + "full_name": "secureCodeBox/swagger-petstore-openshift", + "id": "214418800", + "last_activity_at": "2019-10-11T11:37:41Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-nmap", + "web_url": "https://github.com/secureCodeBox/swagger-petstore-openshift", }, "category": "Git Repository", "description": "A GitHub repository", @@ -86,15 +105,17 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2018-03-20T15:48:39Z", - "full_name": "secureCodeBox/nodejs-scanner-scaffolding", - "id": 126042943, - "last_activity_at": "2020-07-16T10:37:40Z", - "owner_id": 34573705, + "archived": true, + "created_at": "2019-04-10T11:39:04Z", + "full_name": "secureCodeBox/ruby-scanner-scaffolding", + "id": "180568880", + "last_activity_at": "2023-01-28T10:22:10Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/nodejs-scanner-scaffolding", + "web_url": "https://github.com/secureCodeBox/ruby-scanner-scaffolding", }, "category": "Git Repository", "description": "A GitHub repository", @@ -104,15 +125,17 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2018-04-06T13:13:14Z", - "full_name": "secureCodeBox/scanner-webserver-nikto", - "id": 128396681, - "last_activity_at": "2020-06-25T10:11:41Z", - "owner_id": 34573705, + "archived": true, + "created_at": "2018-07-18T16:38:18Z", + "full_name": "secureCodeBox/scanner-infrastructure-amass", + "id": "141462466", + "last_activity_at": "2023-06-22T01:51:32Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/scanner-webserver-nikto", + "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-amass", }, "category": "Git Repository", "description": "A GitHub repository", @@ -122,15 +145,17 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2018-04-10T11:17:29Z", - "full_name": "secureCodeBox/scanner-webapplication-zap", - "id": 128920739, - "last_activity_at": "2020-10-07T14:05:09Z", - "owner_id": 34573705, + "archived": false, + "created_at": "2020-03-29T10:40:12Z", + "full_name": "secureCodeBox/zap-extensions", + "id": "251007807", + "last_activity_at": "2020-03-29T10:40:13Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/scanner-webapplication-zap", + "web_url": "https://github.com/secureCodeBox/zap-extensions", }, "category": "Git Repository", "description": "A GitHub repository", @@ -140,15 +165,44 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2018-05-15T11:43:11Z", - "full_name": "secureCodeBox/scanner-infrastructure-sslyze", - "id": 133507929, - "last_activity_at": "2020-07-16T10:52:54Z", - "owner_id": 34573705, + "archived": true, + "created_at": "2019-02-18T14:23:57Z", + "full_name": "secureCodeBox/scanner-infrastructure-ssh", + "id": "171298120", + "last_activity_at": "2023-01-28T10:22:09Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-sslyze", + "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-ssh", + }, + "category": "Git Repository", + "description": "A GitHub repository", + "name": "GitHub Repo", + "osi_layer": "APPLICATION", + "severity": "INFORMATIONAL", + }, + { + "attributes": { + "archived": true, + "created_at": "2018-04-06T13:13:14Z", + "full_name": "secureCodeBox/scanner-webserver-nikto", + "id": "128396681", + "last_activity_at": "2024-08-10T17:59:05Z", + "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", + "topics": [ + "nikto", + "security", + "security-scanner", + "security-automation", + "security-tools", + "microservice", + ], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/scanner-webserver-nikto", }, "category": "Git Repository", "description": "A GitHub repository", @@ -158,13 +212,22 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { + "archived": true, "created_at": "2018-05-24T06:47:00Z", "full_name": "secureCodeBox/scanner-webapplication-arachni", - "id": 134673181, - "last_activity_at": "2020-10-10T10:29:42Z", - "owner_id": 34573705, + "id": "134673181", + "last_activity_at": "2023-03-29T14:00:28Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [ + "arachni", + "security", + "security-scanner", + "security-automation", + "security-tools", + "microservice", + ], "visibility": "public", "web_url": "https://github.com/secureCodeBox/scanner-webapplication-arachni", }, @@ -176,15 +239,17 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2018-07-18T16:38:18Z", - "full_name": "secureCodeBox/scanner-infrastructure-amass", - "id": 141462466, - "last_activity_at": "2020-03-17T18:59:35Z", - "owner_id": 34573705, + "archived": true, + "created_at": "2019-04-10T09:03:38Z", + "full_name": "secureCodeBox/scanner-cms-wpscan", + "id": "180543766", + "last_activity_at": "2023-04-25T07:15:25Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-amass", + "web_url": "https://github.com/secureCodeBox/scanner-cms-wpscan", }, "category": "Git Repository", "description": "A GitHub repository", @@ -194,15 +259,24 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2018-07-30T12:13:41Z", - "full_name": "secureCodeBox/integration-pipeline-jenkins-examples", - "id": 142870794, - "last_activity_at": "2020-09-27T18:59:24Z", - "owner_id": 34573705, + "archived": true, + "created_at": "2018-03-08T14:20:36Z", + "full_name": "secureCodeBox/scanner-infrastructure-nmap", + "id": "124402117", + "last_activity_at": "2025-04-08T19:31:01Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [ + "nmap", + "security", + "security-scanner", + "security-automation", + "security-tools", + "microservice", + ], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/integration-pipeline-jenkins-examples", + "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-nmap", }, "category": "Git Repository", "description": "A GitHub repository", @@ -212,15 +286,24 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2018-08-16T08:11:15Z", - "full_name": "secureCodeBox/ansible-role-securecodebox-openshift", - "id": 144957631, - "last_activity_at": "2019-04-17T13:36:12Z", - "owner_id": 34573705, + "archived": true, + "created_at": "2018-05-15T11:43:11Z", + "full_name": "secureCodeBox/scanner-infrastructure-sslyze", + "id": "133507929", + "last_activity_at": "2023-01-28T10:22:08Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [ + "sslyze", + "security", + "security-scanner", + "security-automation", + "security-tools", + "microservice", + ], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/ansible-role-securecodebox-openshift", + "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-sslyze", }, "category": "Git Repository", "description": "A GitHub repository", @@ -230,15 +313,17 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2018-12-12T15:21:02Z", - "full_name": "secureCodeBox/django-DefectDojo", - "id": 161506648, - "last_activity_at": "2019-01-09T08:41:31Z", - "owner_id": 34573705, + "archived": true, + "created_at": "2019-11-25T13:34:16Z", + "full_name": "secureCodeBox/scanner-infrastructure-ncrack", + "id": "223956455", + "last_activity_at": "2023-01-28T10:22:10Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/django-DefectDojo", + "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-ncrack", }, "category": "Git Repository", "description": "A GitHub repository", @@ -248,15 +333,17 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2019-02-18T14:23:57Z", - "full_name": "secureCodeBox/scanner-infrastructure-ssh", - "id": 171298120, - "last_activity_at": "2020-06-25T10:11:16Z", - "owner_id": 34573705, + "archived": false, + "created_at": "2020-07-07T14:14:16Z", + "full_name": "secureCodeBox/zaproxy", + "id": "277835641", + "last_activity_at": "2024-01-30T22:45:22Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-ssh", + "web_url": "https://github.com/secureCodeBox/zaproxy", }, "category": "Git Repository", "description": "A GitHub repository", @@ -266,15 +353,25 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2019-04-10T09:03:38Z", - "full_name": "secureCodeBox/scanner-cms-wpscan", - "id": 180543766, - "last_activity_at": "2020-06-25T10:12:29Z", - "owner_id": 34573705, + "archived": true, + "created_at": "2020-03-24T14:33:08Z", + "full_name": "secureCodeBox/secureCodeBox-v2", + "id": "249731346", + "last_activity_at": "2024-01-30T22:40:47Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [ + "securecodebox", + "security-tools", + "penetration-testers", + "devsecops", + "kubernetes-operator", + "scanning", + "hacktoberfest", + ], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/scanner-cms-wpscan", + "web_url": "https://github.com/secureCodeBox/secureCodeBox-v2", }, "category": "Git Repository", "description": "A GitHub repository", @@ -284,15 +381,17 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2019-04-10T11:39:04Z", - "full_name": "secureCodeBox/ruby-scanner-scaffolding", - "id": 180568880, - "last_activity_at": "2020-03-11T14:20:03Z", - "owner_id": 34573705, + "archived": true, + "created_at": "2018-03-20T15:48:39Z", + "full_name": "secureCodeBox/nodejs-scanner-scaffolding", + "id": "126042943", + "last_activity_at": "2023-01-28T10:22:08Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/ruby-scanner-scaffolding", + "web_url": "https://github.com/secureCodeBox/nodejs-scanner-scaffolding", }, "category": "Git Repository", "description": "A GitHub repository", @@ -302,15 +401,24 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2019-08-21T13:21:09Z", - "full_name": "secureCodeBox/securecodebox.github.io", - "id": 203588805, - "last_activity_at": "2020-10-16T11:40:25Z", - "owner_id": 34573705, + "archived": true, + "created_at": "2018-04-10T11:17:29Z", + "full_name": "secureCodeBox/scanner-webapplication-zap", + "id": "128920739", + "last_activity_at": "2024-10-03T05:13:23Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [ + "zap", + "security", + "security-scanner", + "security-automation", + "security-tools", + "microservice", + ], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/securecodebox.github.io", + "web_url": "https://github.com/secureCodeBox/scanner-webapplication-zap", }, "category": "Git Repository", "description": "A GitHub repository", @@ -320,15 +428,17 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2019-08-26T14:11:02Z", - "full_name": "secureCodeBox/gatsby-gh-pages-action", - "id": 204489733, - "last_activity_at": "2019-08-26T14:11:05Z", - "owner_id": 34573705, + "archived": true, + "created_at": "2018-03-01T10:50:05Z", + "full_name": "secureCodeBox/engine", + "id": "123422137", + "last_activity_at": "2023-01-28T10:22:08Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/gatsby-gh-pages-action", + "web_url": "https://github.com/secureCodeBox/engine", }, "category": "Git Repository", "description": "A GitHub repository", @@ -338,15 +448,17 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2019-08-27T12:46:48Z", - "full_name": "secureCodeBox/ssh_scan", - "id": 204701677, - "last_activity_at": "2019-08-27T12:53:11Z", - "owner_id": 34573705, + "archived": false, + "created_at": "2020-10-12T09:58:26Z", + "full_name": "secureCodeBox/kubeaudit", + "id": "303349727", + "last_activity_at": "2024-01-30T22:38:13Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/ssh_scan", + "web_url": "https://github.com/secureCodeBox/kubeaudit", }, "category": "Git Repository", "description": "A GitHub repository", @@ -356,15 +468,17 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2019-10-11T11:28:15Z", - "full_name": "secureCodeBox/swagger-petstore-openshift", - "id": 214418800, - "last_activity_at": "2019-10-11T11:37:41Z", - "owner_id": 34573705, + "archived": false, + "created_at": "2021-04-12T13:36:31Z", + "full_name": "secureCodeBox/django-DefectDojo", + "id": "357207085", + "last_activity_at": "2024-01-30T22:35:01Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/swagger-petstore-openshift", + "web_url": "https://github.com/secureCodeBox/django-DefectDojo", }, "category": "Git Repository", "description": "A GitHub repository", @@ -374,13 +488,35 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { + "archived": false, + "created_at": "2019-08-27T12:46:48Z", + "full_name": "secureCodeBox/ssh_scan", + "id": "204701677", + "last_activity_at": "2022-01-25T02:32:59Z", + "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/ssh_scan", + }, + "category": "Git Repository", + "description": "A GitHub repository", + "name": "GitHub Repo", + "osi_layer": "APPLICATION", + "severity": "INFORMATIONAL", + }, + { + "attributes": { + "archived": false, "created_at": "2019-11-19T11:25:21Z", "full_name": "secureCodeBox/nikto", - "id": 222679857, - "last_activity_at": "2020-03-21T12:43:04Z", - "owner_id": 34573705, + "id": "222679857", + "last_activity_at": "2021-08-25T14:24:37Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", "web_url": "https://github.com/secureCodeBox/nikto", }, @@ -392,15 +528,17 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2019-11-25T13:34:16Z", - "full_name": "secureCodeBox/scanner-infrastructure-ncrack", - "id": 223956455, - "last_activity_at": "2020-07-19T11:16:33Z", - "owner_id": 34573705, + "archived": false, + "created_at": "2021-09-23T06:03:50Z", + "full_name": "secureCodeBox/sslyze", + "id": "409468006", + "last_activity_at": "2021-09-23T06:03:51Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/scanner-infrastructure-ncrack", + "web_url": "https://github.com/secureCodeBox/sslyze", }, "category": "Git Repository", "description": "A GitHub repository", @@ -410,15 +548,17 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2020-03-24T14:33:08Z", - "full_name": "secureCodeBox/secureCodeBox-v2", - "id": 249731346, - "last_activity_at": "2020-10-22T08:39:01Z", - "owner_id": 34573705, + "archived": false, + "created_at": "2019-08-21T13:21:09Z", + "full_name": "secureCodeBox/securecodebox.github.io", + "id": "203588805", + "last_activity_at": "2022-04-19T13:33:36Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/secureCodeBox-v2", + "web_url": "https://github.com/secureCodeBox/securecodebox.github.io", }, "category": "Git Repository", "description": "A GitHub repository", @@ -428,15 +568,22 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2020-03-29T10:40:12Z", - "full_name": "secureCodeBox/zap-extensions", - "id": 251007807, - "last_activity_at": "2020-03-29T10:40:13Z", - "owner_id": 34573705, + "archived": true, + "created_at": "2020-09-02T13:39:10Z", + "full_name": "secureCodeBox/documentation", + "id": "292293538", + "last_activity_at": "2024-01-20T09:04:19Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [ + "securecodebox", + "docusaurus", + "documentation", + "hacktoberfest", + ], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/zap-extensions", + "web_url": "https://github.com/secureCodeBox/documentation", }, "category": "Git Repository", "description": "A GitHub repository", @@ -446,15 +593,17 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2020-07-07T14:14:16Z", - "full_name": "secureCodeBox/zaproxy", - "id": 277835641, - "last_activity_at": "2020-07-07T14:14:18Z", - "owner_id": 34573705, + "archived": false, + "created_at": "2023-03-21T19:51:07Z", + "full_name": "secureCodeBox/www-community", + "id": "617150115", + "last_activity_at": "2024-03-14T15:30:35Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/zaproxy", + "web_url": "https://github.com/secureCodeBox/www-community", }, "category": "Git Repository", "description": "A GitHub repository", @@ -464,15 +613,17 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2020-08-07T17:58:52Z", - "full_name": "secureCodeBox/static-export", - "id": 285890805, - "last_activity_at": "2020-08-12T12:53:05Z", - "owner_id": 34573705, + "archived": false, + "created_at": "2023-10-13T14:15:48Z", + "full_name": "secureCodeBox/landscape", + "id": "704559693", + "last_activity_at": "2024-07-11T19:08:33Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", - "visibility": "private", - "web_url": "https://github.com/secureCodeBox/static-export", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/landscape", }, "category": "Git Repository", "description": "A GitHub repository", @@ -482,15 +633,17 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2020-08-17T15:09:19Z", - "full_name": "secureCodeBox/telemetry", - "id": 288212154, - "last_activity_at": "2020-09-01T10:08:23Z", - "owner_id": 34573705, + "archived": false, + "created_at": "2024-08-09T14:48:36Z", + "full_name": "secureCodeBox/DevSecOps-MaturityModel", + "id": "840369455", + "last_activity_at": "2024-08-09T14:48:36Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/telemetry", + "web_url": "https://github.com/secureCodeBox/DevSecOps-MaturityModel", }, "category": "Git Repository", "description": "A GitHub repository", @@ -500,15 +653,57 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2020-09-02T13:39:10Z", - "full_name": "secureCodeBox/documentation", - "id": 292293538, - "last_activity_at": "2020-10-21T14:28:35Z", - "owner_id": 34573705, + "archived": false, + "created_at": "2021-01-06T14:27:46Z", + "full_name": "secureCodeBox/gitleaks", + "id": "327336031", + "last_activity_at": "2024-01-30T22:39:59Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", + "topics": [], "visibility": "public", - "web_url": "https://github.com/secureCodeBox/documentation", + "web_url": "https://github.com/secureCodeBox/gitleaks", + }, + "category": "Git Repository", + "description": "A GitHub repository", + "name": "GitHub Repo", + "osi_layer": "APPLICATION", + "severity": "INFORMATIONAL", + }, + { + "attributes": { + "archived": false, + "created_at": "2025-04-18T19:36:30Z", + "full_name": "secureCodeBox/scb-cascades-demo", + "id": "968815564", + "last_activity_at": "2025-04-24T11:47:52Z", + "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/scb-cascades-demo", + }, + "category": "Git Repository", + "description": "A GitHub repository", + "name": "GitHub Repo", + "osi_layer": "APPLICATION", + "severity": "INFORMATIONAL", + }, + { + "attributes": { + "archived": false, + "created_at": "2024-12-29T17:07:02Z", + "full_name": "secureCodeBox/scan-throttler", + "id": "909750535", + "last_activity_at": "2025-08-19T14:02:18Z", + "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/scan-throttler", }, "category": "Git Repository", "description": "A GitHub repository", @@ -518,15 +713,24 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2020-09-03T13:08:22Z", - "full_name": "secureCodeBox/ui", - "id": 292573194, - "last_activity_at": "2020-10-07T14:38:02Z", - "owner_id": 34573705, + "archived": false, + "created_at": "2021-01-06T09:59:17Z", + "full_name": "secureCodeBox/defectdojo-client-java", + "id": "327269915", + "last_activity_at": "2025-10-20T08:29:33Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", - "visibility": "private", - "web_url": "https://github.com/secureCodeBox/ui", + "topics": [ + "defectdojo", + "owasp", + "client-library", + "java", + "gradle", + "hacktoberfest", + ], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/defectdojo-client-java", }, "category": "Git Repository", "description": "A GitHub repository", @@ -536,15 +740,49 @@ test("should properly parse git-scanner json file", async () => { }, { "attributes": { - "created_at": "2020-09-28T08:58:53Z", - "full_name": "secureCodeBox/internal", - "id": 299249650, - "last_activity_at": "2020-10-21T15:11:56Z", - "owner_id": 34573705, + "archived": false, + "created_at": "2020-08-17T15:09:19Z", + "full_name": "secureCodeBox/telemetry", + "id": "288212154", + "last_activity_at": "2025-11-20T07:43:05Z", + "owner_id": "34573705", "owner_name": "secureCodeBox", "owner_type": "Organization", - "visibility": "private", - "web_url": "https://github.com/secureCodeBox/internal", + "topics": [], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/telemetry", + }, + "category": "Git Repository", + "description": "A GitHub repository", + "name": "GitHub Repo", + "osi_layer": "APPLICATION", + "severity": "INFORMATIONAL", + }, + { + "attributes": { + "archived": false, + "created_at": "2017-02-02T09:48:05Z", + "full_name": "secureCodeBox/secureCodeBox", + "id": "80711933", + "last_activity_at": "2025-11-24T10:04:46Z", + "owner_id": "34573705", + "owner_name": "secureCodeBox", + "owner_type": "Organization", + "topics": [ + "security", + "security-automation", + "security-tools", + "security-testing", + "securecodebox", + "devsecops", + "kubernetes", + "kubernetes-operator", + "owasp", + "hacktoberfest", + "zaproxy", + ], + "visibility": "public", + "web_url": "https://github.com/secureCodeBox/secureCodeBox", }, "category": "Git Repository", "description": "A GitHub repository", diff --git a/scanners/git-repo-scanner/scanner/.dockerignore b/scanners/git-repo-scanner/scanner/.dockerignore index d4ea27fec2..ddb1ff28e6 100644 --- a/scanners/git-repo-scanner/scanner/.dockerignore +++ b/scanners/git-repo-scanner/scanner/.dockerignore @@ -2,6 +2,4 @@ # # SPDX-License-Identifier: Apache-2.0 -**/.pytest_cache -**/__pycache__ -/tests +/test diff --git a/scanners/git-repo-scanner/scanner/Dockerfile b/scanners/git-repo-scanner/scanner/Dockerfile index d03a8a91aa..751c628ef5 100644 --- a/scanners/git-repo-scanner/scanner/Dockerfile +++ b/scanners/git-repo-scanner/scanner/Dockerfile @@ -2,10 +2,29 @@ # # SPDX-License-Identifier: Apache-2.0 -FROM docker.io/python:3-alpine -COPY . /scripts/ -RUN pip install -r /scripts/requirements.txt -RUN adduser -S -H -u 1001 gitreposcanner -USER 1001 -WORKDIR /scripts -ENTRYPOINT ["python", "-m", "git_repo_scanner"] +# Build the pull-secret-extractor binary +FROM --platform=$BUILDPLATFORM golang:1.25.7 AS builder + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +COPY main.go main.go +COPY internal/ internal/ + +# Build +ARG TARGETOS TARGETARCH +RUN GOOS="$TARGETOS" GOARCH="$TARGETARCH" CGO_ENABLED=0 go build -a -o git-repo-scanner main.go + +# Use distroless as minimal base image to package the manager binary +# Refer to https://github.com/GoogleContainerTools/distroless for more details +FROM gcr.io/distroless/static:nonroot +WORKDIR / +COPY --from=builder /workspace/git-repo-scanner . + +ENTRYPOINT ["/git-repo-scanner"] diff --git a/scanners/git-repo-scanner/scanner/git_repo_scanner/__main__.py b/scanners/git-repo-scanner/scanner/git_repo_scanner/__main__.py deleted file mode 100644 index 093c0acf97..0000000000 --- a/scanners/git-repo-scanner/scanner/git_repo_scanner/__main__.py +++ /dev/null @@ -1,188 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -import argparse -import json -import logging -import sys -from datetime import datetime, timedelta, timezone -from pathlib import Path - -import github -import gitlab -import pytz - -# https://pypi.org/project/pytimeparse/ -from pytimeparse.timeparse import timeparse - -from git_repo_scanner.abstract_scanner import AbstractScanner -from git_repo_scanner.github_scanner import GitHubScanner -from git_repo_scanner.gitlab_scanner import GitLabScanner - -log_format = "%(asctime)s - %(levelname)-7s - %(name)s - %(message)s" -logging.basicConfig(level=logging.INFO, format=log_format) -logger = logging.getLogger("git_repo_scanner") - -now_utc = datetime.now(timezone.utc) - - -def main(): - args = get_parser_args() - - if not args.git_type: - logger.info("Argument error: No git type specified") - sys.exit(1) - - findings = process(args) - - logger.info("Write findings to file...") - write_findings_to_file(args, findings) - logger.info("Finished!") - - -def process(args): - scanner: AbstractScanner - - if args.git_type == "gitlab": - scanner = GitLabScanner( - url=args.url, - access_token=args.access_token, - group=args.group, - ignored_groups=args.ignore_groups, - ignore_repos=args.ignore_repos, - obey_rate_limit=args.obey_rate_limit, - annotate_latest_commit_id=args.annotate_latest_commit_id, - ) - elif args.git_type == "github": - scanner = GitHubScanner( - url=args.url, - access_token=args.access_token, - organization=args.organization, - ignore_repos=args.ignore_repos, - obey_rate_limit=args.obey_rate_limit, - annotate_latest_commit_id=args.annotate_latest_commit_id, - ) - else: - logger.info("Argument error: Unknown git type") - sys.exit(1) - - try: - return scanner.process( - args.activity_since_duration, args.activity_until_duration - ) - except argparse.ArgumentError as e: - logger.error(f"Argument error: {e}") - sys.exit(1) - except gitlab.exceptions.GitlabAuthenticationError: - logger.info("No permission. Check your access token.") - sys.exit(1) - except github.GithubException as e: - logger.error(f'Github API Exception: {e.status} -> {e.data["message"]}') - sys.exit(2) - except gitlab.GitlabError as e: - logger.error(f"Gitlab API Exception: {e}") - sys.exit(2) - except Exception as e: - logger.error(f"Unexpected error: {e}") - sys.exit(3) - - -def write_findings_to_file(args, findings): - Path(args.file_output).mkdir(parents=True, exist_ok=True) - with open(f"{args.file_output}/git-repo-scanner-findings.json", "w") as out: - json.dump(findings, out) - - -def parse_duration_as_datetime(val: str): - try: - parsed = timeparse(val) - if parsed is None: - raise argparse.ArgumentTypeError(f"Not a valid duration: {val}.") - delta = timedelta(seconds=parsed) - return now_utc - delta - except Exception: - raise argparse.ArgumentTypeError(f"Not a valid duration: {val}.") - - -def get_parser_args(args=None): - parser = argparse.ArgumentParser( - prog="git_repo_scanner", - description="Scan public or private git repositories of organizations or groups", - ) - parser.add_argument( - "--git-type", - help="Repository type can be github or GitLab", - choices=["github", "gitlab"], - required=True, - ) - parser.add_argument( - "--file-output", help="The path of the output file", required=True - ), - parser.add_argument( - "--url", help="The GitLab url or a GitHub enterprise api url.", required=False - ) - parser.add_argument( - "--access-token", help="An access token for authentication", required=False - ) - parser.add_argument( - "--organization", - help="The name of the GitHub organization to scan", - required=False, - ) - parser.add_argument( - "--group", help="The id of the GitLab group to scan", type=int, required=False - ) - parser.add_argument( - "--ignore-repos", - help="A list of repo ids to ignore", - action="extend", - nargs="+", - type=int, - default=[], - required=False, - ) - parser.add_argument( - "--ignore-groups", - help="A list of GitLab group ids to ignore", - action="extend", - nargs="+", - type=int, - default=[], - required=False, - ) - parser.add_argument( - "--obey-rate-limit", - help="True to obey the rate limit of the GitLab or GitHub server (default), otherwise False", - type=bool, - default=True, - required=False, - ) - parser.add_argument( - "--annotate-latest-commit-id", - help="Annotate the results with the latest commit hash of the main branch of the repository. " - "Will result in up to two extra API hits per repository", - type=bool, - default=False, - required=False, - ) - parser.add_argument( - "--activity-since-duration", - help="Return git repo findings with repo activity (e.g. commits) more recent than a specific " - "date expressed by a duration (now - duration)", - type=parse_duration_as_datetime, - required=False, - ) - parser.add_argument( - "--activity-until-duration", - help="Return git repo findings with repo activity (e.g. commits) older than a specific date " - "expressed by a duration (now - duration)", - type=parse_duration_as_datetime, - required=False, - ) - - return parser.parse_args(args) - - -if __name__ == "__main__": - main() diff --git a/scanners/git-repo-scanner/scanner/git_repo_scanner/abstract_scanner.py b/scanners/git-repo-scanner/scanner/git_repo_scanner/abstract_scanner.py deleted file mode 100644 index 175b247379..0000000000 --- a/scanners/git-repo-scanner/scanner/git_repo_scanner/abstract_scanner.py +++ /dev/null @@ -1,61 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -import abc -from datetime import datetime -from typing import Dict, List, Optional - -FINDING = Dict[str, any] - - -class AbstractScanner(abc.ABC): - @property - @abc.abstractmethod - def git_type(self) -> str: - raise NotImplementedError() - - @abc.abstractmethod - def process( - self, start_time: Optional[datetime] = None, end_time: Optional[datetime] = None - ) -> List[FINDING]: - raise NotImplementedError() - - def _create_finding( - self, - repo_id: str, - web_url: str, - full_name: str, - owner_type: str, - owner_id: str, - owner_name: str, - created_at: str, - last_activity_at: str, - visibility: str, - archived: bool, - topics: list, - last_commit_id: str = None, - ) -> FINDING: - finding = { - "name": f"{self.git_type} Repo", - "description": f"A {self.git_type} repository", - "category": "Git Repository", - "osi_layer": "APPLICATION", - "severity": "INFORMATIONAL", - "attributes": { - "id": repo_id, - "web_url": web_url, - "full_name": full_name, - "owner_type": owner_type, - "owner_id": owner_id, - "topics": topics, - "owner_name": owner_name, - "created_at": created_at, - "last_activity_at": last_activity_at, - "visibility": visibility, - "archived": archived, - }, - } - if last_commit_id is not None: - finding["attributes"]["last_commit_id"] = last_commit_id - return finding diff --git a/scanners/git-repo-scanner/scanner/git_repo_scanner/github_scanner.py b/scanners/git-repo-scanner/scanner/git_repo_scanner/github_scanner.py deleted file mode 100644 index 2a02ca43f5..0000000000 --- a/scanners/git-repo-scanner/scanner/git_repo_scanner/github_scanner.py +++ /dev/null @@ -1,190 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -import argparse -import logging -import time -from calendar import timegm -from datetime import datetime, timezone -from typing import Optional, List - -import github -from github.Organization import Organization -from github.PaginatedList import PaginatedList -from github.Repository import Repository - -from git_repo_scanner.abstract_scanner import AbstractScanner, FINDING - - -class GitHubScanner(AbstractScanner): - LOGGER = logging.getLogger("git_repo_scanner") - - def __init__( - self, - url: Optional[str], - access_token: Optional[str], - organization: str, - ignore_repos: List[int], - obey_rate_limit: bool = True, - annotate_latest_commit_id: bool = False, - ) -> None: - super().__init__() - if not organization: - raise argparse.ArgumentError( - None, "Organization required for GitHub connection." - ) - if url and not access_token: - raise argparse.ArgumentError( - None, "Access token required for GitHub connection." - ) - - self._url = url - self._access_token = access_token - self._organization = organization - self._ignore_repos = ignore_repos - self._obey_rate_limit = obey_rate_limit - self._annotate_latest_commit_id = annotate_latest_commit_id - self._gh: Optional[github.Github] = None - - @property - def git_type(self) -> str: - return "GitHub" - - def process( - self, start_time: Optional[datetime] = None, end_time: Optional[datetime] = None - ) -> List[FINDING]: - self._setup() - return self._process_repos(start_time, end_time) - - def _process_repos( - self, start_time: Optional[datetime], end_time: Optional[datetime] - ): - findings = [] - org: Organization = self._gh.get_organization(self._organization) - - repos: PaginatedList[Repository] = org.get_repos( - type="all", sort="pushed", direction="asc" - ) - - if start_time: - repos = org.get_repos(type="all", sort="pushed", direction="desc") - - for i in range(repos.totalCount): - self._process_repos_page(findings, repos.get_page(i), start_time, end_time) - return findings - - def _process_repos_page( - self, - findings: List[FINDING], - repos: List[Repository], - start_time: Optional[datetime] = None, - end_time: Optional[datetime] = None, - ): - repo: Repository - for repo in repos: - if repo.id not in self._ignore_repos: - self.LOGGER.info( - f"{len(findings) + 1} - Name: {repo.name} - LastUpdate: {repo.updated_at} - LastPush: {repo.pushed_at}" - ) - - if (start_time or end_time) and not self._check_repo_is_in_time_frame( - repo.pushed_at, start_time, end_time - ): - break - - findings.append(self._create_finding_from_repo(repo)) - self._respect_github_ratelimit() - - def _check_repo_is_in_time_frame( - self, - pushed_at: datetime, - start_time: Optional[datetime] = None, - end_time: Optional[datetime] = None, - ): - # Explicitly set timezone of pushed_at, as it is not set by the library (but is in UTC) - pushed_at = pushed_at.replace(tzinfo=timezone.utc) - if start_time: - if pushed_at > start_time: - return True - else: - self.LOGGER.info( - f"Reached activity limit! Ignoring all repos with activity since `{start_time}`." - ) - return False - elif end_time: - if pushed_at < end_time: - return True - else: - self.LOGGER.info( - f"Reached activity limit! Ignoring all repos with activity until `{end_time}`." - ) - return False - - def _respect_github_ratelimit(self): - if self._obey_rate_limit: - api_limit = self._gh.get_rate_limit().core - reset_timestamp = timegm(api_limit.reset.timetuple()) - # add 5 seconds to be sure the rate limit has been reset - seconds_until_reset = reset_timestamp - timegm(time.gmtime()) + 5 - sleep_time = seconds_until_reset / api_limit.remaining - - self.LOGGER.info( - "Checking Rate-Limit (" - + str(self._obey_rate_limit) - + ") [remainingApiCalls: " - + str(api_limit.remaining) - + ", seconds_until_reset: " - + str(seconds_until_reset) - + ", sleepTime: " - + str(sleep_time) - + "]" - ) - time.sleep(sleep_time) - - def _setup(self): - if self._url: - self._setup_with_url() - else: - self._setup_without_url() - - def _setup_without_url(self): - if self._access_token: - self._gh = github.Github(self._access_token) - else: - self._gh = github.Github() - - def _setup_with_url(self): - if self._access_token: - self._gh = github.Github( - base_url=self._url, login_or_token=self._access_token - ) - else: - raise argparse.ArgumentError( - None, "Access token required for github enterprise authentication." - ) - - def _create_finding_from_repo(self, repo: Repository) -> FINDING: - latest_commit: str = None - if self._annotate_latest_commit_id: - try: - latest_commit = repo.get_commits()[0].sha - except Exception: - self.LOGGER.warn( - "Could not identify the latest commit ID - repository without commits?" - ) - latest_commit = "" - return super()._create_finding( - str(repo.id), - repo.html_url, - repo.full_name, - repo.owner.type, - str(repo.owner.id), - repo.owner.name, - repo.created_at.strftime("%Y-%m-%dT%H:%M:%SZ"), - repo.updated_at.strftime("%Y-%m-%dT%H:%M:%SZ"), - "private" if repo.private else "public", - repo.archived, - repo.get_topics(), - latest_commit, - ) diff --git a/scanners/git-repo-scanner/scanner/git_repo_scanner/gitlab_scanner.py b/scanners/git-repo-scanner/scanner/git_repo_scanner/gitlab_scanner.py deleted file mode 100644 index 70140bca41..0000000000 --- a/scanners/git-repo-scanner/scanner/git_repo_scanner/gitlab_scanner.py +++ /dev/null @@ -1,154 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -import argparse -import logging -from datetime import datetime -from typing import List, Optional - -import gitlab -from gitlab.v4.objects import Project, ProjectManager - -from git_repo_scanner.abstract_scanner import AbstractScanner, FINDING - -logger = logging.getLogger("git_repo_scanner") - - -class GitLabScanner(AbstractScanner): - LOGGER = logging.getLogger("git_repo_scanner") - - def __init__( - self, - url: str, - access_token: str, - group: Optional[int], - ignored_groups: List[int], - ignore_repos: List[int], - obey_rate_limit: bool = True, - annotate_latest_commit_id: bool = False, - ) -> None: - super().__init__() - if not url: - raise argparse.ArgumentError(None, "URL required for GitLab connection.") - if not access_token: - raise argparse.ArgumentError( - None, "Access token required for GitLab authentication." - ) - - self._url = url - self._access_token = access_token - self._group = group - self._ignored_groups = ignored_groups - self._ignore_repos = ignore_repos - self._obey_rate_limit = obey_rate_limit - self._annotate_latest_commit_id = annotate_latest_commit_id - self._gl: Optional[gitlab.Gitlab] = None - - @property - def git_type(self) -> str: - return "GitLab" - - def process( - self, start_time: Optional[datetime] = None, end_time: Optional[datetime] = None - ) -> List[FINDING]: - self._authenticate() - - projects: List[Project] = self._get_projects(start_time, end_time) - return self._process_projects(projects) - - def _group_project_to_project(self, group_project): - # The GitLab API library gives us a GroupProject object, which has limited functionality. - # This function turns the GroupProject into a "real" project, which allows us to get the - # list of commits and include the SHA1 of the latest commit in the output later - return self._gl.projects.get(group_project.id, lazy=True) - - def _get_projects( - self, start_time: Optional[datetime], end_time: Optional[datetime] - ): - logger.info( - f"Get GitLab repositories with last activity between {start_time} and {end_time}." - ) - - project_manager: ProjectManager = self._gl.projects - options = dict( - all=True, - order_by="last_activity_at", - sort="desc", - obey_rate_limit=self._obey_rate_limit, - max_retries=12, - ) - if start_time is not None: - options["last_activity_after"] = start_time - if end_time is not None: - options["last_activity_before"] = end_time - - if self._group: - options["include_subgroups"] = True - project_manager = self._gl.groups.get(self._group).projects - - return project_manager.list(**options) - - def _process_projects(self, projects: List[Project]) -> List[FINDING]: - project_count = len(projects) - return [ - self._create_finding_from_project(project, i, project_count) - for i, project in enumerate(projects) - if self._is_not_ignored(project) - ] - - def _authenticate(self): - logger.info("Start GitLab authentication") - try: - self._gl = gitlab.Gitlab(self._url, private_token=self._access_token) - self._gl.auth() - except gitlab.exceptions.GitlabAuthenticationError: - self._gl = gitlab.Gitlab(self._url, oauth_token=self._access_token) - self._gl.auth() - - logger.info("GitLab authentication succeeded") - - def _is_not_ignored(self, project: Project) -> bool: - id_project = project.id - kind = project.namespace["kind"] - id_namespace = project.namespace["id"] - if id_project in self._ignore_repos: - return False - if kind == "group" and id_namespace in self._ignored_groups: - return False - return True - - def _create_finding_from_project( - self, project: Project, index: int, total: int - ) -> FINDING: - logger.info( - f"({index + 1}/{total}) Add finding for repo {project.name} with last activity at " - f"{datetime.fromisoformat(project.last_activity_at)}" - ) - - # Retrieve the latest commit ID - latest_commit_id: str = None - if self._annotate_latest_commit_id: - try: - latest_commit_id = ( - self._group_project_to_project(project).commits.list()[0].id - ) - except Exception as e: - logger.warn( - "Could not identify the latest commit ID - repository without commits?" - ) - latest_commit_id = "" - return super()._create_finding( - project.id, - project.web_url, - project.path_with_namespace, - project.namespace["kind"], - project.namespace["id"], - project.namespace["name"], - project.created_at, - project.last_activity_at, - project.visibility, - project.archived, - project.topics, - latest_commit_id, - ) diff --git a/scanners/git-repo-scanner/scanner/go.mod b/scanners/git-repo-scanner/scanner/go.mod new file mode 100644 index 0000000000..89efde301c --- /dev/null +++ b/scanners/git-repo-scanner/scanner/go.mod @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +module github.com/secureCodeBox/scanners/git-repo-scanner/scanner + +go 1.25.4 + +require ( + github.com/google/go-github/v79 v79.0.0 + gitlab.com/gitlab-org/api/client-go v0.160.1 + golang.org/x/oauth2 v0.30.0 +) + +require ( + github.com/google/go-querystring v1.1.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-retryablehttp v0.7.8 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect + golang.org/x/time v0.12.0 // indirect +) diff --git a/scanners/git-repo-scanner/scanner/go.sum b/scanners/git-repo-scanner/scanner/go.sum new file mode 100644 index 0000000000..eb2dcdd019 --- /dev/null +++ b/scanners/git-repo-scanner/scanner/go.sum @@ -0,0 +1,38 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-github/v79 v79.0.0 h1:MdodQojuFPBhmtwHiBcIGLw/e/wei2PvFX9ndxK0X4Y= +github.com/google/go-github/v79 v79.0.0/go.mod h1:OAFbNhq7fQwohojb06iIIQAB9CBGYLq999myfUFnrS4= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48= +github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +gitlab.com/gitlab-org/api/client-go v0.160.1 h1:7kEgo1yQ3ZMRps/2JbXzqbRb4Rs8n2ECkAv+6MadJw8= +gitlab.com/gitlab-org/api/client-go v0.160.1/go.mod h1:YqKcnxyV9OPAL5U99mpwBVEgBPz1PK/3qwqq/3h6bao= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/operator/Chart.lock.license b/scanners/git-repo-scanner/scanner/go.sum.license similarity index 100% rename from operator/Chart.lock.license rename to scanners/git-repo-scanner/scanner/go.sum.license diff --git a/scanners/git-repo-scanner/scanner/internal/config/config.go b/scanners/git-repo-scanner/scanner/internal/config/config.go new file mode 100644 index 0000000000..e11c5b7767 --- /dev/null +++ b/scanners/git-repo-scanner/scanner/internal/config/config.go @@ -0,0 +1,224 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +package config + +import ( + "flag" + "fmt" + "strconv" + "strings" + "time" + + "github.com/secureCodeBox/scanners/git-repo-scanner/scanner/internal/duration" +) + +type Config struct { + GitType string + FileOutput string + URL string + AccessToken string + Organization string + Group *int + IgnoreRepos []int64 + IgnoreGroups []int + ObeyRateLimit bool + AnnotateLatestCommitID bool + ActivitySinceDuration *time.Duration + ActivityUntilDuration *time.Duration +} + +func ParseFlags() (*Config, error) { + config := &Config{} + + // Define flags + flag.StringVar(&config.GitType, "git-type", "", "Repository type can be GitHub or GitLab") + flag.StringVar(&config.FileOutput, "file-output", "", "The path of the output file") + flag.StringVar(&config.URL, "url", "", "The GitLab url or a GitHub enterprise api url") + flag.StringVar(&config.AccessToken, "access-token", "", "An access token for authentication") + flag.StringVar(&config.Organization, "organization", "", "The name of the GitHub organization to scan") + + var groupStr string + flag.StringVar(&groupStr, "group", "", "The id of the GitLab group to scan") + + var ignoreReposStr string + flag.StringVar(&ignoreReposStr, "ignore-repos", "", "Comma-separated list of repo ids to ignore") + + var ignoreGroupsStr string + flag.StringVar(&ignoreGroupsStr, "ignore-groups", "", "Comma-separated list of GitLab group ids to ignore") + + flag.BoolVar(&config.ObeyRateLimit, "obey-rate-limit", true, + "True to obey the rate limit of the GitLab or GitHub server (default), otherwise false") + flag.BoolVar(&config.AnnotateLatestCommitID, "annotate-latest-commit-id", false, + "Annotate the results with the latest commit hash of the main branch of the repository") + + var activitySinceStr string + var activityUntilStr string + flag.StringVar(&activitySinceStr, "activity-since-duration", "", + "Return git repo findings with repo activity more recent than a specific duration (e.g., '7d', '2w', '1h')") + flag.StringVar(&activityUntilStr, "activity-until-duration", "", + "Return git repo findings with repo activity older than a specific duration (e.g., '7d', '2w', '1h')") + + flag.Parse() + + config.GitType = normalizeGitType(config.GitType) + + if err := config.validate(); err != nil { + flag.Usage() + return nil, err + } + + if err := config.parseOptionalFields(groupStr, ignoreReposStr, ignoreGroupsStr, activitySinceStr, activityUntilStr); err != nil { + return nil, err + } + + return config, nil +} + +func normalizeGitType(gitType string) string { + switch strings.ToLower(gitType) { + case "github": + return "GitHub" + case "gitlab": + return "GitLab" + default: + return gitType + } +} + +func (c *Config) validate() error { + if c.GitType == "" { + return fmt.Errorf("--git-type is required") + } + + if c.GitType != "GitHub" && c.GitType != "GitLab" { + return fmt.Errorf("invalid git-type: %s. Must be 'GitHub' or 'GitLab'", c.GitType) + } + + if c.FileOutput == "" { + return fmt.Errorf("--file-output is required") + } + + // Validate GitLab specific requirements + if c.GitType == "GitLab" && c.URL == "" { + return fmt.Errorf("--url is required for GitLab") + } + + // Validate GitHub specific requirements + if c.GitType == "GitHub" && c.Organization == "" { + return fmt.Errorf("--organization is required for GitHub") + } + + return nil +} + +func (c *Config) parseOptionalFields(groupStr, ignoreReposStr, ignoreGroupsStr, activitySinceStr, activityUntilStr string) error { + if groupStr != "" { + group, err := strconv.Atoi(groupStr) + if err != nil { + return fmt.Errorf("invalid group id: %s", groupStr) + } + c.Group = &group + } + + if ignoreReposStr != "" { + repos, err := parseIntListAsInt64(ignoreReposStr) + if err != nil { + return fmt.Errorf("invalid repo ids in ignore-repos: %w", err) + } + c.IgnoreRepos = repos + } + + if ignoreGroupsStr != "" { + groups, err := parseIntListAsInt(ignoreGroupsStr) + if err != nil { + return fmt.Errorf("invalid group ids in ignore-groups: %w", err) + } + c.IgnoreGroups = groups + } + + if activitySinceStr != "" { + d, err := duration.Parse(activitySinceStr) + if err != nil { + return fmt.Errorf("invalid activity-since-duration: %w", err) + } + c.ActivitySinceDuration = &d + } + + if activityUntilStr != "" { + d, err := duration.Parse(activityUntilStr) + if err != nil { + return fmt.Errorf("invalid activity-until-duration: %w", err) + } + c.ActivityUntilDuration = &d + } + + return nil +} + +func parseIntListAsInt64(s string) ([]int64, error) { + var result []int64 + parts := strings.SplitSeq(s, ",") + + for part := range parts { + part = strings.TrimSpace(part) + if part == "" { + continue + } + + id, err := strconv.ParseInt(part, 10, 64) + if err != nil { + return nil, fmt.Errorf("invalid id: %s", part) + } + result = append(result, id) + } + + return result, nil +} + +func parseIntListAsInt(s string) ([]int, error) { + var result []int + parts := strings.SplitSeq(s, ",") + + for part := range parts { + part = strings.TrimSpace(part) + if part == "" { + continue + } + + id, err := strconv.Atoi(part) + if err != nil { + return nil, fmt.Errorf("invalid id: %s", part) + } + result = append(result, id) + } + + return result, nil +} + +// GetTimeFrame returns the start and end times based on duration configuration +func (c *Config) GetTimeFrame() (*time.Time, *time.Time, error) { + if c.ActivitySinceDuration == nil && c.ActivityUntilDuration == nil { + return nil, nil, nil + } + + now := time.Now().UTC() + var startTime, endTime *time.Time + + if c.ActivitySinceDuration != nil { + t := now.Add(-*c.ActivitySinceDuration) + startTime = &t + } + + if c.ActivityUntilDuration != nil { + t := now.Add(-*c.ActivityUntilDuration) + endTime = &t + } + + if startTime != nil && endTime != nil && startTime.After(*endTime) { + return nil, nil, fmt.Errorf("activity-since-duration must be greater than activity-until-duration") + } + + return startTime, endTime, nil +} diff --git a/scanners/git-repo-scanner/scanner/internal/config/config_test.go b/scanners/git-repo-scanner/scanner/internal/config/config_test.go new file mode 100644 index 0000000000..d32171d4fe --- /dev/null +++ b/scanners/git-repo-scanner/scanner/internal/config/config_test.go @@ -0,0 +1,234 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +package config + +import ( + "strings" + "testing" + "time" +) + +const fileOutput = "output.json" + +func TestValidateConfig(t *testing.T) { + tests := []struct { + name string + config Config + wantErr bool + errMsg string + }{ + { + name: "missing git-type", + config: Config{FileOutput: fileOutput}, + wantErr: true, + errMsg: "--git-type is required", + }, + { + name: "invalid git-type", + config: Config{GitType: "Bitbucket", FileOutput: fileOutput}, + wantErr: true, + errMsg: "invalid git-type", + }, + { + name: "GitLab missing URL", + config: Config{GitType: "GitLab", FileOutput: fileOutput}, + wantErr: true, + errMsg: "--url is required for GitLab", + }, + { + name: "GitHub missing organization", + config: Config{GitType: "GitHub", FileOutput: fileOutput}, + wantErr: true, + errMsg: "--organization is required for GitHub", + }, + { + name: "valid GitHub config", + config: Config{ + GitType: "GitHub", + FileOutput: fileOutput, + Organization: "test-org", + }, + wantErr: false, + }, + { + name: "valid GitLab config", + config: Config{ + GitType: "GitLab", + FileOutput: fileOutput, + URL: "https://gitlab.com", + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.config.validate() + if (err != nil) != tt.wantErr { + t.Errorf("validate() error = %v, wantErr %v", err, tt.wantErr) + } + if err != nil && tt.errMsg != "" && !strings.Contains(err.Error(), tt.errMsg) { + t.Errorf("error message = %v, want to contain %v", err.Error(), tt.errMsg) + } + }) + } +} + +func TestParseOptionalFields(t *testing.T) { + tests := []struct { + name string + groupStr string + ignoreReposStr string + ignoreGroupsStr string + activitySinceStr string + activityUntilStr string + wantErr bool + validateResult func(t *testing.T, c *Config) + }{ + { + name: "valid group ID", + groupStr: "123", + wantErr: false, + validateResult: func(t *testing.T, c *Config) { + if c.Group == nil || *c.Group != 123 { + t.Errorf("expected group to be 123, got %v", c.Group) + } + }, + }, + { + name: "invalid group ID", + groupStr: "abc", + wantErr: true, + }, + { + name: "valid ignore repos list", + ignoreReposStr: "1,2,3,456", + wantErr: false, + validateResult: func(t *testing.T, c *Config) { + expected := []int64{1, 2, 3, 456} + if len(c.IgnoreRepos) != len(expected) { + t.Errorf("expected %d repos, got %d", len(expected), len(c.IgnoreRepos)) + } + for i, v := range expected { + if c.IgnoreRepos[i] != v { + t.Errorf("repo[%d]: expected %d, got %d", i, v, c.IgnoreRepos[i]) + } + } + }, + }, + { + name: "ignore repos with spaces", + ignoreReposStr: " 1 , 2 , 3 ", + wantErr: false, + validateResult: func(t *testing.T, c *Config) { + if len(c.IgnoreRepos) != 3 { + t.Errorf("expected 3 repos, got %d", len(c.IgnoreRepos)) + } + }, + }, + { + name: "invalid ignore repos", + ignoreReposStr: "1,abc,3", + wantErr: true, + }, + { + name: "valid activity durations", + activitySinceStr: "7d", + activityUntilStr: "1d", + wantErr: false, + validateResult: func(t *testing.T, c *Config) { + if c.ActivitySinceDuration == nil { + t.Error("ActivitySinceDuration should not be nil") + } + if c.ActivityUntilDuration == nil { + t.Error("ActivityUntilDuration should not be nil") + } + }, + }, + { + name: "invalid activity-since duration", + activitySinceStr: "invalid", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Config{} + err := c.parseOptionalFields(tt.groupStr, tt.ignoreReposStr, tt.ignoreGroupsStr, + tt.activitySinceStr, tt.activityUntilStr) + + if (err != nil) != tt.wantErr { + t.Errorf("parseOptionalFields() error = %v, wantErr %v", err, tt.wantErr) + } + + if !tt.wantErr && tt.validateResult != nil { + tt.validateResult(t, c) + } + }) + } +} + +func TestGetTimeFrame(t *testing.T) { + sevenDays := 7 * 24 * time.Hour + oneDay := 24 * time.Hour + + tests := []struct { + name string + activitySinceDuration *time.Duration + activityUntilDuration *time.Duration + wantErr bool + errMsg string + }{ + { + name: "no durations returns nil", + wantErr: false, + }, + { + name: "valid range: 7 days since, 1 day until", + activitySinceDuration: &sevenDays, + activityUntilDuration: &oneDay, + wantErr: false, + }, + { + name: "invalid range: since < until", + activitySinceDuration: &oneDay, + activityUntilDuration: &sevenDays, + wantErr: true, + errMsg: "activity-since-duration must be greater than activity-until-duration", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Config{ + ActivitySinceDuration: tt.activitySinceDuration, + ActivityUntilDuration: tt.activityUntilDuration, + } + + start, end, err := c.GetTimeFrame() + + if (err != nil) != tt.wantErr { + t.Errorf("GetTimeFrame() error = %v, wantErr %v", err, tt.wantErr) + } + + if err != nil && tt.errMsg != "" && !strings.Contains(err.Error(), tt.errMsg) { + t.Errorf("error message = %v, want to contain %v", err.Error(), tt.errMsg) + } + + // Basic validation of the logic + if err == nil { + if tt.activitySinceDuration == nil && tt.activityUntilDuration == nil { + if start != nil || end != nil { + t.Error("expected both start and end to be nil when no durations set") + } + } + if start != nil && end != nil && start.After(*end) { + t.Error("start time should be before end time") + } + } + }) + } +} diff --git a/scanners/git-repo-scanner/scanner/internal/duration/parser.go b/scanners/git-repo-scanner/scanner/internal/duration/parser.go new file mode 100644 index 0000000000..bdce224709 --- /dev/null +++ b/scanners/git-repo-scanner/scanner/internal/duration/parser.go @@ -0,0 +1,57 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +package duration + +import ( + "fmt" + "strconv" + "strings" + "time" +) + +var durationMultipliers = map[string]time.Duration{ + "s": time.Second, + "m": time.Minute, + "h": time.Hour, + "d": 24 * time.Hour, + "w": 7 * 24 * time.Hour, + "mo": 30 * 24 * time.Hour, + "y": 365 * 24 * time.Hour, +} + +// parseDuration parses duration strings like "7d", "2w", "1h30m" +func Parse(s string) (time.Duration, error) { + // First try standard Go duration parsing + if d, err := time.ParseDuration(s); err == nil { + return d, nil + } + + // Handle common suffixes + s = strings.ToLower(strings.TrimSpace(s)) + + multipliers := map[string]time.Duration{ + "s": time.Second, + "m": time.Minute, + "h": time.Hour, + "d": 24 * time.Hour, + "w": 7 * 24 * time.Hour, + "mo": 30 * 24 * time.Hour, + "y": 365 * 24 * time.Hour, + } + + // Try to parse with custom suffixes + for suffix, multiplier := range multipliers { + if strings.HasSuffix(s, suffix) { + numStr := strings.TrimSuffix(s, suffix) + num, err := strconv.ParseFloat(numStr, 64) + if err != nil { + continue + } + return time.Duration(float64(multiplier) * num), nil + } + } + + return 0, fmt.Errorf("unable to parse duration: %s", s) +} diff --git a/scanners/git-repo-scanner/scanner/internal/duration/parser_test.go b/scanners/git-repo-scanner/scanner/internal/duration/parser_test.go new file mode 100644 index 0000000000..23d7e4b826 --- /dev/null +++ b/scanners/git-repo-scanner/scanner/internal/duration/parser_test.go @@ -0,0 +1,147 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +package duration + +import ( + "testing" + "time" +) + +func TestParse(t *testing.T) { + tests := []struct { + name string + input string + expected time.Duration + wantErr bool + }{ + { + name: "standard_seconds", + input: "30s", + expected: 30 * time.Second, + wantErr: false, + }, + { + name: "standard_minutes", + input: "15m", + expected: 15 * time.Minute, + wantErr: false, + }, + { + name: "standard_hours", + input: "2h", + expected: 2 * time.Hour, + wantErr: false, + }, + { + name: "standard_combined", + input: "1h30m", + expected: 90 * time.Minute, + wantErr: false, + }, + { + name: "custom_days", + input: "7d", + expected: 7 * 24 * time.Hour, + wantErr: false, + }, + { + name: "custom_weeks", + input: "2w", + expected: 14 * 24 * time.Hour, + wantErr: false, + }, + { + name: "custom_months", + input: "1mo", + expected: 30 * 24 * time.Hour, + wantErr: false, + }, + { + name: "custom_years", + input: "1y", + expected: 365 * 24 * time.Hour, + wantErr: false, + }, + { + name: "decimal_days", + input: "1.5d", + expected: 36 * time.Hour, + wantErr: false, + }, + { + name: "decimal_weeks", + input: "0.5w", + expected: 84 * time.Hour, + wantErr: false, + }, + { + name: "uppercase_days", + input: "7D", + expected: 7 * 24 * time.Hour, + wantErr: false, + }, + { + name: "uppercase_months", + input: "2MO", + expected: 60 * 24 * time.Hour, + wantErr: false, + }, + { + name: "invalid_format", + input: "invalid", + expected: 0, + wantErr: true, + }, + { + name: "empty_string", + input: "", + expected: 0, + wantErr: true, + }, + { + name: "number_only", + input: "42", + expected: 0, + wantErr: true, + }, + { + name: "invalid_suffix", + input: "7x", + expected: 0, + wantErr: true, + }, + { + name: "non_numeric_prefix", + input: "abcd", + expected: 0, + wantErr: true, + }, + { + name: "mixed_invalid", + input: "1d2w", // Not supported format + expected: 0, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := Parse(tt.input) + + if tt.wantErr { + if err == nil { + t.Errorf("Parse(%q) expected error, got nil", tt.input) + } + } else { + if err != nil { + t.Errorf("Parse(%q) unexpected error: %v", tt.input, err) + } + if got != tt.expected { + t.Errorf("Parse(%q) = %v, want %v", tt.input, got, tt.expected) + } + } + }) + } +} diff --git a/scanners/git-repo-scanner/scanner/internal/git_repo_scanner/git_repo_scanner.go b/scanners/git-repo-scanner/scanner/internal/git_repo_scanner/git_repo_scanner.go new file mode 100644 index 0000000000..d33bdbcc52 --- /dev/null +++ b/scanners/git-repo-scanner/scanner/internal/git_repo_scanner/git_repo_scanner.go @@ -0,0 +1,73 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +package gitreposcanner + +import ( + "time" +) + +type Finding struct { + Name string `json:"name"` + Description string `json:"description"` + Category string `json:"category"` + OSILayer string `json:"osi_layer"` + Severity string `json:"severity"` + Attributes map[string]any `json:"attributes"` +} + +type GitType string + +// GitRepoScanner defines the interface that all scanners must implement +type GitRepoScanner interface { + GitType() GitType + Process(startTime, endTime *time.Time) ([]Finding, error) +} + +// BaseScanner provides common functionality for scanner implementations +type BaseScanner struct{} + +func (b *BaseScanner) CreateFinding( + gitType GitType, + repoID string, + webURL string, + fullName string, + ownerType string, + ownerID string, + ownerName string, + createdAt string, + lastActivityAt string, + visibility string, + archived bool, + topics []string, + lastCommitID *string, +) Finding { + finding := Finding{ + Name: string(gitType) + " Repo", + Description: "A " + string(gitType) + " repository", + Category: "Git Repository", + OSILayer: "APPLICATION", + Severity: "INFORMATIONAL", + Attributes: map[string]any{ + "id": repoID, + "web_url": webURL, + "full_name": fullName, + "owner_type": ownerType, + "owner_id": ownerID, + "topics": topics, + "owner_name": ownerName, + "created_at": createdAt, + "last_activity_at": lastActivityAt, + "visibility": visibility, + "archived": archived, + }, + } + + if lastCommitID != nil { + attributes := finding.Attributes + attributes["last_commit_id"] = *lastCommitID + } + + return finding +} diff --git a/scanners/git-repo-scanner/scanner/internal/git_repo_scanner/github_repo_scanner.go b/scanners/git-repo-scanner/scanner/internal/git_repo_scanner/github_repo_scanner.go new file mode 100644 index 0000000000..ebc39a67bd --- /dev/null +++ b/scanners/git-repo-scanner/scanner/internal/git_repo_scanner/github_repo_scanner.go @@ -0,0 +1,351 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +package gitreposcanner + +import ( + "context" + "fmt" + "log" + "net/http" + "time" + + "github.com/google/go-github/v79/github" + "golang.org/x/oauth2" +) + +const GitHub GitType = "GitHub" + +// GitHubRepoScanner implements the GitRepoScanner interface for GitHub repositories +type GitHubRepoScanner struct { + BaseScanner + url string + accessToken string + organization string + ignoreRepos map[int64]bool + obeyRateLimit bool + annotateLatestCommitID bool + client *github.Client + logger *log.Logger + ctx context.Context + lastRateLimitCheck time.Time + requestsSinceCheck int +} + +func NewGitHubScanner( + url string, + accessToken string, + organization string, + ignoreRepos []int64, + obeyRateLimit bool, + annotateLatestCommitID bool, + logger *log.Logger, +) (*GitHubRepoScanner, error) { + if organization == "" { + return nil, fmt.Errorf("organization required for GitHub connection") + } + if url != "" && accessToken == "" { + return nil, fmt.Errorf("access token required for GitHub connection") + } + + ignoreMap := make(map[int64]bool) + for _, id := range ignoreRepos { + ignoreMap[id] = true + } + + if logger == nil { + logger = log.New(log.Writer(), "git_repo_scanner: ", log.LstdFlags) + } + + return &GitHubRepoScanner{ + url: url, + accessToken: accessToken, + organization: organization, + ignoreRepos: ignoreMap, + obeyRateLimit: obeyRateLimit, + annotateLatestCommitID: annotateLatestCommitID, + logger: logger, + ctx: context.Background(), + lastRateLimitCheck: time.Time{}, + requestsSinceCheck: 0, + }, nil +} + +func (g *GitHubRepoScanner) GitType() GitType { + return GitHub +} + +func (g *GitHubRepoScanner) Process(startTime, endTime *time.Time) ([]Finding, error) { + if err := g.setup(); err != nil { + return nil, fmt.Errorf("failed to setup GitHub client: %w", err) + } + + findings, err := g.processRepos(startTime, endTime) + + // Log remaining API calls at the end + if g.obeyRateLimit { + rate, _, rateLimitErr := g.client.RateLimit.Get(g.ctx) + if rateLimitErr == nil { + core := rate.GetCore() + g.logger.Printf("Scan complete. Rate limit status: %d/%d remaining, resets at %s", + core.Remaining, core.Limit, core.Reset.Time.Format(time.RFC3339)) + } + } + + return findings, err +} + +func (g *GitHubRepoScanner) setup() error { + if g.url != "" { + return g.setupWithURL() + } + return g.setupWithoutURL() +} + +func (g *GitHubRepoScanner) setupWithoutURL() error { + if g.accessToken != "" { + tc := g.createTokenClient() + g.client = github.NewClient(tc) + } else { + g.client = github.NewClient(nil) + } + return nil +} + +func (g *GitHubRepoScanner) setupWithURL() error { + if g.accessToken == "" { + return fmt.Errorf("access token required for github enterprise authentication") + } + + tc := g.createTokenClient() + + var err error + g.client, err = github.NewClient(tc).WithEnterpriseURLs(g.url, g.url) + return err +} + +// The go-github library does not directly handle authentication. +// Instead, when creating a new client, pass an http.Client that can handle authentication for you. +// https://pkg.go.dev/github.com/google/go-github/github#hdr-Authentication +func (g *GitHubRepoScanner) createTokenClient() *http.Client { + ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: g.accessToken}) + return oauth2.NewClient(g.ctx, ts) +} + +func (g *GitHubRepoScanner) trackAPICall() { + g.requestsSinceCheck++ +} + +func (g *GitHubRepoScanner) processRepos(startTime, endTime *time.Time) ([]Finding, error) { + var findings []Finding + + org, _, err := g.client.Organizations.Get(g.ctx, g.organization) + g.trackAPICall() + if err != nil { + return nil, fmt.Errorf("failed to get organization: %w", err) + } + + opts := &github.RepositoryListByOrgOptions{ + Type: "all", + Sort: "pushed", + Direction: "asc", + ListOptions: github.ListOptions{ + PerPage: 100, + }, + } + + // If start time is specified, reverse the sort order + if startTime != nil { + opts.Direction = "desc" + } + + // Paginate through all repositories + for { + repos, resp, err := g.client.Repositories.ListByOrg(g.ctx, org.GetLogin(), opts) + g.trackAPICall() + if err != nil { + return nil, fmt.Errorf("failed to list repositories: %w", err) + } + + findingsForRepo, shouldContinue, err := g.processReposPage(repos, startTime, endTime) + if err != nil { + return nil, err + } + findings = append(findings, findingsForRepo...) + + if !shouldContinue || resp.NextPage == 0 { + break + } + + opts.Page = resp.NextPage + } + + return findings, nil +} + +func (g *GitHubRepoScanner) processReposPage( + repos []*github.Repository, + startTime, endTime *time.Time, +) ([]Finding, bool, error) { + var findings []Finding + + for _, repo := range repos { + if g.ignoreRepos[repo.GetID()] { + continue + } + + if (startTime != nil || endTime != nil) && !g.checkRepoIsInTimeFrame(repo.GetPushedAt().Time, startTime, endTime) { + return findings, false, nil // Stop processing further pages + } + + g.logger.Printf("Processing repository: %s", repo.GetFullName()) + + finding, err := g.createFindingFromRepo(repo) + if err != nil { + g.logger.Printf("Warning: failed to create finding for repo %s: %v", repo.GetName(), err) + continue + } + + findings = append(findings, finding) + + // Respect rate limit after processing each repo + if err := g.respectGitHubRateLimit(); err != nil { + return findings, false, err + } + } + + return findings, true, nil // Continue to next page +} + +func (g *GitHubRepoScanner) checkRepoIsInTimeFrame( + pushedAt time.Time, + startTime, endTime *time.Time, +) bool { + // GitHub API returns timestamps in UTC + pushedAt = pushedAt.UTC() + + if startTime != nil && pushedAt.Before(*startTime) { + g.logger.Printf("Reached activity limit! Ignoring all repos with activity before `%s`.", + startTime.Format(time.RFC3339)) + return false + } + + if endTime != nil && pushedAt.After(*endTime) { + g.logger.Printf("Reached activity limit! Ignoring all repos with activity after `%s`.", + endTime.Format(time.RFC3339)) + return false + } + + return true +} + +func (g *GitHubRepoScanner) respectGitHubRateLimit() error { + if !g.obeyRateLimit { + return nil + } + + // Determine check interval based on authentication + // For unauthenticated (60/hour), check more frequently + checkInterval := 50 + if g.accessToken == "" { + checkInterval = 5 + } + + if g.requestsSinceCheck < checkInterval && time.Since(g.lastRateLimitCheck) < 30*time.Second { + return nil + } + + g.requestsSinceCheck = 0 + g.lastRateLimitCheck = time.Now() + + rate, _, err := g.client.RateLimit.Get(g.ctx) + g.trackAPICall() + if err != nil { + return fmt.Errorf("failed to get rate limit: %w", err) + } + + core := rate.GetCore() + remaining := core.Remaining + reset := core.Reset.Time + limit := core.Limit + + // Determine threshold based on whether authenticated or not + var lowThreshold int + if limit <= 60 { + lowThreshold = 10 + g.logger.Printf("Warning: Using unauthenticated GitHub API (60 requests/hour limit). Consider providing an access token for better performance.") + } else { + lowThreshold = 100 + } + + if remaining < lowThreshold { + secondsUntilReset := time.Until(reset).Seconds() + 5 + if remaining > 0 { + sleepTime := secondsUntilReset / float64(remaining) + + maxSleep := 10.0 + if sleepTime > maxSleep { + sleepTime = maxSleep + g.logger.Printf("Rate limit low (%d/%d remaining), sleeping %.1fs (capped)", + remaining, limit, sleepTime) + } else if sleepTime > 1 { + g.logger.Printf("Rate limit low (%d/%d remaining), sleeping %.1fs between requests", + remaining, limit, sleepTime) + } + + if sleepTime > 0 { + time.Sleep(time.Duration(sleepTime * float64(time.Second))) + } + } else { + g.logger.Printf("Rate limit exhausted. Waiting until %s", reset.Format(time.RFC3339)) + time.Sleep(time.Until(reset) + 5*time.Second) + } + } + + return nil +} + +func (g *GitHubRepoScanner) createFindingFromRepo(repo *github.Repository) (Finding, error) { + var latestCommitID *string + + if g.annotateLatestCommitID { + commits, _, err := g.client.Repositories.ListCommits(g.ctx, + repo.GetOwner().GetLogin(), + repo.GetName(), + &github.CommitsListOptions{ + ListOptions: github.ListOptions{PerPage: 1}, + }) + g.trackAPICall() + + if err != nil { + g.logger.Printf("Warning: Could not identify the latest commit ID - repository without commits?") + empty := "" + latestCommitID = &empty + } else if len(commits) > 0 { + sha := commits[0].GetSHA() + latestCommitID = &sha + } + } + + visibility := "public" + if repo.GetPrivate() { + visibility = "private" + } + + return g.CreateFinding( + g.GitType(), + fmt.Sprintf("%d", repo.GetID()), + repo.GetHTMLURL(), + repo.GetFullName(), + repo.GetOwner().GetType(), + fmt.Sprintf("%d", repo.GetOwner().GetID()), + repo.GetOwner().GetLogin(), + repo.GetCreatedAt().Format("2006-01-02T15:04:05Z"), + repo.GetUpdatedAt().Format("2006-01-02T15:04:05Z"), + visibility, + repo.GetArchived(), + repo.Topics, + latestCommitID, + ), nil +} diff --git a/scanners/git-repo-scanner/scanner/internal/git_repo_scanner/gitlab_repo_scanner.go b/scanners/git-repo-scanner/scanner/internal/git_repo_scanner/gitlab_repo_scanner.go new file mode 100644 index 0000000000..21d106e2fb --- /dev/null +++ b/scanners/git-repo-scanner/scanner/internal/git_repo_scanner/gitlab_repo_scanner.go @@ -0,0 +1,317 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +package gitreposcanner + +import ( + "fmt" + "log" + "time" + + gitlab "gitlab.com/gitlab-org/api/client-go" + "golang.org/x/oauth2" +) + +const GitLab GitType = "GitLab" + +// GitLabScanner implements the GitRepoScanner interface for GitLab repositories +type GitLabRepoScanner struct { + BaseScanner + url string + accessToken string + group *int + ignoredGroups map[int]bool + ignoreRepos map[int]bool + obeyRateLimit bool + annotateLatestCommitID bool + client *gitlab.Client + logger *log.Logger +} + +func NewGitLabScanner( + url string, + accessToken string, + group *int, + ignoredGroups []int, + ignoreRepos []int, + obeyRateLimit bool, + annotateLatestCommitID bool, + logger *log.Logger, +) (*GitLabRepoScanner, error) { + if url == "" { + return nil, fmt.Errorf("URL required for GitLab connection") + } + if accessToken == "" { + return nil, fmt.Errorf("access token required for GitLab authentication") + } + + ignoredGroupsMap := make(map[int]bool) + for _, id := range ignoredGroups { + ignoredGroupsMap[id] = true + } + + ignoreReposMap := make(map[int]bool) + for _, id := range ignoreRepos { + ignoreReposMap[id] = true + } + + if logger == nil { + logger = log.New(log.Writer(), "git_repo_scanner: ", log.LstdFlags) + } + + return &GitLabRepoScanner{ + url: url, + accessToken: accessToken, + group: group, + ignoredGroups: ignoredGroupsMap, + ignoreRepos: ignoreReposMap, + obeyRateLimit: obeyRateLimit, + annotateLatestCommitID: annotateLatestCommitID, + logger: logger, + }, nil +} + +func (g *GitLabRepoScanner) GitType() GitType { + return GitLab +} + +func (g *GitLabRepoScanner) Process(startTime, endTime *time.Time) ([]Finding, error) { + if err := g.authenticate(); err != nil { + return nil, fmt.Errorf("failed to authenticate: %w", err) + } + + projects, err := g.getProjects(startTime, endTime) + if err != nil { + return nil, fmt.Errorf("failed to get projects: %w", err) + } + + return g.processProjects(projects) +} + +func (g *GitLabRepoScanner) authenticate() error { + g.logger.Println("Start GitLab authentication") + + var err error + // Try private token authentication first + g.client, err = gitlab.NewClient(g.accessToken, gitlab.WithBaseURL(g.url)) + if err != nil { + return fmt.Errorf("failed to create GitLab client: %w", err) + } + + // Test authentication by getting current user + _, _, err = g.client.Users.CurrentUser() + if err != nil { + // Try OAuth token if private token fails + ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: g.accessToken}) + g.client, err = gitlab.NewAuthSourceClient(gitlab.OAuthTokenSource{TokenSource: ts}, gitlab.WithBaseURL(g.url)) + if err != nil { + return fmt.Errorf("failed to create GitLab OAuth client: %w", err) + } + + // Test OAuth authentication + _, _, err = g.client.Users.CurrentUser() + if err != nil { + return fmt.Errorf("GitLab authentication failed: %w", err) + } + } + + g.logger.Println("GitLab authentication succeeded") + return nil +} + +func (g *GitLabRepoScanner) getProjects(startTime, endTime *time.Time) ([]*gitlab.Project, error) { + g.logger.Printf("Get GitLab repositories with last activity between %v and %v", startTime, endTime) + + var allProjects []*gitlab.Project + + listOptions := &gitlab.ListProjectsOptions{ + OrderBy: gitlab.Ptr("last_activity_at"), + Sort: gitlab.Ptr("desc"), + ListOptions: gitlab.ListOptions{ + PerPage: 100, + }, + } + + if startTime != nil { + listOptions.LastActivityAfter = startTime + } + if endTime != nil { + listOptions.LastActivityBefore = endTime + } + + if g.group != nil { + groupOptions := &gitlab.ListGroupProjectsOptions{ + OrderBy: listOptions.OrderBy, + Sort: listOptions.Sort, + IncludeSubGroups: gitlab.Ptr(true), + ListOptions: listOptions.ListOptions, + } + + // Paginate through all group projects + for { + projects, resp, err := g.client.Groups.ListGroupProjects(*g.group, groupOptions) + if err != nil { + return nil, fmt.Errorf("failed to list group projects: %w", err) + } + + allProjects = append(allProjects, projects...) + + if resp.NextPage == 0 { + break + } + groupOptions.Page = resp.NextPage + + if g.obeyRateLimit { + g.respectRateLimit(resp) + } + } + } else { + // List all projects accessible to the user + for { + projects, resp, err := g.client.Projects.ListProjects(listOptions) + if err != nil { + return nil, fmt.Errorf("failed to list projects: %w", err) + } + + allProjects = append(allProjects, projects...) + + if resp.NextPage == 0 { + break + } + listOptions.Page = resp.NextPage + + if g.obeyRateLimit { + g.respectRateLimit(resp) + } + } + } + + return allProjects, nil +} + +func (g *GitLabRepoScanner) respectRateLimit(resp *gitlab.Response) { + if !g.obeyRateLimit || resp == nil { + return + } + + // GitLab provides rate limit info in headers + remaining := resp.Header.Get("RateLimit-Remaining") + reset := resp.Header.Get("RateLimit-Reset") + + if remaining != "" && reset != "" { + g.logger.Printf("Rate limit - Remaining: %s, Reset: %s", remaining, reset) + + var remainingInt int + fmt.Sscanf(remaining, "%d", &remainingInt) + if remainingInt < 10 { + time.Sleep(time.Second) + } + } +} + +func (g *GitLabRepoScanner) processProjects(projects []*gitlab.Project) ([]Finding, error) { + projectCount := len(projects) + findings := make([]Finding, 0, projectCount) + + for i, project := range projects { + if !g.isNotIgnored(project) { + continue + } + + finding, err := g.createFindingFromProject(project, i, projectCount) + if err != nil { + g.logger.Printf("Warning: failed to create finding for project %s: %v", + project.Name, err) + continue + } + + findings = append(findings, finding) + } + + return findings, nil +} + +func (g *GitLabRepoScanner) isNotIgnored(project *gitlab.Project) bool { + if g.ignoreRepos[project.ID] { + return false + } + + if project.Namespace != nil && project.Namespace.Kind == "group" { + if g.ignoredGroups[project.Namespace.ID] { + return false + } + } + + return true +} + +func (g *GitLabRepoScanner) createFindingFromProject( + project *gitlab.Project, + index int, + total int, +) (Finding, error) { + g.logger.Printf("(%d/%d) Add finding for repo %s with last activity at %s", + index+1, total, project.Name, project.LastActivityAt.String()) + + var latestCommitID *string + + if g.annotateLatestCommitID { + // Get the latest commit + commits, _, err := g.client.Commits.ListCommits(project.ID, &gitlab.ListCommitsOptions{ + ListOptions: gitlab.ListOptions{ + PerPage: 1, + Page: 1, + }, + }) + + if err != nil || len(commits) == 0 { + g.logger.Printf("Warning: Could not identify the latest commit ID - repository without commits?") + empty := "" + latestCommitID = &empty + } else { + latestCommitID = &commits[0].ID + } + } + + // Determine owner info from namespace + ownerType := "" + ownerID := "" + ownerName := "" + if project.Namespace != nil { + ownerType = project.Namespace.Kind + ownerID = fmt.Sprintf("%d", project.Namespace.ID) + ownerName = project.Namespace.Name + } + + createdAt := "" + if project.CreatedAt != nil { + createdAt = project.CreatedAt.Format("2006-01-02T15:04:05Z") + } + + lastActivityAt := "" + if project.LastActivityAt != nil { + lastActivityAt = project.LastActivityAt.Format("2006-01-02T15:04:05Z") + } + + topics := []string{} + if project.Topics != nil { + topics = project.Topics + } + + return g.CreateFinding( + g.GitType(), + fmt.Sprintf("%d", project.ID), + project.WebURL, + project.PathWithNamespace, + ownerType, + ownerID, + ownerName, + createdAt, + lastActivityAt, + string(project.Visibility), + project.Archived, + topics, + latestCommitID, + ), nil +} diff --git a/scanners/git-repo-scanner/scanner/internal/output/writer.go b/scanners/git-repo-scanner/scanner/internal/output/writer.go new file mode 100644 index 0000000000..9d7989ee47 --- /dev/null +++ b/scanners/git-repo-scanner/scanner/internal/output/writer.go @@ -0,0 +1,59 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +package output + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" +) + +const defaultOutputFileName = "git-repo-scanner-findings.json" + +func WriteFindings(fileOutput string, findings any) error { + outputPath, err := resolveOutputPath(fileOutput) + if err != nil { + return err + } + + var data []byte + data, err = json.MarshalIndent(findings, "", " ") + if err != nil { + return fmt.Errorf("failed to marshal findings: %w", err) + } + + if err := os.WriteFile(outputPath, data, 0644); err != nil { + return fmt.Errorf("failed to write file: %w", err) + } + + return nil +} + +func resolveOutputPath(fileOutput string) (string, error) { + // Create directory if it doesn't exist + dir := filepath.Dir(fileOutput) + if dir != "" && dir != "." { + if err := os.MkdirAll(dir, 0755); err != nil { + return "", fmt.Errorf("failed to create output directory: %w", err) + } + } + + // Check if fileOutput is a directory + fileInfo, err := os.Stat(fileOutput) + if err == nil && fileInfo.IsDir() { + return filepath.Join(fileOutput, defaultOutputFileName), nil + } + + // If no extension, treat as directory + if filepath.Ext(fileOutput) == "" { + if err := os.MkdirAll(fileOutput, 0755); err != nil { + return "", fmt.Errorf("failed to create output directory: %w", err) + } + return filepath.Join(fileOutput, defaultOutputFileName), nil + } + + return fileOutput, nil +} diff --git a/scanners/git-repo-scanner/scanner/main.go b/scanners/git-repo-scanner/scanner/main.go new file mode 100644 index 0000000000..168d8cd0c1 --- /dev/null +++ b/scanners/git-repo-scanner/scanner/main.go @@ -0,0 +1,102 @@ +// SPDX-FileCopyrightText: the secureCodeBox authors +// +// SPDX-License-Identifier: Apache-2.0 + +package main + +import ( + "fmt" + "log" + "os" + "time" + + "github.com/secureCodeBox/scanners/git-repo-scanner/scanner/internal/config" + gitreposcanner "github.com/secureCodeBox/scanners/git-repo-scanner/scanner/internal/git_repo_scanner" + "github.com/secureCodeBox/scanners/git-repo-scanner/scanner/internal/output" +) + +var ( + logger = log.New(os.Stdout, "git-repo-scanner - ", log.LstdFlags) +) + +func main() { + config, err := config.ParseFlags() + if err != nil { + logger.Fatalf("Error parsing flags: %v", err) + } + + findings, err := process(config) + if err != nil { + logger.Fatalf("Error processing: %v", err) + } + + logger.Println("Write findings to file...") + if err := output.WriteFindings(config.FileOutput, findings); err != nil { + logger.Fatalf("Failed to write findings: %v", err) + } + logger.Println("Finished!") +} + +func process(config *config.Config) ([]gitreposcanner.Finding, error) { + var scanner gitreposcanner.GitRepoScanner + var err error + + var startTime, endTime *time.Time + now := time.Now().UTC() + + if config.ActivitySinceDuration != nil { + t := now.Add(-*config.ActivitySinceDuration) + startTime = &t + } + + if config.ActivityUntilDuration != nil { + t := now.Add(-*config.ActivityUntilDuration) + endTime = &t + } + + if startTime != nil && endTime != nil && startTime.After(*endTime) { + return nil, fmt.Errorf("activity-since-duration must be greater than activity-until-duration") + } + + switch config.GitType { + case "GitLab": + // Convert int64 slice to int slice for GitLab + ignoreRepos := make([]int, len(config.IgnoreRepos)) + for i, id := range config.IgnoreRepos { + ignoreRepos[i] = int(id) + } + + scanner, err = gitreposcanner.NewGitLabScanner( + config.URL, + config.AccessToken, + config.Group, + config.IgnoreGroups, + ignoreRepos, + config.ObeyRateLimit, + config.AnnotateLatestCommitID, + logger, + ) + if err != nil { + return nil, fmt.Errorf("failed to create GitLab scanner: %w", err) + } + + case "GitHub": + scanner, err = gitreposcanner.NewGitHubScanner( + config.URL, + config.AccessToken, + config.Organization, + config.IgnoreRepos, + config.ObeyRateLimit, + config.AnnotateLatestCommitID, + logger, + ) + if err != nil { + return nil, fmt.Errorf("failed to create GitHub scanner: %w", err) + } + + default: + return nil, fmt.Errorf("unknown git type: %s", config.GitType) + } + + return scanner.Process(startTime, endTime) +} diff --git a/scanners/git-repo-scanner/scanner/requirements.txt b/scanners/git-repo-scanner/scanner/requirements.txt deleted file mode 100644 index 8f0063c892..0000000000 --- a/scanners/git-repo-scanner/scanner/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -PyGithub == 1.54.1 -python-gitlab == 2.6.0 -pytimeparse == 1.1.8 -pytz == 2021.1 diff --git a/scanners/git-repo-scanner/scanner/tests/git_repo_scanner_test.py b/scanners/git-repo-scanner/scanner/tests/git_repo_scanner_test.py deleted file mode 100644 index 3ac4331e92..0000000000 --- a/scanners/git-repo-scanner/scanner/tests/git_repo_scanner_test.py +++ /dev/null @@ -1,420 +0,0 @@ -# SPDX-FileCopyrightText: the secureCodeBox authors -# -# SPDX-License-Identifier: Apache-2.0 - -import argparse -import datetime -import unittest -from datetime import timezone -from unittest.mock import MagicMock, Mock -from unittest.mock import patch - -import gitlab -from gitlab.v4.objects import Project, ProjectManager - -from git_repo_scanner.__main__ import get_parser_args -from git_repo_scanner.github_scanner import GitHubScanner -from git_repo_scanner.gitlab_scanner import GitLabScanner - - -class GitRepoScannerTests(unittest.TestCase): - @property - def wrong_output_msg(self) -> str: - return "Test finding output" - - def prepare_gitlab_commitlist_mock(self, mock_gptp, mock_commitmanager): - mock_gptp.side_effect = self._mock_group_project_to_project - mock_commitmanager.return_value = [Mock(id="deadbeef")] - - def _mock_group_project_to_project(self, project): - return project - - @patch("gitlab.v4.objects.ProjectCommitManager.list") - @patch("git_repo_scanner.gitlab_scanner.GitLabScanner._group_project_to_project") - def test_process_gitlab_projects_with_no_ignore_list( - self, mock_gptp, mock_commitmanager - ): - # given - scanner = GitLabScanner( - "url", "token", None, [], [], annotate_latest_commit_id=True - ) - projects = assemble_projects() - self.prepare_gitlab_commitlist_mock(mock_gptp, mock_commitmanager) - # when - findings = scanner._process_projects(projects) - # then - self.assertEqual(3, len(findings), msg="There should be exactly 3 findings") - self.assertEqual(findings[0]["name"], "GitLab Repo", msg=self.wrong_output_msg) - self.assertEqual( - findings[0]["attributes"]["web_url"], "url1", msg=self.wrong_output_msg - ) - self.assertEqual( - findings[1]["attributes"]["web_url"], "url2", msg=self.wrong_output_msg - ) - self.assertEqual( - findings[2]["attributes"]["web_url"], "url3", msg=self.wrong_output_msg - ) - self.assertEqual(findings[0]["attributes"]["last_commit_id"], "deadbeef") - self.assertEqual(findings[1]["attributes"]["archived"], False) - self.assertEqual(findings[2]["attributes"]["archived"], True) - self.assertEqual(findings[0]["attributes"]["topics"], []) - self.assertEqual(findings[2]["attributes"]["topics"], ["outdated"]) - mock_gptp.assert_called() - mock_commitmanager.assert_called() - - @patch("gitlab.v4.objects.ProjectCommitManager.list") - @patch("git_repo_scanner.gitlab_scanner.GitLabScanner._group_project_to_project") - def test_process_gitlab_projects_without_annotating_commit_id( - self, mock_gptp, mock_commitmanager - ): - # given - scanner = GitLabScanner( - "url", "token", None, [], [], annotate_latest_commit_id=False - ) - projects = assemble_projects() - self.prepare_gitlab_commitlist_mock(mock_gptp, mock_commitmanager) - # when - findings = scanner._process_projects(projects) - # then - self.assertEqual(3, len(findings), msg="There should be exactly 3 findings") - self.assertEqual(findings[0]["name"], "GitLab Repo", msg=self.wrong_output_msg) - self.assertEqual( - findings[0]["attributes"]["web_url"], "url1", msg=self.wrong_output_msg - ) - self.assertEqual( - findings[1]["attributes"]["web_url"], "url2", msg=self.wrong_output_msg - ) - self.assertEqual( - findings[2]["attributes"]["web_url"], "url3", msg=self.wrong_output_msg - ) - self.assertFalse("last_commit_id" in findings[0]["attributes"]) - mock_gptp.assert_not_called() - mock_commitmanager.assert_not_called() - - @patch("gitlab.v4.objects.ProjectCommitManager.list") - @patch("git_repo_scanner.gitlab_scanner.GitLabScanner._group_project_to_project") - def test_process_gitlab_projects_with_ignore_group( - self, mock_gptp, mock_commitmanager - ): - # given - scanner = GitLabScanner( - "url", "token", None, [33], [], annotate_latest_commit_id=True - ) - projects = assemble_projects() - self.prepare_gitlab_commitlist_mock(mock_gptp, mock_commitmanager) - # when - findings = scanner._process_projects(projects) - # then - self.assertEqual(2, len(findings), msg="There should be exactly 2 findings") - self.assertEqual( - findings[0]["attributes"]["web_url"], "url1", msg=self.wrong_output_msg - ) - self.assertEqual( - findings[1]["attributes"]["web_url"], "url2", msg=self.wrong_output_msg - ) - self.assertEqual(findings[0]["attributes"]["last_commit_id"], "deadbeef") - mock_gptp.assert_called() - mock_commitmanager.assert_called() - - @patch("gitlab.v4.objects.ProjectCommitManager.list") - @patch("git_repo_scanner.gitlab_scanner.GitLabScanner._group_project_to_project") - def test_process_gitlab_projects_with_ignore_project( - self, mock_gptp, mock_commitmanager - ): - # given - scanner = GitLabScanner( - "url", "token", None, [], [1], annotate_latest_commit_id=True - ) - projects = assemble_projects() - self.prepare_gitlab_commitlist_mock(mock_gptp, mock_commitmanager) - # when - findings = scanner._process_projects(projects) - # then - self.assertEqual(2, len(findings), msg="There should be exactly 2 findings") - self.assertEqual( - findings[0]["attributes"]["web_url"], "url2", msg=self.wrong_output_msg - ) - self.assertEqual( - findings[1]["attributes"]["web_url"], "url3", msg=self.wrong_output_msg - ) - self.assertEqual(findings[0]["attributes"]["last_commit_id"], "deadbeef") - mock_gptp.assert_called() - mock_commitmanager.assert_called() - - @patch("github.Github") - @patch("github.Organization") - @patch("github.PaginatedList") - def test_process_github_repos_with_no_ignore_list( - self, github_mock, org_mock, pag_mock - ): - # given - scanner = GitHubScanner( - "url", "token", "org", [], False, annotate_latest_commit_id=True - ) - repos = assemble_repos() - create_mocks(github_mock, org_mock, pag_mock, repos) - scanner._gh = github_mock - # when - findings = scanner._process_repos(None, None) - # then - org_mock.get_repos.assert_called_with( - type="all", sort="pushed", direction="asc" - ) - self.assertEqual(6, len(findings), msg="There should be exactly 6 findings") - for finding in findings: - self.assertEqual(finding["name"], "GitHub Repo", msg=self.wrong_output_msg) - self.assertEqual(finding["attributes"]["last_commit_id"], "deadbeef") - - @patch("github.Github") - @patch("github.Organization") - @patch("github.PaginatedList") - def test_process_github_repos_without_annotating_commit_ids( - self, github_mock, org_mock, pag_mock - ): - # given - scanner = GitHubScanner( - "url", "token", "org", [], False, annotate_latest_commit_id=False - ) - repos = assemble_repos() - create_mocks(github_mock, org_mock, pag_mock, repos) - scanner._gh = github_mock - # when - findings = scanner._process_repos(None, None) - # then - org_mock.get_repos.assert_called_with( - type="all", sort="pushed", direction="asc" - ) - self.assertEqual(6, len(findings), msg="There should be exactly 6 findings") - self.assertFalse(findings[0]["attributes"]["archived"]) - self.assertFalse(findings[1]["attributes"]["archived"]) - self.assertTrue(findings[2]["attributes"]["archived"]) - self.assertFalse(findings[3]["attributes"]["archived"]) - self.assertFalse(findings[4]["attributes"]["archived"]) - self.assertTrue(findings[5]["attributes"]["archived"]) - self.assertEqual(findings[0]["attributes"]["topics"], []) - self.assertEqual(findings[2]["attributes"]["topics"], ["outdated"]) - for finding in findings: - self.assertEqual(finding["name"], "GitHub Repo", msg=self.wrong_output_msg) - self.assertFalse("last_commit_id" in finding["attributes"]) - - @patch("github.Github") - @patch("github.Organization") - @patch("github.PaginatedList") - def test_process_github_repos_with_ignore_repos( - self, github_mock, org_mock, pag_mock - ): - # given - scanner = GitHubScanner( - "url", "token", "org", [1], False, annotate_latest_commit_id=True - ) - repos = assemble_repos() - create_mocks(github_mock, org_mock, pag_mock, repos) - scanner._gh = github_mock - # when - findings = scanner._process_repos(None, None) - # then - github_mock.get_organization.assert_called_with("org") - self.assertEqual(4, len(findings), msg="There should be exactly 4 findings") - self.assertEqual(findings[0]["attributes"]["last_commit_id"], "deadbeef") - - def test_setup_github_with_url_and_no_token_should_exit(self): - # when - with self.assertRaises(argparse.ArgumentError) as cm: - GitHubScanner("url", None, "org", []) - # then - self.assertEqual( - cm.exception.args[1], - "Access token required for GitHub connection.", - msg="Process should exit", - ) - - -def get_args(ignore_groups=0, ignore_projects=0, url=None, access_token=None, org=None): - args = [ - "--git-type", - "someType", - "--file-output", - "out", - "--obey-rate-limit", - False, - "--ignore-repos", - str(ignore_projects), - "--ignore-groups", - str(ignore_groups), - ] - if url: - args.append("--url") - args.append(url) - if access_token: - args.append("--access-token") - args.append(access_token) - if org: - args.append("--organization") - args.append(org) - - return get_parser_args(args) - - -def create_mocks(github_mock, org_mock, pag_mock, repos): - pag_mock.totalCount = 2 - pag_mock.get_page = MagicMock(return_value=repos) - org_mock.get_repos = MagicMock(return_value=pag_mock) - github_mock.get_organization = MagicMock(return_value=org_mock) - - -def assemble_projects(): - created = datetime.datetime(2020, 10, 10, tzinfo=timezone.utc).isoformat() - updated = datetime.datetime(2020, 11, 10, tzinfo=timezone.utc).isoformat() - project1 = assemble_project( - p_id=1, - name="name1", - url="url1", - path="path1", - date_created=created, - date_updated=updated, - visibility="private", - o_id=11, - o_kind="group", - o_name="name11", - ) - project2 = assemble_project( - p_id=2, - name="name2", - url="url2", - path="path2", - date_created=created, - date_updated=updated, - visibility="private", - o_id=22, - o_kind="user", - o_name="name22", - ) - project3 = assemble_project( - p_id=3, - name="name3", - url="url3", - path="path3", - date_created=created, - date_updated=updated, - visibility="private", - o_id=33, - o_kind="group", - o_name="name33", - archived=True, - topics=["outdated"], - ) - return [project1, project2, project3] - - -def assemble_project( - p_id, - name, - url, - path, - date_created, - date_updated, - visibility, - o_id, - o_kind, - o_name, - archived=False, - topics=[], -): - project = Project(ProjectManager(gitlab), {}) - project.id = p_id - project.name = name - project.web_url = url - project.path_with_namespace = path - project.created_at = date_created - project.last_activity_at = date_updated - project.visibility = visibility - project.namespace = {"kind": o_kind, "id": o_id, "name": o_name} - project.archived = archived - project.topics = topics - return project - - -def assemble_repos(): - date = datetime.datetime(2020, 5, 17, tzinfo=timezone.utc) - project1 = assemble_repository( - p_id=1, - name="name1", - url="url1", - path="path1", - date_created=date, - date_updated=date, - date_pushed=date, - visibility=True, - o_id=11, - o_kind="organization", - o_name="name11", - ) - project2 = assemble_repository( - p_id=2, - name="name2", - url="url2", - path="path2", - date_created=date, - date_updated=date, - date_pushed=date, - visibility=False, - o_id=22, - o_kind="organization", - o_name="name22", - ) - project3 = assemble_repository( - p_id=3, - name="name3", - url="url3", - path="path3", - date_created=date, - date_updated=date, - date_pushed=date, - visibility=False, - o_id=33, - o_kind="organization", - o_name="name33", - archived=True, - topics=["outdated"], - ) - return [project1, project2, project3] - - -def assemble_repository( - p_id, - name, - url, - path, - date_created: datetime, - date_updated: datetime, - date_pushed: datetime, - visibility: bool, - o_id, - o_kind, - o_name, - archived=False, - topics=[], -): - - repo = Mock() - owner = Mock() - owner.type = o_kind - owner.id = o_id - owner.name = o_name - repo.id = p_id - repo.name = name - repo.html_url = url - repo.full_name = path - repo.created_at = date_created - repo.pushed_at = date_pushed - repo.updated_at = date_updated - repo.private = visibility - repo.owner = owner - repo.get_commits = lambda: [Mock(sha="deadbeef")] - repo.get_topics = lambda: topics - repo.archived = archived - return repo - - -if __name__ == "__main__": - unittest.main() diff --git a/scanners/git-repo-scanner/templates/git-repo-scanner-scan-type.yaml b/scanners/git-repo-scanner/templates/git-repo-scanner-scan-type.yaml index 62f9d2ff3f..f056faf2b1 100644 --- a/scanners/git-repo-scanner/templates/git-repo-scanner-scan-type.yaml +++ b/scanners/git-repo-scanner/templates/git-repo-scanner-scan-type.yaml @@ -25,7 +25,7 @@ spec: restartPolicy: OnFailure affinity: {{- toYaml .Values.scanner.affinity | nindent 12 }} - tolerations: + tolerations: {{- toYaml .Values.scanner.tolerations | nindent 12 }} {{- with .Values.imagePullSecrets }} imagePullSecrets: @@ -38,9 +38,7 @@ spec: image: "{{ .Values.scanner.image.repository }}:{{ .Values.scanner.image.tag | default .Chart.Version }}" imagePullPolicy: {{ .Values.scanner.image.pullPolicy }} command: - - "python" - - "-m" - - "git_repo_scanner" + - "/git-repo-scanner" - "--file-output" - "/home/securecodebox" resources: diff --git a/scanners/git-repo-scanner/tests/__snapshot__/scanner_test.yaml.snap b/scanners/git-repo-scanner/tests/__snapshot__/scanner_test.yaml.snap index 79d7837be9..82db039ed9 100644 --- a/scanners/git-repo-scanner/tests/__snapshot__/scanner_test.yaml.snap +++ b/scanners/git-repo-scanner/tests/__snapshot__/scanner_test.yaml.snap @@ -40,9 +40,7 @@ matches the snapshot: foo: bar containers: - command: - - python - - -m - - git_repo_scanner + - /git-repo-scanner - --file-output - /home/securecodebox env: diff --git a/scanners/gitleaks/Chart.yaml b/scanners/gitleaks/Chart.yaml index 0cf1c470fb..b53e1eac7d 100644 --- a/scanners/gitleaks/Chart.yaml +++ b/scanners/gitleaks/Chart.yaml @@ -8,7 +8,7 @@ description: A Helm chart for the gitleaks repository scanner that integrates wi type: application # version - gets automatically set to the secureCodeBox release version when the helm charts gets published version: v3.1.0-alpha1 -appVersion: "v8.27.2" +appVersion: "v8.30.0" kubeVersion: ">=v1.11.0-0" annotations: versionApi: https://api.github.com/repos/zricethezav/gitleaks/releases/latest diff --git a/scanners/gitleaks/README.md b/scanners/gitleaks/README.md index b295aae179..5d5cef98d7 100644 --- a/scanners/gitleaks/README.md +++ b/scanners/gitleaks/README.md @@ -3,7 +3,7 @@ title: "Gitleaks" category: "scanner" type: "Repository" state: "released" -appVersion: "v8.27.2" +appVersion: "v8.30.0" usecase: "Find potential secrets in repositories" --- diff --git a/scanners/gitleaks/docs/README.DockerHub-Parser.md b/scanners/gitleaks/docs/README.DockerHub-Parser.md index 4e24c56754..2b96784304 100644 --- a/scanners/gitleaks/docs/README.DockerHub-Parser.md +++ b/scanners/gitleaks/docs/README.DockerHub-Parser.md @@ -42,7 +42,7 @@ You can find resources to help you get started on our [documentation website](ht ## Supported Tags - `latest` (represents the latest stable release build) -- tagged releases, e.g. `v8.27.2` +- tagged releases, e.g. `v8.30.0` ## How to use this image This `parser` image is intended to work in combination with the corresponding security scanner docker image to parse the `findings` results. For more information details please take a look at the documentation page: https://www.securecodebox.io/docs/scanners/gitleaks. diff --git a/scanners/gitleaks/examples/private-repository/scan.yaml b/scanners/gitleaks/examples/private-repository/scan.yaml index f3970cc713..2fdd2a0412 100644 --- a/scanners/gitleaks/examples/private-repository/scan.yaml +++ b/scanners/gitleaks/examples/private-repository/scan.yaml @@ -20,7 +20,7 @@ spec: # Define an init container to run the git clone for us initContainers: - name: "git-clone" - image: bitnami/git + image: alpine/git # Specify that the "repo" volume should also be mounted on the # initContainer volumeMounts: diff --git a/scanners/gitleaks/examples/provide-own-rules/scan.yaml b/scanners/gitleaks/examples/provide-own-rules/scan.yaml index 7fd0f95e11..0ba1e4d91c 100644 --- a/scanners/gitleaks/examples/provide-own-rules/scan.yaml +++ b/scanners/gitleaks/examples/provide-own-rules/scan.yaml @@ -48,7 +48,7 @@ spec: # Define an init container to run the git clone for us initContainers: - name: "git-clone" - image: bitnami/git + image: alpine/git # Specify that the "repo" volume should also be mounted on the # initContainer volumeMounts: diff --git a/scanners/gitleaks/examples/secureCodeBox/scan.yaml b/scanners/gitleaks/examples/secureCodeBox/scan.yaml index 7109459772..cf7c8b7c15 100644 --- a/scanners/gitleaks/examples/secureCodeBox/scan.yaml +++ b/scanners/gitleaks/examples/secureCodeBox/scan.yaml @@ -20,7 +20,7 @@ spec: # Define an init container to run the git clone for us initContainers: - name: "git-clone" - image: bitnami/git + image: alpine/git # Specify that the "repo" volume should also be mounted on the # initContainer volumeMounts: diff --git a/scanners/gitleaks/integration-tests/gitleaks.test.js b/scanners/gitleaks/integration-tests/gitleaks.test.js index d99fb4ec36..7579844003 100644 --- a/scanners/gitleaks/integration-tests/gitleaks.test.js +++ b/scanners/gitleaks/integration-tests/gitleaks.test.js @@ -31,9 +31,9 @@ test( [ { name: "init-git", - image: "bitnami/git", + image: "alpine/git", command: [ - "bash", + "sh", "-c", // Bash script to create a git repo with a demo file `cd /repo && \\ diff --git a/scanners/gitleaks/parser/Dockerfile b/scanners/gitleaks/parser/Dockerfile index 159649e6ba..449c709d29 100644 --- a/scanners/gitleaks/parser/Dockerfile +++ b/scanners/gitleaks/parser/Dockerfile @@ -2,16 +2,8 @@ # # SPDX-License-Identifier: Apache-2.0 -# Commented out the dependency management as there are no dependencies in the -# parser at the moment. Add the commented-out parts of the Dockerfile again -# if the parser starts needing packages once again. ARG namespace ARG baseImageTag -# FROM node:22-alpine as build -# RUN mkdir -p /home/app -# WORKDIR /home/app -# COPY package.json package-lock.json ./ -# RUN npm ci --omit=dev FROM ${namespace:-securecodebox}/parser-sdk-nodejs:${baseImageTag:-latest} WORKDIR /home/app/parser-wrapper/parser/ diff --git a/scanners/gitleaks/parser/parser.test.js b/scanners/gitleaks/parser/parser.test.js index fd83d8f03b..84da650a5f 100644 --- a/scanners/gitleaks/parser/parser.test.js +++ b/scanners/gitleaks/parser/parser.test.js @@ -15,7 +15,7 @@ test("should properly parse empty gitleaks json file", async () => { }, ); const findings = await parse(jsonContent); - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchObject([]); }); @@ -27,7 +27,7 @@ test("should properly parse gitleaks json file with null result", async () => { }, ); const findings = await parse(jsonContent); - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchObject([]); }); @@ -39,7 +39,7 @@ test("should properly parse gitleaks json file", async () => { }, ); const findings = await parse(jsonContent); - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(` [ { @@ -132,7 +132,7 @@ test("should define severity based on tags in result file", async () => { }, ); const findings = await parse(jsonContent); - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(` [ @@ -222,7 +222,7 @@ test("should properly construct commit URL if given in scan annotation without t }, ); const findings = await parse(jsonContent, scan); - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(` [ @@ -329,7 +329,7 @@ test("should properly construct commit URL if given in scan annotation with trai }, ); const findings = await parse(jsonContent, scan); - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(` [ diff --git a/scanners/kube-hunter/parser/__snapshots__/parser.test.js.snap b/scanners/kube-hunter/parser/__snapshots__/parser.test.js.snap index a989c2d30a..29618bbd39 100644 --- a/scanners/kube-hunter/parser/__snapshots__/parser.test.js.snap +++ b/scanners/kube-hunter/parser/__snapshots__/parser.test.js.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Bun Snapshot v1, https://bun.sh/docs/test/snapshots exports[`parses result from kind-1.18-in-cluster-scan correctly 1`] = ` [ diff --git a/scanners/kube-hunter/parser/parser.test.js b/scanners/kube-hunter/parser/parser.test.js index 9cddcab818..0c980c85a4 100644 --- a/scanners/kube-hunter/parser/parser.test.js +++ b/scanners/kube-hunter/parser/parser.test.js @@ -17,7 +17,7 @@ test("parses result from kind-1.18-in-cluster-scan correctly", async () => { ), ); const findings = await parse(fileContent); - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchSnapshot(); }); @@ -29,6 +29,6 @@ test("should properly parse empty kube-hunter json file", async () => { }, ); const findings = await parse(jsonContent); - await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(validateParser(findings)).toBeUndefined(); expect(findings).toMatchInlineSnapshot(`[]`); }); diff --git a/scanners/ncrack/.helm-docs.gotmpl b/scanners/ncrack/.helm-docs.gotmpl index 3405924b59..32f814b332 100644 --- a/scanners/ncrack/.helm-docs.gotmpl +++ b/scanners/ncrack/.helm-docs.gotmpl @@ -73,7 +73,7 @@ TIMING AND PERFORMANCE: to (time-out): maximum cracking