From bf5d66222cd484a54f00fc74bcc1cef18d288a74 Mon Sep 17 00:00:00 2001 From: Xe Iaso Date: Sun, 15 Feb 2026 13:19:12 +0000 Subject: [PATCH] chore: set up commitlint, husky, and prettier (#1451) * chore: add prettier configuration Signed-off-by: Xe Iaso * format: run prettier tree-wide Signed-off-by: Xe Iaso * chore(prettier): ignore intentionally ungrammatical files Signed-off-by: Xe Iaso * ci: add PR title lint rule Signed-off-by: Xe Iaso * ci: add DCO check Signed-off-by: Xe Iaso * chore: add commitlint and husky Signed-off-by: Xe Iaso * chore: add CONTRIBUTING guidelines Signed-off-by: Xe Iaso * chore: set SKIP_INTEGRATION in precommit tests Signed-off-by: Xe Iaso * chore: update spelling Signed-off-by: Xe Iaso * ci(dco): remove reopened trigger Signed-off-by: Xe Iaso * chore: remove dead file Signed-off-by: Xe Iaso * chore(prettier): don't format nginx includes Signed-off-by: Xe Iaso --------- Signed-off-by: Xe Iaso --- .devcontainer/devcontainer.json | 6 +- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 - .github/ISSUE_TEMPLATE/feature_request.yaml | 2 +- .github/actions/spelling/README.md | 24 +- .github/actions/spelling/advice.md | 19 +- .github/actions/spelling/expect.txt | 4 + .github/workflows/asset-verification.yml | 4 +- .github/workflows/dco-check.yaml | 9 + .github/workflows/docker-pr.yml | 4 +- .github/workflows/docker.yml | 4 +- .github/workflows/go-mod-tidy-check.yml | 2 +- .github/workflows/go.yml | 4 +- .github/workflows/lint-pr-title.yaml | 19 + .github/workflows/package-builds-stable.yml | 4 +- .github/workflows/package-builds-unstable.yml | 4 +- .github/workflows/spelling.yml | 12 +- .github/workflows/ssh-ci.yml | 2 +- .github/workflows/zizmor.yml | 16 +- .husky/commit-msg | 8 + .husky/pre-commit | 2 + .ko.yaml | 18 +- .prettierignore | 2 + .vscode/extensions.json | 2 +- .vscode/launch.json | 2 +- CONTRIBUTING.md | 144 +++ cmd/robots2policy/testdata/blacklist.yaml | 4 +- cmd/robots2policy/testdata/complex.yaml | 24 +- cmd/robots2policy/testdata/consecutive.yaml | 26 +- cmd/robots2policy/testdata/empty.yaml | 2 +- cmd/robots2policy/testdata/simple.json | 2 +- data/apps/allow-api-routes.yaml | 4 +- data/apps/gitea-rss-feeds.yaml | 2 +- data/apps/qualys-ssl-labs.yml | 6 +- data/apps/searx-checker.yml | 4 +- data/bots/headless-browsers.yaml | 2 +- data/bots/irc-bots/archlinux-phrik.yaml | 8 +- data/bots/irc-bots/gentoo-chat.yaml | 8 +- data/bots/us-ai-scraper.yaml | 2 +- data/clients/go-get.yaml | 6 +- data/clients/mistral-mistralai-user.yaml | 5 +- data/clients/openai-chatgpt-user.yaml | 173 ++-- data/clients/perplexity-user.yaml | 8 +- data/clients/telegram-preview.yaml | 12 +- data/clients/vk-preview.yaml | 12 +- data/common/allow-api-like.yaml | 4 +- data/common/json-api.yaml | 2 +- data/common/rfc-violations.yaml | 2 +- data/crawlers/applebot.yaml | 29 +- data/crawlers/bingbot.yaml | 61 +- data/crawlers/duckduckbot.yaml | 543 +++++------ data/crawlers/googlebot.yaml | 519 +++++----- data/crawlers/internet-archive.yaml | 6 +- data/crawlers/kagibot.yaml | 13 +- data/crawlers/marginalia.yaml | 15 +- data/crawlers/mojeekbot.yaml | 2 +- data/crawlers/openai-gptbot.yaml | 21 +- data/crawlers/openai-searchbot.yaml | 15 +- data/crawlers/perplexitybot.yaml | 21 +- data/crawlers/qwantbot.yaml | 2 +- data/crawlers/yandexbot.yaml | 12 +- data/meta/README.md | 2 +- data/meta/ai-block-aggressive.yaml | 2 +- data/meta/messengers-preview.yaml | 4 +- data/services/uptime-robot.yaml | 439 ++++----- .../ProofOfWorkDiagram/index.jsx | 150 ++- .../ProofOfWorkDiagram/styles.module.css | 8 +- docs/docs/admin/_category_.json | 2 +- docs/docs/admin/configuration/_category_.json | 2 +- .../configuration/challenges/_category_.json | 2 +- docs/docs/admin/configuration/expressions.mdx | 26 +- docs/docs/admin/default-allow-behavior.mdx | 2 +- docs/docs/admin/environments/_category_.json | 2 +- docs/docs/admin/environments/kubernetes.mdx | 2 - .../admin/environments/nginx/conf-anubis.inc | 10 +- docs/docs/admin/environments/traefik.mdx | 2 +- docs/docs/admin/frameworks/_category_.json | 2 +- docs/docs/admin/honeypot/_category_.json | 2 +- docs/docs/admin/installation.mdx | 4 +- docs/docs/admin/roles/_category_.json | 2 +- docs/docs/design/_category_.json | 2 +- docs/docs/developer/_category_.json | 2 +- docs/docs/user/_category_.json | 2 +- docs/docusaurus.config.ts | 122 +-- docs/manifest/ingress.yaml | 2 +- docs/manifest/onionservice.yaml | 14 +- docs/manifest/service.yaml | 12 +- docs/sidebars.ts | 4 +- docs/src/components/EnterpriseOnly/index.jsx | 4 +- .../EnterpriseOnly/styles.module.css | 4 +- lib/challenge/preact/js/xeact.js | 8 +- lib/config/testdata/bad/badregexes.json | 2 +- lib/config/testdata/bad/badregexes.yaml | 12 +- lib/config/testdata/bad/import_and_bot.json | 2 +- lib/config/testdata/bad/import_and_bot.yaml | 10 +- .../testdata/bad/import_invalid_file.json | 2 +- .../testdata/bad/import_invalid_file.yaml | 2 +- lib/config/testdata/bad/invalid.json | 6 +- lib/config/testdata/bad/invalid.yaml | 2 +- .../bad/multiple_expression_types.json | 6 +- .../bad/multiple_expression_types.yaml | 18 +- lib/config/testdata/bad/nobots.json | 2 +- lib/config/testdata/bad/nobots.yaml | 2 +- .../testdata/bad/regex_ends_newline.yaml | 32 +- lib/config/testdata/bad/status-codes-0.yaml | 8 +- lib/config/testdata/good/allow_everyone.json | 7 +- lib/config/testdata/good/allow_everyone.yaml | 10 +- .../testdata/good/block_cf_workers.json | 2 +- .../testdata/good/block_cf_workers.yaml | 2 +- .../testdata/good/challengemozilla.json | 2 +- .../testdata/good/challengemozilla.yaml | 6 +- .../testdata/good/everything_blocked.json | 2 +- .../testdata/good/everything_blocked.yaml | 6 +- lib/config/testdata/good/git_client.json | 2 +- lib/config/testdata/good/git_client.yaml | 14 +- .../testdata/good/import_filesystem.json | 2 +- .../testdata/good/import_filesystem.yaml | 2 +- .../good/import_keep_internet_working.json | 2 +- .../good/import_keep_internet_working.yaml | 2 +- lib/config/testdata/good/old_xesite.json | 2 +- .../testdata/good/status-codes-paranoid.yaml | 8 +- .../testdata/good/status-codes-rfc.yaml | 8 +- lib/config/testdata/hack-test.json | 6 +- lib/config/testdata/hack-test.yaml | 2 +- lib/localization/locales/cs.json | 2 +- lib/localization/locales/en.json | 2 +- lib/localization/locales/es.json | 2 +- lib/localization/locales/et.json | 2 +- lib/localization/locales/fi.json | 2 +- lib/localization/locales/fr.json | 2 +- lib/localization/locales/it.json | 2 +- lib/localization/locales/ja.json | 2 +- lib/localization/locales/nb.json | 2 +- lib/localization/locales/pl.json | 130 +-- lib/localization/locales/ru.json | 2 +- lib/localization/locales/sv.json | 2 +- lib/localization/locales/vi.json | 2 +- lib/localization/locales/zh-TW.json | 2 +- lib/policy/testdata/hack-test.json | 6 +- lib/policy/testdata/hack-test.yaml | 2 +- lib/testdata/cloudflare-workers-cel.yaml | 8 +- lib/testdata/cloudflare-workers-header.yaml | 10 +- lib/testdata/hack-test.json | 6 +- lib/testdata/hack-test.yaml | 2 +- lib/testdata/rule_change.yaml | 14 +- package-lock.json | 895 +++++++++++++++++- package.json | 45 +- test/anubis_configs/aggressive_403.yaml | 14 +- test/double_slash/test.mjs | 6 +- test/forced-language/test.mjs | 10 +- test/i18n/test.mjs | 18 +- test/k8s/cert-manager/selfsigned-issuer.yaml | 2 +- test/k8s/deps/cert-manager.yaml | 2 +- test/log-file/test.mjs | 22 +- test/nginx/conf/nginx/conf-anubis.inc | 3 +- test/robots_txt/test.mjs | 10 +- test/shared/www/index.html | 13 +- test/unix-socket-xff/test.mjs | 21 +- web/js/algorithms/fast.ts | 9 +- web/js/algorithms/index.ts | 2 +- web/js/bench.ts | 35 +- web/js/main.ts | 80 +- web/js/worker/sha256-purejs.ts | 12 +- web/js/worker/sha256-webcrypto.ts | 13 +- xess/postcss.config.js | 2 +- yeetfile.js | 128 ++- 165 files changed, 2854 insertions(+), 1621 deletions(-) create mode 100644 .github/workflows/dco-check.yaml create mode 100644 .github/workflows/lint-pr-title.yaml create mode 100644 .husky/commit-msg create mode 100644 .husky/pre-commit create mode 100644 .prettierignore create mode 100644 CONTRIBUTING.md diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 0602ff19..9d17aaa4 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,9 +2,7 @@ // README at: https://github.com/devcontainers/templates/tree/main/src/debian { "name": "Dev", - "dockerComposeFile": [ - "./docker-compose.yaml" - ], + "dockerComposeFile": ["./docker-compose.yaml"], "service": "workspace", "workspaceFolder": "/workspace/anubis", "postStartCommand": "bash ./.devcontainer/poststart.sh", @@ -31,4 +29,4 @@ } } } -} \ No newline at end of file +} diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index f7f94316..4a275b0a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -58,4 +58,3 @@ body: attributes: label: Additional context description: Add any other context about the problem here. - diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index 64f710b9..fd5b6707 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -1,6 +1,6 @@ name: Feature request description: Suggest an idea for this project -title: '[Feature request] ' +title: "[Feature request] " body: - type: textarea diff --git a/.github/actions/spelling/README.md b/.github/actions/spelling/README.md index 1f699f3d..ef73ac26 100644 --- a/.github/actions/spelling/README.md +++ b/.github/actions/spelling/README.md @@ -1,17 +1,17 @@ # check-spelling/check-spelling configuration -File | Purpose | Format | Info --|-|-|- -[dictionary.txt](dictionary.txt) | Replacement dictionary (creating this file will override the default dictionary) | one word per line | [dictionary](https://github.com/check-spelling/check-spelling/wiki/Configuration#dictionary) -[allow.txt](allow.txt) | Add words to the dictionary | one word per line (only letters and `'`s allowed) | [allow](https://github.com/check-spelling/check-spelling/wiki/Configuration#allow) -[reject.txt](reject.txt) | Remove words from the dictionary (after allow) | grep pattern matching whole dictionary words | [reject](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-reject) -[excludes.txt](excludes.txt) | Files to ignore entirely | perl regular expression | [excludes](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-excludes) -[only.txt](only.txt) | Only check matching files (applied after excludes) | perl regular expression | [only](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-only) -[patterns.txt](patterns.txt) | Patterns to ignore from checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns) -[candidate.patterns](candidate.patterns) | Patterns that might be worth adding to [patterns.txt](patterns.txt) | perl regular expression with optional comment block introductions (all matches will be suggested) | [candidates](https://github.com/check-spelling/check-spelling/wiki/Feature:-Suggest-patterns) -[line_forbidden.patterns](line_forbidden.patterns) | Patterns to flag in checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns) -[expect.txt](expect.txt) | Expected words that aren't in the dictionary | one word per line (sorted, alphabetically) | [expect](https://github.com/check-spelling/check-spelling/wiki/Configuration#expect) -[advice.md](advice.md) | Supplement for GitHub comment when unrecognized words are found | GitHub Markdown | [advice](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice) +| File | Purpose | Format | Info | +| -------------------------------------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | +| [dictionary.txt](dictionary.txt) | Replacement dictionary (creating this file will override the default dictionary) | one word per line | [dictionary](https://github.com/check-spelling/check-spelling/wiki/Configuration#dictionary) | +| [allow.txt](allow.txt) | Add words to the dictionary | one word per line (only letters and `'`s allowed) | [allow](https://github.com/check-spelling/check-spelling/wiki/Configuration#allow) | +| [reject.txt](reject.txt) | Remove words from the dictionary (after allow) | grep pattern matching whole dictionary words | [reject](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-reject) | +| [excludes.txt](excludes.txt) | Files to ignore entirely | perl regular expression | [excludes](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-excludes) | +| [only.txt](only.txt) | Only check matching files (applied after excludes) | perl regular expression | [only](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-only) | +| [patterns.txt](patterns.txt) | Patterns to ignore from checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns) | +| [candidate.patterns](candidate.patterns) | Patterns that might be worth adding to [patterns.txt](patterns.txt) | perl regular expression with optional comment block introductions (all matches will be suggested) | [candidates](https://github.com/check-spelling/check-spelling/wiki/Feature:-Suggest-patterns) | +| [line_forbidden.patterns](line_forbidden.patterns) | Patterns to flag in checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns) | +| [expect.txt](expect.txt) | Expected words that aren't in the dictionary | one word per line (sorted, alphabetically) | [expect](https://github.com/check-spelling/check-spelling/wiki/Configuration#expect) | +| [advice.md](advice.md) | Supplement for GitHub comment when unrecognized words are found | GitHub Markdown | [advice](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice) | Note: you can replace any of these files with a directory by the same name (minus the suffix) and then include multiple files inside that directory (with that suffix) to merge multiple files together. diff --git a/.github/actions/spelling/advice.md b/.github/actions/spelling/advice.md index a32d1090..17445e53 100644 --- a/.github/actions/spelling/advice.md +++ b/.github/actions/spelling/advice.md @@ -2,30 +2,27 @@
If the flagged items are :exploding_head: false positives If items relate to a ... -* binary file (or some other file you wouldn't want to check at all). + +- binary file (or some other file you wouldn't want to check at all). Please add a file path to the `excludes.txt` file matching the containing file. - File paths are Perl 5 Regular Expressions - you can [test]( -https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files. + File paths are Perl 5 Regular Expressions - you can [test](https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files. - `^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude [README.md]( -../tree/HEAD/README.md) (on whichever branch you're using). + `^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude [README.md](../tree/HEAD/README.md) (on whichever branch you're using). -* well-formed pattern. +- well-formed pattern. - If you can write a [pattern]( -https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns -) that would match it, + If you can write a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it, try adding it to the `patterns.txt` file. - Patterns are Perl 5 Regular Expressions - you can [test]( -https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines. + Patterns are Perl 5 Regular Expressions - you can [test](https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines. Note that patterns can't match multiline strings.
+ :steam_locomotive: If you're seeing this message and your PR is from a branch that doesn't have check-spelling, please merge to your PR's base branch to get the version configured for your repository. diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index 113528cb..9a2be625 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -74,6 +74,7 @@ Cscript daemonizing databento dayjob +dco DDOS Debian debrpm @@ -134,6 +135,7 @@ gipc gitea GLM godotenv +goimports goland gomod goodbot @@ -367,6 +369,7 @@ VKE vnd VPS Vultr +WAIFU weblate webmaster webpage @@ -404,3 +407,4 @@ Zenos zizmor zombocom zos +zst diff --git a/.github/workflows/asset-verification.yml b/.github/workflows/asset-verification.yml index f6595036..4a0286a4 100644 --- a/.github/workflows/asset-verification.yml +++ b/.github/workflows/asset-verification.yml @@ -24,10 +24,10 @@ jobs: - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: - node-version: '24.11.0' + node-version: "24.11.0" - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: - go-version: '1.25.4' + go-version: "1.25.4" - name: install node deps run: | diff --git a/.github/workflows/dco-check.yaml b/.github/workflows/dco-check.yaml new file mode 100644 index 00000000..1b7561a6 --- /dev/null +++ b/.github/workflows/dco-check.yaml @@ -0,0 +1,9 @@ +name: DCO Check + +on: [pull_request] + +jobs: + dco_check: + runs-on: ubuntu-latest + steps: + - uses: tisonkun/actions-dco@f1024cd563550b5632e754df11b7d30b73be54a5 # v1.1 diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index 25e086e8..f5d70ca8 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -28,10 +28,10 @@ jobs: - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: - node-version: '24.11.0' + node-version: "24.11.0" - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: - go-version: '1.25.4' + go-version: "1.25.4" - uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9 diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 1954ba86..b2db3f30 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -38,10 +38,10 @@ jobs: - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: - node-version: '24.11.0' + node-version: "24.11.0" - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: - go-version: '1.25.4' + go-version: "1.25.4" - uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9 diff --git a/.github/workflows/go-mod-tidy-check.yml b/.github/workflows/go-mod-tidy-check.yml index 5eb3a2e2..19377f7b 100644 --- a/.github/workflows/go-mod-tidy-check.yml +++ b/.github/workflows/go-mod-tidy-check.yml @@ -19,7 +19,7 @@ jobs: - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: - go-version: '1.25.4' + go-version: "1.25.4" - name: Check go.mod and go.sum in main directory run: | diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 96a101e4..1d8ee269 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -26,10 +26,10 @@ jobs: - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: - node-version: '24.11.0' + node-version: "24.11.0" - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: - go-version: '1.25.4' + go-version: "1.25.4" - name: Cache playwright binaries uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2 diff --git a/.github/workflows/lint-pr-title.yaml b/.github/workflows/lint-pr-title.yaml new file mode 100644 index 00000000..2ee7b737 --- /dev/null +++ b/.github/workflows/lint-pr-title.yaml @@ -0,0 +1,19 @@ +name: "Lint PR" + +on: + pull_request_target: + types: + - opened + - edited + - synchronize + +jobs: + lint_pr_title: + name: Validate PR title + runs-on: ubuntu-latest + permissions: + pull-requests: read + steps: + - uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017 # v5.5.3 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-builds-stable.yml b/.github/workflows/package-builds-stable.yml index a77b77f2..c66af3da 100644 --- a/.github/workflows/package-builds-stable.yml +++ b/.github/workflows/package-builds-stable.yml @@ -27,10 +27,10 @@ jobs: - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: - node-version: '24.11.0' + node-version: "24.11.0" - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: - go-version: '1.25.4' + go-version: "1.25.4" - name: install node deps run: | diff --git a/.github/workflows/package-builds-unstable.yml b/.github/workflows/package-builds-unstable.yml index 11cc060f..9bc6de97 100644 --- a/.github/workflows/package-builds-unstable.yml +++ b/.github/workflows/package-builds-unstable.yml @@ -28,10 +28,10 @@ jobs: - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: - node-version: '24.11.0' + node-version: "24.11.0" - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: - go-version: '1.25.4' + go-version: "1.25.4" - name: install node deps run: | diff --git a/.github/workflows/spelling.yml b/.github/workflows/spelling.yml index 6ce8bd8c..599cc784 100644 --- a/.github/workflows/spelling.yml +++ b/.github/workflows/spelling.yml @@ -59,16 +59,16 @@ name: Check Spelling on: push: branches: - - '**' + - "**" tags-ignore: - - '**' + - "**" pull_request: branches: - - '**' + - "**" types: - - 'opened' - - 'reopened' - - 'synchronize' + - "opened" + - "reopened" + - "synchronize" jobs: spelling: diff --git a/.github/workflows/ssh-ci.yml b/.github/workflows/ssh-ci.yml index bb1e5d9d..fba87269 100644 --- a/.github/workflows/ssh-ci.yml +++ b/.github/workflows/ssh-ci.yml @@ -37,7 +37,7 @@ jobs: - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: - go-version: '1.25.4' + go-version: "1.25.4" - name: Run CI run: go run ./utils/cmd/backoff-retry bash test/ssh-ci/rigging.sh ${{ matrix.host }} diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 2c0da877..641f6360 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -1,12 +1,12 @@ name: zizmor on: - push: - paths: - - '.github/workflows/*.ya?ml' - pull_request: - paths: - - '.github/workflows/*.ya?ml' + push: + paths: + - ".github/workflows/*.ya?ml" + pull_request: + paths: + - ".github/workflows/*.ya?ml" jobs: zizmor: @@ -24,9 +24,9 @@ jobs: uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7.2.0 - name: Run zizmor 🌈 - run: uvx zizmor --format sarif . > results.sarif + run: uvx zizmor --format sarif . > results.sarif env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload SARIF file uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100644 index 00000000..cbed8544 --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1,8 @@ +npx --no-install commitlint --edit "$1" + +# Check if commit message contains Signed-off-by line +if ! grep -q "^Signed-off-by:" "$1"; then + echo "Commit message must contain a 'Signed-off-by:' line." + echo "Please use 'git commit --signoff' or add a Signed-off-by line to your commit message." + exit 1 +fi diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 00000000..ab4c1191 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,2 @@ +npm run lint +npm run test diff --git a/.ko.yaml b/.ko.yaml index 35c1fa01..3be52db6 100644 --- a/.ko.yaml +++ b/.ko.yaml @@ -1,13 +1,13 @@ defaultBaseImage: cgr.dev/chainguard/static defaultPlatforms: -- linux/arm64 -- linux/amd64 -- linux/arm/v7 + - linux/arm64 + - linux/amd64 + - linux/arm/v7 builds: -- id: anubis - main: ./cmd/anubis - ldflags: - - -s -w - - -extldflags "-static" - - -X github.com/TecharoHQ/anubis.Version={{.Env.VERSION}} + - id: anubis + main: ./cmd/anubis + ldflags: + - -s -w + - -extldflags "-static" + - -X github.com/TecharoHQ/anubis.Version={{.Env.VERSION}} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..04f75622 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +lib/config/testdata/bad/* +*.inc \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 6e2ae177..5305d550 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -8,4 +8,4 @@ "redhat.vscode-yaml", "streetsidesoftware.code-spell-checker" ] -} \ No newline at end of file +} diff --git a/.vscode/launch.json b/.vscode/launch.json index f6db59f0..4e495937 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -24,4 +24,4 @@ "type": "node-terminal" } ] -} \ No newline at end of file +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..d7013fa7 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,144 @@ +# Contributing to Anubis + +Anubis is a Web AI Firewall Utility (WAIFU) written in Go. It uses sha256 proof-of-work challenges to protect upstream HTTP resources from scraper bots. This is security software -- correctness matters. + +## Build & Run + +Prerequisites: Go 1.24+, Node.js (any supported version), esbuild, gzip, zstd, brotli. Install all with `brew bundle` if you are using Homebrew. + +```shell +npm ci # install node dependencies +npm run assets # build JS/CSS (required before any Go build/test) +npm run build # assets + go build -> ./var/anubis +npm run dev # assets + run locally with --use-remote-address +``` + +## Testing + +```shell +# Run all unit tests (assets must be built first) +npm run test # or: make test + +# Run a single test by name +go test -run TestClampIP ./internal/ + +# Run a single test file's package +go test ./lib/config/ + +# Run tests with verbose output +go test -v -run TestBotValid ./lib/config/ +``` + +### Smoke tests + +The `tests` folder contains "smoke tests" that are intended to set up Anubis in production-adjacent settings and testing it against real infrastructure tools. A smoke test is a folder with `test.sh` that sets up infrastructure, validates the behaviour, and then tears it down. Smoke tests are run in GitHub actions with `.github/workflows/smoke-tests.yaml`. + +## Linting + +```shell +go vet ./... +go tool staticcheck ./... +go tool govulncheck ./... +``` + +## Code Generation + +The project uses `go generate` for templ templates and stringer. Always run `npm run generate` (or `make assets`) before building or testing. Generated files include: + +- `web/*.templ` -> templ-generated Go code +- `web/static/` -> bundled/minified JS and CSS (with .gz, .zst, .br variants) + +## Project Layout + +Important folders: + +- `cmd/anubis`: Main entrypoint for the project. This is the program that runs on servers. +- `lib/*`: The core library for Anubis and all of its features. This is internal code that is made public for ease of downstream consumption. No API stability is guaranteed. Use at your own risk. +- `internal/*`: Actual internal code that is private to the implementation of Anubis. If you need to use a package in this, please copy it out and manually vendor it in your own project. +- `test/*` Smoke tests (see dedicated section for details). +- `web`: Frontend HTML templates. +- `xess`: Frontend CSS framework and build logic. + +## Code Style + +### Go + +This project follows the idioms of the Go standard library. Generally follow the patterns that upstream Go uses, including: + +- Prefer packages from the standard library unless there is no other option. +- Use package import aliases only when package names collide. +- Use `goimports` to format code. Run with `npm run format`. +- Use sentinel errors as package-level variables prefixed with `Err` (such as `ErrBotMustHaveName`). Wrap with `fmt.Errorf("package: small message giving context: %w", err)`. +- Use `log/slog` for structured logging. Pass loggers as arguments to functions. Use `lg.With` to preload with context. Prefer using `slog.Debug` unless you absolutely need to report messages to users, some users have magical thinking about log verbosity. +- Name PublicFunctionsAndTypes in PascalCase. Name privateFunctionsAndTypes in camelCase. +- Acronyms stay uppercase (`URL`, `HTTP`, `IP`, `DNS`, etc.) +- Enumerations should use strong types with validation logic for parsing remote input. +- Be conservative in what you send but liberal in what you accept. +- Anything reading configuration values should use both `json` and `yaml` struct tags. Use pointer values for optional configuration values. +- Use [table-driven tests](https://go.dev/wiki/TableDrivenTests) when writing test code. +- Use [`t.Helper()`](https://pkg.go.dev/testing#T.Helper) in helper code (setup/teardown scaffolding). +- Use [`t.Cleanup()`](https://pkg.go.dev/testing#T.Cleanup) to tear down per-test or per-suite scaffolding. +- Use [`errors.Is`](https://pkg.go.dev/errors#Is) for validating function results against sentinel errors. +- Prefer same-package tests over black-box tests (`_test` packages). + +### JavaScript / TypeScript + +- Source lives in `web/js/`. Built with esbuild, bundled and minified. +- Uses Preact (not React). +- No linter config. Keep functions small. Use `const` by default. + +### Templ Templates + +Anubis uses [Templ](https://templ.guide) for generating HTML on the server. + +- `.templ` files in `web/` generate Go code. Run `go generate ./...` (or `npm run assets`) after modifying them. +- Templates receive typed Go parameters. Keep logic in Go, not templates. + +## Commit Messages + +Commit messages follow the [**Conventional Commits**](https://www.conventionalcommits.org/en/v1.0.0/) format: + +```text +[optional scope]: + +[optional body] + +[optional footer(s)] +``` + +**Types**: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert` + +- Add `!` after type/scope for breaking changes or include `BREAKING CHANGE:` in the footer. +- Keep descriptions concise, imperative, lowercase, and without a trailing period. +- Reference issues/PRs in the footer when applicable. +- **ALL git commits MUST be made with `--signoff`.** This is mandatory. + +### Attribution Requirements + +AI agents must disclose what tool and model they are using in the "Assisted-by" commit footer: + +```text +Assisted-by: [Model Name] via [Tool Name] +``` + +Example: + +```text +Assisted-by: GLM 4.6 via Claude Code +``` + +## PR Checklist + +- Add description of changes to `[Unreleased]` in `docs/docs/CHANGELOG.md`. +- Add test cases for bug fixes and behavior changes. +- Run integration tests: `npm run test:integration`. +- All commits must have verified (signed) signatures. + +## Key Conventions + +- **Security-first**: This is security software. Code reviews are strict. Always add tests for bug fixes. Consider adversarial inputs. +- **Configuration**: YAML-based policy files. Config structs validate via `Valid() error` methods returning sentinel errors. +- **Store interface**: `lib/store.Interface` abstracts key-value storage. +- **Environment variables**: Parsed from flags via `flagenv`. Use `.env` files locally (loaded by `godotenv/autoload`). Never commit `.env` files. +- **Assets must be built first**: JS/CSS assets are embedded into the Go binary. Always run `npm run assets` before `go test` or `go build`. +- **CEL expressions**: Policy rules support CEL (Common Expression Language) expressions for advanced matching. See `lib/policy/expressions/`. diff --git a/cmd/robots2policy/testdata/blacklist.yaml b/cmd/robots2policy/testdata/blacklist.yaml index a3096f51..1f8fbabd 100644 --- a/cmd/robots2policy/testdata/blacklist.yaml +++ b/cmd/robots2policy/testdata/blacklist.yaml @@ -25,6 +25,6 @@ - action: CHALLENGE expression: all: - - userAgent.contains("Googlebot") - - path.startsWith("/search") + - userAgent.contains("Googlebot") + - path.startsWith("/search") name: robots-txt-policy-disallow-7 diff --git a/cmd/robots2policy/testdata/complex.yaml b/cmd/robots2policy/testdata/complex.yaml index 6e677ad2..d6ddeb63 100644 --- a/cmd/robots2policy/testdata/complex.yaml +++ b/cmd/robots2policy/testdata/complex.yaml @@ -20,8 +20,8 @@ - action: CHALLENGE expression: all: - - userAgent.contains("Googlebot") - - path.startsWith("/search/") + - userAgent.contains("Googlebot") + - path.startsWith("/search/") name: robots-txt-policy-disallow-6 - action: WEIGH expression: userAgent.contains("Bingbot") @@ -31,14 +31,14 @@ - action: CHALLENGE expression: all: - - userAgent.contains("Bingbot") - - path.startsWith("/search/") + - userAgent.contains("Bingbot") + - path.startsWith("/search/") name: robots-txt-policy-disallow-8 - action: CHALLENGE expression: all: - - userAgent.contains("Bingbot") - - path.startsWith("/admin/") + - userAgent.contains("Bingbot") + - path.startsWith("/admin/") name: robots-txt-policy-disallow-9 - action: DENY expression: userAgent.contains("BadBot") @@ -54,18 +54,18 @@ - action: CHALLENGE expression: all: - - userAgent.contains("TestBot") - - path.matches("^/.*/admin") + - userAgent.contains("TestBot") + - path.matches("^/.*/admin") name: robots-txt-policy-disallow-13 - action: CHALLENGE expression: all: - - userAgent.contains("TestBot") - - path.matches("^/temp.*\\.html") + - userAgent.contains("TestBot") + - path.matches("^/temp.*\\.html") name: robots-txt-policy-disallow-14 - action: CHALLENGE expression: all: - - userAgent.contains("TestBot") - - path.matches("^/file.\\.log") + - userAgent.contains("TestBot") + - path.matches("^/file.\\.log") name: robots-txt-policy-disallow-15 diff --git a/cmd/robots2policy/testdata/consecutive.yaml b/cmd/robots2policy/testdata/consecutive.yaml index 144abda0..3ba3dde5 100644 --- a/cmd/robots2policy/testdata/consecutive.yaml +++ b/cmd/robots2policy/testdata/consecutive.yaml @@ -9,39 +9,39 @@ - action: DENY expression: any: - - userAgent.contains("BadBot") - - userAgent.contains("SpamBot") - - userAgent.contains("EvilBot") + - userAgent.contains("BadBot") + - userAgent.contains("SpamBot") + - userAgent.contains("EvilBot") name: robots-txt-policy-blacklist-3 - action: CHALLENGE expression: all: - - userAgent.contains("GoodBot") - - path.startsWith("/private") + - userAgent.contains("GoodBot") + - path.startsWith("/private") name: robots-txt-policy-disallow-4 - action: WEIGH expression: any: - - userAgent.contains("SlowBot1") - - userAgent.contains("SlowBot2") + - userAgent.contains("SlowBot1") + - userAgent.contains("SlowBot2") name: robots-txt-policy-crawl-delay-5 weight: adjust: 3 - action: CHALLENGE expression: all: - - userAgent.contains("SearchBot1") - - path.startsWith("/search") + - userAgent.contains("SearchBot1") + - path.startsWith("/search") name: robots-txt-policy-disallow-7 - action: CHALLENGE expression: all: - - userAgent.contains("SearchBot2") - - path.startsWith("/search") + - userAgent.contains("SearchBot2") + - path.startsWith("/search") name: robots-txt-policy-disallow-8 - action: CHALLENGE expression: all: - - userAgent.contains("SearchBot3") - - path.startsWith("/search") + - userAgent.contains("SearchBot3") + - path.startsWith("/search") name: robots-txt-policy-disallow-9 diff --git a/cmd/robots2policy/testdata/empty.yaml b/cmd/robots2policy/testdata/empty.yaml index 0637a088..fe51488c 100644 --- a/cmd/robots2policy/testdata/empty.yaml +++ b/cmd/robots2policy/testdata/empty.yaml @@ -1 +1 @@ -[] \ No newline at end of file +[] diff --git a/cmd/robots2policy/testdata/simple.json b/cmd/robots2policy/testdata/simple.json index c8e1de09..72207e9c 100644 --- a/cmd/robots2policy/testdata/simple.json +++ b/cmd/robots2policy/testdata/simple.json @@ -9,4 +9,4 @@ "name": "robots-txt-policy-disallow-2", "action": "CHALLENGE" } -] \ No newline at end of file +] diff --git a/data/apps/allow-api-routes.yaml b/data/apps/allow-api-routes.yaml index 0cc3e3bf..61d1541b 100644 --- a/data/apps/allow-api-routes.yaml +++ b/data/apps/allow-api-routes.yaml @@ -2,5 +2,5 @@ action: ALLOW expression: all: - - '!(method == "HEAD" || method == "GET")' - - path.startsWith("/api/") \ No newline at end of file + - '!(method == "HEAD" || method == "GET")' + - path.startsWith("/api/") diff --git a/data/apps/gitea-rss-feeds.yaml b/data/apps/gitea-rss-feeds.yaml index 7bd34ceb..89dec844 100644 --- a/data/apps/gitea-rss-feeds.yaml +++ b/data/apps/gitea-rss-feeds.yaml @@ -4,4 +4,4 @@ path_regex: ^/[.A-Za-z0-9_-]{1,256}?[./A-Za-z0-9_-]*\.atom$ - name: gitea-feed-rss action: ALLOW - path_regex: ^/[.A-Za-z0-9_-]{1,256}?[./A-Za-z0-9_-]*\.rss$ \ No newline at end of file + path_regex: ^/[.A-Za-z0-9_-]{1,256}?[./A-Za-z0-9_-]*\.rss$ diff --git a/data/apps/qualys-ssl-labs.yml b/data/apps/qualys-ssl-labs.yml index 3a9ed386..8dc6ab6e 100644 --- a/data/apps/qualys-ssl-labs.yml +++ b/data/apps/qualys-ssl-labs.yml @@ -3,6 +3,6 @@ - name: qualys-ssl-labs action: ALLOW remote_addresses: - - 69.67.183.0/24 - - 2600:C02:1020:4202::/64 - - 2602:fdaa:c6:2::/64 \ No newline at end of file + - 69.67.183.0/24 + - 2600:C02:1020:4202::/64 + - 2602:fdaa:c6:2::/64 diff --git a/data/apps/searx-checker.yml b/data/apps/searx-checker.yml index c6da25f8..a6063c91 100644 --- a/data/apps/searx-checker.yml +++ b/data/apps/searx-checker.yml @@ -5,5 +5,5 @@ - name: searx-checker action: ALLOW remote_addresses: - - 167.235.158.251/32 - - 2a01:4f8:1c1c:8fc2::1/128 \ No newline at end of file + - 167.235.158.251/32 + - 2a01:4f8:1c1c:8fc2::1/128 diff --git a/data/bots/headless-browsers.yaml b/data/bots/headless-browsers.yaml index 98052906..bac2d8ed 100644 --- a/data/bots/headless-browsers.yaml +++ b/data/bots/headless-browsers.yaml @@ -6,4 +6,4 @@ action: DENY - name: headless-chromium user_agent_regex: HeadlessChromium - action: DENY \ No newline at end of file + action: DENY diff --git a/data/bots/irc-bots/archlinux-phrik.yaml b/data/bots/irc-bots/archlinux-phrik.yaml index 6124e2e3..93e37915 100644 --- a/data/bots/irc-bots/archlinux-phrik.yaml +++ b/data/bots/irc-bots/archlinux-phrik.yaml @@ -3,7 +3,7 @@ action: ALLOW expression: all: - - remoteAddress == "159.69.213.214" || remoteAddress == "2a01:4f8:c2c:7bf4::1" - - userAgent == "Mozilla/5.0 (compatible; utils.web Limnoria module)" - - '"X-Http-Version" in headers' - - headers["X-Http-Version"] == "HTTP/1.1" \ No newline at end of file + - remoteAddress == "159.69.213.214" || remoteAddress == "2a01:4f8:c2c:7bf4::1" + - userAgent == "Mozilla/5.0 (compatible; utils.web Limnoria module)" + - '"X-Http-Version" in headers' + - headers["X-Http-Version"] == "HTTP/1.1" diff --git a/data/bots/irc-bots/gentoo-chat.yaml b/data/bots/irc-bots/gentoo-chat.yaml index 92f2a4f5..30db4a11 100644 --- a/data/bots/irc-bots/gentoo-chat.yaml +++ b/data/bots/irc-bots/gentoo-chat.yaml @@ -3,7 +3,7 @@ action: ALLOW expression: all: - - remoteAddress == "45.76.166.57" - - userAgent == "Mozilla/5.0 (Linux x86_64; rv:76.0) Gecko/20100101 Firefox/76.0" - - '"X-Http-Version" in headers' - - headers["X-Http-Version"] == "HTTP/1.1" \ No newline at end of file + - remoteAddress == "45.76.166.57" + - userAgent == "Mozilla/5.0 (Linux x86_64; rv:76.0) Gecko/20100101 Firefox/76.0" + - '"X-Http-Version" in headers' + - headers["X-Http-Version"] == "HTTP/1.1" diff --git a/data/bots/us-ai-scraper.yaml b/data/bots/us-ai-scraper.yaml index b68920f7..90b4994b 100644 --- a/data/bots/us-ai-scraper.yaml +++ b/data/bots/us-ai-scraper.yaml @@ -1,3 +1,3 @@ - name: us-artificial-intelligence-scraper user_agent_regex: \+https\://github\.com/US-Artificial-Intelligence/scraper - action: DENY \ No newline at end of file + action: DENY diff --git a/data/clients/go-get.yaml b/data/clients/go-get.yaml index 701bd5d8..d9e8aa52 100644 --- a/data/clients/go-get.yaml +++ b/data/clients/go-get.yaml @@ -2,6 +2,6 @@ action: ALLOW expression: all: - - userAgent.startsWith("Go-http-client/") - - '"go-get" in query' - - query["go-get"] == "1" \ No newline at end of file + - userAgent.startsWith("Go-http-client/") + - '"go-get" in query' + - query["go-get"] == "1" diff --git a/data/clients/mistral-mistralai-user.yaml b/data/clients/mistral-mistralai-user.yaml index 59b86fbd..cf2dfa05 100644 --- a/data/clients/mistral-mistralai-user.yaml +++ b/data/clients/mistral-mistralai-user.yaml @@ -4,7 +4,4 @@ user_agent_regex: MistralAI-User/.+; \+https\://docs\.mistral\.ai/robots action: ALLOW # https://mistral.ai/mistralai-user-ips.json - remote_addresses: [ - "20.240.160.161/32", - "20.240.160.1/32", - ] \ No newline at end of file + remote_addresses: ["20.240.160.161/32", "20.240.160.1/32"] diff --git a/data/clients/openai-chatgpt-user.yaml b/data/clients/openai-chatgpt-user.yaml index 063cf08d..9b3208bd 100644 --- a/data/clients/openai-chatgpt-user.yaml +++ b/data/clients/openai-chatgpt-user.yaml @@ -5,89 +5,90 @@ action: ALLOW # https://openai.com/chatgpt-user.json # curl 'https://openai.com/chatgpt-user.json' | jq '.prefixes.[].ipv4Prefix' | sed 's/$/,/' - remote_addresses: [ - "13.65.138.112/28", - "23.98.179.16/28", - "13.65.138.96/28", - "172.183.222.128/28", - "20.102.212.144/28", - "40.116.73.208/28", - "172.183.143.224/28", - "52.190.190.16/28", - "13.83.237.176/28", - "51.8.155.64/28", - "74.249.86.176/28", - "51.8.155.48/28", - "20.55.229.144/28", - "135.237.131.208/28", - "135.237.133.48/28", - "51.8.155.112/28", - "135.237.133.112/28", - "52.159.249.96/28", - "52.190.137.16/28", - "52.255.111.112/28", - "40.84.181.32/28", - "172.178.141.112/28", - "52.190.142.64/28", - "172.178.140.144/28", - "52.190.137.144/28", - "172.178.141.128/28", - "57.154.187.32/28", - "4.196.118.112/28", - "20.193.50.32/28", - "20.215.188.192/28", - "20.215.214.16/28", - "4.197.22.112/28", - "4.197.115.112/28", - "172.213.21.16/28", - "172.213.11.144/28", - "172.213.12.112/28", - "172.213.21.144/28", - "20.90.7.144/28", - "57.154.175.0/28", - "57.154.174.112/28", - "52.236.94.144/28", - "137.135.191.176/28", - "23.98.186.192/28", - "23.98.186.96/28", - "23.98.186.176/28", - "23.98.186.64/28", - "68.221.67.192/28", - "68.221.67.160/28", - "13.83.167.128/28", - "20.228.106.176/28", - "52.159.227.32/28", - "68.220.57.64/28", - "172.213.21.112/28", - "68.221.67.224/28", - "68.221.75.16/28", - "20.97.189.96/28", - "52.252.113.240/28", - "52.230.163.32/28", - "172.212.159.64/28", - "52.255.111.80/28", - "52.255.111.0/28", - "4.151.241.240/28", - "52.255.111.32/28", - "52.255.111.48/28", - "52.255.111.16/28", - "52.230.164.176/28", - "52.176.139.176/28", - "52.173.234.16/28", - "4.151.71.176/28", - "4.151.119.48/28", - "52.255.109.112/28", - "52.255.109.80/28", - "20.161.75.208/28", - "68.154.28.96/28", - "52.255.109.128/28", - "52.225.75.208/28", - "52.190.139.48/28", - "68.221.67.240/28", - "52.156.77.144/28", - "52.148.129.32/28", - "40.84.221.208/28", - "104.210.139.224/28", - "40.84.221.224/28", - "104.210.139.192/28", - ] \ No newline at end of file + remote_addresses: + [ + "13.65.138.112/28", + "23.98.179.16/28", + "13.65.138.96/28", + "172.183.222.128/28", + "20.102.212.144/28", + "40.116.73.208/28", + "172.183.143.224/28", + "52.190.190.16/28", + "13.83.237.176/28", + "51.8.155.64/28", + "74.249.86.176/28", + "51.8.155.48/28", + "20.55.229.144/28", + "135.237.131.208/28", + "135.237.133.48/28", + "51.8.155.112/28", + "135.237.133.112/28", + "52.159.249.96/28", + "52.190.137.16/28", + "52.255.111.112/28", + "40.84.181.32/28", + "172.178.141.112/28", + "52.190.142.64/28", + "172.178.140.144/28", + "52.190.137.144/28", + "172.178.141.128/28", + "57.154.187.32/28", + "4.196.118.112/28", + "20.193.50.32/28", + "20.215.188.192/28", + "20.215.214.16/28", + "4.197.22.112/28", + "4.197.115.112/28", + "172.213.21.16/28", + "172.213.11.144/28", + "172.213.12.112/28", + "172.213.21.144/28", + "20.90.7.144/28", + "57.154.175.0/28", + "57.154.174.112/28", + "52.236.94.144/28", + "137.135.191.176/28", + "23.98.186.192/28", + "23.98.186.96/28", + "23.98.186.176/28", + "23.98.186.64/28", + "68.221.67.192/28", + "68.221.67.160/28", + "13.83.167.128/28", + "20.228.106.176/28", + "52.159.227.32/28", + "68.220.57.64/28", + "172.213.21.112/28", + "68.221.67.224/28", + "68.221.75.16/28", + "20.97.189.96/28", + "52.252.113.240/28", + "52.230.163.32/28", + "172.212.159.64/28", + "52.255.111.80/28", + "52.255.111.0/28", + "4.151.241.240/28", + "52.255.111.32/28", + "52.255.111.48/28", + "52.255.111.16/28", + "52.230.164.176/28", + "52.176.139.176/28", + "52.173.234.16/28", + "4.151.71.176/28", + "4.151.119.48/28", + "52.255.109.112/28", + "52.255.109.80/28", + "20.161.75.208/28", + "68.154.28.96/28", + "52.255.109.128/28", + "52.225.75.208/28", + "52.190.139.48/28", + "68.221.67.240/28", + "52.156.77.144/28", + "52.148.129.32/28", + "40.84.221.208/28", + "104.210.139.224/28", + "40.84.221.224/28", + "104.210.139.192/28", + ] diff --git a/data/clients/perplexity-user.yaml b/data/clients/perplexity-user.yaml index 13f64fda..cb95b2fc 100644 --- a/data/clients/perplexity-user.yaml +++ b/data/clients/perplexity-user.yaml @@ -4,9 +4,5 @@ user_agent_regex: Perplexity-User/.+; \+https\://perplexity\.ai/perplexity-user action: ALLOW # https://www.perplexity.com/perplexity-user.json - remote_addresses: [ - "44.208.221.197/32", - "34.193.163.52/32", - "18.97.21.0/30", - "18.97.43.80/29", - ] + remote_addresses: + ["44.208.221.197/32", "34.193.163.52/32", "18.97.21.0/30", "18.97.43.80/29"] diff --git a/data/clients/telegram-preview.yaml b/data/clients/telegram-preview.yaml index 85076dca..f6be7a8a 100644 --- a/data/clients/telegram-preview.yaml +++ b/data/clients/telegram-preview.yaml @@ -1,6 +1,6 @@ -- name: telegrambot - action: ALLOW - expression: - all: - - userAgent.matches("TelegramBot") - - verifyFCrDNS(remoteAddress, "ptr\\.telegram\\.org$") +- name: telegrambot + action: ALLOW + expression: + all: + - userAgent.matches("TelegramBot") + - verifyFCrDNS(remoteAddress, "ptr\\.telegram\\.org$") diff --git a/data/clients/vk-preview.yaml b/data/clients/vk-preview.yaml index 3e23067a..580afd94 100644 --- a/data/clients/vk-preview.yaml +++ b/data/clients/vk-preview.yaml @@ -1,6 +1,6 @@ -- name: vkbot - action: ALLOW - expression: - all: - - userAgent.matches("vkShare[^+]+\\+http\\://vk\\.com/dev/Share") - - verifyFCrDNS(remoteAddress, "^snipster\\d+\\.go\\.mail\\.ru$") +- name: vkbot + action: ALLOW + expression: + all: + - userAgent.matches("vkShare[^+]+\\+http\\://vk\\.com/dev/Share") + - verifyFCrDNS(remoteAddress, "^snipster\\d+\\.go\\.mail\\.ru$") diff --git a/data/common/allow-api-like.yaml b/data/common/allow-api-like.yaml index 0cc3e3bf..61d1541b 100644 --- a/data/common/allow-api-like.yaml +++ b/data/common/allow-api-like.yaml @@ -2,5 +2,5 @@ action: ALLOW expression: all: - - '!(method == "HEAD" || method == "GET")' - - path.startsWith("/api/") \ No newline at end of file + - '!(method == "HEAD" || method == "GET")' + - path.startsWith("/api/") diff --git a/data/common/json-api.yaml b/data/common/json-api.yaml index b5b51d62..bfe44cf0 100644 --- a/data/common/json-api.yaml +++ b/data/common/json-api.yaml @@ -4,4 +4,4 @@ all: - '"Accept" in headers' - 'headers["Accept"] == "application/json"' - - 'path.startsWith("/api/")' \ No newline at end of file + - 'path.startsWith("/api/")' diff --git a/data/common/rfc-violations.yaml b/data/common/rfc-violations.yaml index 6f933608..eec89f25 100644 --- a/data/common/rfc-violations.yaml +++ b/data/common/rfc-violations.yaml @@ -1,3 +1,3 @@ - name: no-user-agent-string action: DENY - expression: userAgent == "" \ No newline at end of file + expression: userAgent == "" diff --git a/data/crawlers/applebot.yaml b/data/crawlers/applebot.yaml index e75dfe14..9fae2485 100644 --- a/data/crawlers/applebot.yaml +++ b/data/crawlers/applebot.yaml @@ -4,17 +4,18 @@ user_agent_regex: Applebot action: ALLOW # https://search.developer.apple.com/applebot.json - remote_addresses: [ - "17.241.208.160/27", - "17.241.193.160/27", - "17.241.200.160/27", - "17.22.237.0/24", - "17.22.245.0/24", - "17.22.253.0/24", - "17.241.75.0/24", - "17.241.219.0/24", - "17.241.227.0/24", - "17.246.15.0/24", - "17.246.19.0/24", - "17.246.23.0/24", - ] + remote_addresses: + [ + "17.241.208.160/27", + "17.241.193.160/27", + "17.241.200.160/27", + "17.22.237.0/24", + "17.22.245.0/24", + "17.22.253.0/24", + "17.241.75.0/24", + "17.241.219.0/24", + "17.241.227.0/24", + "17.246.15.0/24", + "17.246.19.0/24", + "17.246.23.0/24", + ] diff --git a/data/crawlers/bingbot.yaml b/data/crawlers/bingbot.yaml index 2f7885dd..8d5b2e0f 100644 --- a/data/crawlers/bingbot.yaml +++ b/data/crawlers/bingbot.yaml @@ -2,33 +2,34 @@ user_agent_regex: \+http\://www\.bing\.com/bingbot\.htm action: ALLOW # https://www.bing.com/toolbox/bingbot.json - remote_addresses: [ - "157.55.39.0/24", - "207.46.13.0/24", - "40.77.167.0/24", - "13.66.139.0/24", - "13.66.144.0/24", - "52.167.144.0/24", - "13.67.10.16/28", - "13.69.66.240/28", - "13.71.172.224/28", - "139.217.52.0/28", - "191.233.204.224/28", - "20.36.108.32/28", - "20.43.120.16/28", - "40.79.131.208/28", - "40.79.186.176/28", - "52.231.148.0/28", - "20.79.107.240/28", - "51.105.67.0/28", - "20.125.163.80/28", - "40.77.188.0/22", - "65.55.210.0/24", - "199.30.24.0/23", - "40.77.202.0/24", - "40.77.139.0/25", - "20.74.197.0/28", - "20.15.133.160/27", - "40.77.177.0/24", - "40.77.178.0/23" - ] + remote_addresses: + [ + "157.55.39.0/24", + "207.46.13.0/24", + "40.77.167.0/24", + "13.66.139.0/24", + "13.66.144.0/24", + "52.167.144.0/24", + "13.67.10.16/28", + "13.69.66.240/28", + "13.71.172.224/28", + "139.217.52.0/28", + "191.233.204.224/28", + "20.36.108.32/28", + "20.43.120.16/28", + "40.79.131.208/28", + "40.79.186.176/28", + "52.231.148.0/28", + "20.79.107.240/28", + "51.105.67.0/28", + "20.125.163.80/28", + "40.77.188.0/22", + "65.55.210.0/24", + "199.30.24.0/23", + "40.77.202.0/24", + "40.77.139.0/25", + "20.74.197.0/28", + "20.15.133.160/27", + "40.77.177.0/24", + "40.77.178.0/23", + ] diff --git a/data/crawlers/duckduckbot.yaml b/data/crawlers/duckduckbot.yaml index 302a1e38..4b3ed161 100644 --- a/data/crawlers/duckduckbot.yaml +++ b/data/crawlers/duckduckbot.yaml @@ -2,274 +2,275 @@ user_agent_regex: DuckDuckBot/1\.1; \(\+http\://duckduckgo\.com/duckduckbot\.html\) action: ALLOW # https://duckduckgo.com/duckduckgo-help-pages/results/duckduckbot - remote_addresses: [ - "57.152.72.128/32", - "51.8.253.152/32", - "40.80.242.63/32", - "20.12.141.99/32", - "20.49.136.28/32", - "51.116.131.221/32", - "51.107.40.209/32", - "20.40.133.240/32", - "20.50.168.91/32", - "51.120.48.122/32", - "20.193.45.113/32", - "40.76.173.151/32", - "40.76.163.7/32", - "20.185.79.47/32", - "52.142.26.175/32", - "20.185.79.15/32", - "52.142.24.149/32", - "40.76.162.208/32", - "40.76.163.23/32", - "40.76.162.191/32", - "40.76.162.247/32", - "40.88.21.235/32", - "20.191.45.212/32", - "52.146.59.12/32", - "52.146.59.156/32", - "52.146.59.154/32", - "52.146.58.236/32", - "20.62.224.44/32", - "51.104.180.53/32", - "51.104.180.47/32", - "51.104.180.26/32", - "51.104.146.225/32", - "51.104.146.235/32", - "20.73.202.147/32", - "20.73.132.240/32", - "20.71.12.143/32", - "20.56.197.58/32", - "20.56.197.63/32", - "20.43.150.93/32", - "20.43.150.85/32", - "20.44.222.1/32", - "40.89.243.175/32", - "13.89.106.77/32", - "52.143.242.6/32", - "52.143.241.111/32", - "52.154.60.82/32", - "20.197.209.11/32", - "20.197.209.27/32", - "20.226.133.105/32", - "191.234.216.4/32", - "191.234.216.178/32", - "20.53.92.211/32", - "20.53.91.2/32", - "20.207.99.197/32", - "20.207.97.190/32", - "40.81.250.205/32", - "40.64.106.11/32", - "40.64.105.247/32", - "20.72.242.93/32", - "20.99.255.235/32", - "20.113.3.121/32", - "52.224.16.221/32", - "52.224.21.53/32", - "52.224.20.204/32", - "52.224.21.19/32", - "52.224.20.249/32", - "52.224.20.203/32", - "52.224.20.190/32", - "52.224.16.229/32", - "52.224.21.20/32", - "52.146.63.80/32", - "52.224.20.227/32", - "52.224.20.193/32", - "52.190.37.160/32", - "52.224.21.23/32", - "52.224.20.223/32", - "52.224.20.181/32", - "52.224.21.49/32", - "52.224.21.55/32", - "52.224.21.61/32", - "52.224.19.152/32", - "52.224.20.186/32", - "52.224.21.27/32", - "52.224.21.51/32", - "52.224.20.174/32", - "52.224.21.4/32", - "51.104.164.109/32", - "51.104.167.71/32", - "51.104.160.177/32", - "51.104.162.149/32", - "51.104.167.95/32", - "51.104.167.54/32", - "51.104.166.111/32", - "51.104.167.88/32", - "51.104.161.32/32", - "51.104.163.250/32", - "51.104.164.189/32", - "51.104.167.19/32", - "51.104.160.167/32", - "51.104.167.110/32", - "20.191.44.119/32", - "51.104.167.104/32", - "20.191.44.234/32", - "51.104.164.215/32", - "51.104.167.52/32", - "20.191.44.22/32", - "51.104.167.87/32", - "51.104.167.96/32", - "20.191.44.16/32", - "51.104.167.61/32", - "51.104.164.147/32", - "20.50.48.159/32", - "40.114.182.172/32", - "20.50.50.130/32", - "20.50.50.163/32", - "20.50.50.46/32", - "40.114.182.153/32", - "20.50.50.118/32", - "20.50.49.55/32", - "20.50.49.25/32", - "40.114.183.251/32", - "20.50.50.123/32", - "20.50.49.237/32", - "20.50.48.192/32", - "20.50.50.134/32", - "51.138.90.233/32", - "40.114.183.196/32", - "20.50.50.146/32", - "40.114.183.88/32", - "20.50.50.145/32", - "20.50.50.121/32", - "20.50.49.40/32", - "51.138.90.206/32", - "40.114.182.45/32", - "51.138.90.161/32", - "20.50.49.0/32", - "40.119.232.215/32", - "104.43.55.167/32", - "40.119.232.251/32", - "40.119.232.50/32", - "40.119.232.146/32", - "40.119.232.218/32", - "104.43.54.127/32", - "104.43.55.117/32", - "104.43.55.116/32", - "104.43.55.166/32", - "52.154.169.50/32", - "52.154.171.70/32", - "52.154.170.229/32", - "52.154.170.113/32", - "52.154.171.44/32", - "52.154.172.2/32", - "52.143.244.81/32", - "52.154.171.87/32", - "52.154.171.250/32", - "52.154.170.28/32", - "52.154.170.122/32", - "52.143.243.117/32", - "52.143.247.235/32", - "52.154.171.235/32", - "52.154.171.196/32", - "52.154.171.0/32", - "52.154.170.243/32", - "52.154.170.26/32", - "52.154.169.200/32", - "52.154.170.96/32", - "52.154.170.88/32", - "52.154.171.150/32", - "52.154.171.205/32", - "52.154.170.117/32", - "52.154.170.209/32", - "191.235.202.48/32", - "191.233.3.202/32", - "191.235.201.214/32", - "191.233.3.197/32", - "191.235.202.38/32", - "20.53.78.144/32", - "20.193.24.10/32", - "20.53.78.236/32", - "20.53.78.138/32", - "20.53.78.123/32", - "20.53.78.106/32", - "20.193.27.215/32", - "20.193.25.197/32", - "20.193.12.126/32", - "20.193.24.251/32", - "20.204.242.101/32", - "20.207.72.113/32", - "20.204.242.19/32", - "20.219.45.67/32", - "20.207.72.11/32", - "20.219.45.190/32", - "20.204.243.55/32", - "20.204.241.148/32", - "20.207.72.110/32", - "20.204.240.172/32", - "20.207.72.21/32", - "20.204.246.81/32", - "20.207.107.181/32", - "20.204.246.254/32", - "20.219.43.246/32", - "52.149.25.43/32", - "52.149.61.51/32", - "52.149.58.139/32", - "52.149.60.38/32", - "52.148.165.38/32", - "52.143.95.162/32", - "52.149.56.151/32", - "52.149.30.45/32", - "52.149.58.173/32", - "52.143.95.204/32", - "52.149.28.83/32", - "52.149.58.69/32", - "52.148.161.87/32", - "52.149.58.27/32", - "52.149.28.18/32", - "20.79.226.26/32", - "20.79.239.66/32", - "20.79.238.198/32", - "20.113.14.159/32", - "20.75.144.152/32", - "20.43.172.120/32", - "20.53.134.160/32", - "20.201.15.208/32", - "20.93.28.24/32", - "20.61.34.40/32", - "52.242.224.168/32", - "20.80.129.80/32", - "20.195.108.47/32", - "4.195.133.120/32", - "4.228.76.163/32", - "4.182.131.108/32", - "4.209.224.56/32", - "108.141.83.74/32", - "4.213.46.14/32", - "172.169.17.165/32", - "51.8.71.117/32", - "20.3.1.178/32", - "52.149.56.151/32", - "52.149.30.45/32", - "52.149.58.173/32", - "52.143.95.204/32", - "52.149.28.83/32", - "52.149.58.69/32", - "52.148.161.87/32", - "52.149.58.27/32", - "52.149.28.18/32", - "20.79.226.26/32", - "20.79.239.66/32", - "20.79.238.198/32", - "20.113.14.159/32", - "20.75.144.152/32", - "20.43.172.120/32", - "20.53.134.160/32", - "20.201.15.208/32", - "20.93.28.24/32", - "20.61.34.40/32", - "52.242.224.168/32", - "20.80.129.80/32", - "20.195.108.47/32", - "4.195.133.120/32", - "4.228.76.163/32", - "4.182.131.108/32", - "4.209.224.56/32", - "108.141.83.74/32", - "4.213.46.14/32", - "172.169.17.165/32", - "51.8.71.117/32", - "20.3.1.178/32" - ] + remote_addresses: + [ + "57.152.72.128/32", + "51.8.253.152/32", + "40.80.242.63/32", + "20.12.141.99/32", + "20.49.136.28/32", + "51.116.131.221/32", + "51.107.40.209/32", + "20.40.133.240/32", + "20.50.168.91/32", + "51.120.48.122/32", + "20.193.45.113/32", + "40.76.173.151/32", + "40.76.163.7/32", + "20.185.79.47/32", + "52.142.26.175/32", + "20.185.79.15/32", + "52.142.24.149/32", + "40.76.162.208/32", + "40.76.163.23/32", + "40.76.162.191/32", + "40.76.162.247/32", + "40.88.21.235/32", + "20.191.45.212/32", + "52.146.59.12/32", + "52.146.59.156/32", + "52.146.59.154/32", + "52.146.58.236/32", + "20.62.224.44/32", + "51.104.180.53/32", + "51.104.180.47/32", + "51.104.180.26/32", + "51.104.146.225/32", + "51.104.146.235/32", + "20.73.202.147/32", + "20.73.132.240/32", + "20.71.12.143/32", + "20.56.197.58/32", + "20.56.197.63/32", + "20.43.150.93/32", + "20.43.150.85/32", + "20.44.222.1/32", + "40.89.243.175/32", + "13.89.106.77/32", + "52.143.242.6/32", + "52.143.241.111/32", + "52.154.60.82/32", + "20.197.209.11/32", + "20.197.209.27/32", + "20.226.133.105/32", + "191.234.216.4/32", + "191.234.216.178/32", + "20.53.92.211/32", + "20.53.91.2/32", + "20.207.99.197/32", + "20.207.97.190/32", + "40.81.250.205/32", + "40.64.106.11/32", + "40.64.105.247/32", + "20.72.242.93/32", + "20.99.255.235/32", + "20.113.3.121/32", + "52.224.16.221/32", + "52.224.21.53/32", + "52.224.20.204/32", + "52.224.21.19/32", + "52.224.20.249/32", + "52.224.20.203/32", + "52.224.20.190/32", + "52.224.16.229/32", + "52.224.21.20/32", + "52.146.63.80/32", + "52.224.20.227/32", + "52.224.20.193/32", + "52.190.37.160/32", + "52.224.21.23/32", + "52.224.20.223/32", + "52.224.20.181/32", + "52.224.21.49/32", + "52.224.21.55/32", + "52.224.21.61/32", + "52.224.19.152/32", + "52.224.20.186/32", + "52.224.21.27/32", + "52.224.21.51/32", + "52.224.20.174/32", + "52.224.21.4/32", + "51.104.164.109/32", + "51.104.167.71/32", + "51.104.160.177/32", + "51.104.162.149/32", + "51.104.167.95/32", + "51.104.167.54/32", + "51.104.166.111/32", + "51.104.167.88/32", + "51.104.161.32/32", + "51.104.163.250/32", + "51.104.164.189/32", + "51.104.167.19/32", + "51.104.160.167/32", + "51.104.167.110/32", + "20.191.44.119/32", + "51.104.167.104/32", + "20.191.44.234/32", + "51.104.164.215/32", + "51.104.167.52/32", + "20.191.44.22/32", + "51.104.167.87/32", + "51.104.167.96/32", + "20.191.44.16/32", + "51.104.167.61/32", + "51.104.164.147/32", + "20.50.48.159/32", + "40.114.182.172/32", + "20.50.50.130/32", + "20.50.50.163/32", + "20.50.50.46/32", + "40.114.182.153/32", + "20.50.50.118/32", + "20.50.49.55/32", + "20.50.49.25/32", + "40.114.183.251/32", + "20.50.50.123/32", + "20.50.49.237/32", + "20.50.48.192/32", + "20.50.50.134/32", + "51.138.90.233/32", + "40.114.183.196/32", + "20.50.50.146/32", + "40.114.183.88/32", + "20.50.50.145/32", + "20.50.50.121/32", + "20.50.49.40/32", + "51.138.90.206/32", + "40.114.182.45/32", + "51.138.90.161/32", + "20.50.49.0/32", + "40.119.232.215/32", + "104.43.55.167/32", + "40.119.232.251/32", + "40.119.232.50/32", + "40.119.232.146/32", + "40.119.232.218/32", + "104.43.54.127/32", + "104.43.55.117/32", + "104.43.55.116/32", + "104.43.55.166/32", + "52.154.169.50/32", + "52.154.171.70/32", + "52.154.170.229/32", + "52.154.170.113/32", + "52.154.171.44/32", + "52.154.172.2/32", + "52.143.244.81/32", + "52.154.171.87/32", + "52.154.171.250/32", + "52.154.170.28/32", + "52.154.170.122/32", + "52.143.243.117/32", + "52.143.247.235/32", + "52.154.171.235/32", + "52.154.171.196/32", + "52.154.171.0/32", + "52.154.170.243/32", + "52.154.170.26/32", + "52.154.169.200/32", + "52.154.170.96/32", + "52.154.170.88/32", + "52.154.171.150/32", + "52.154.171.205/32", + "52.154.170.117/32", + "52.154.170.209/32", + "191.235.202.48/32", + "191.233.3.202/32", + "191.235.201.214/32", + "191.233.3.197/32", + "191.235.202.38/32", + "20.53.78.144/32", + "20.193.24.10/32", + "20.53.78.236/32", + "20.53.78.138/32", + "20.53.78.123/32", + "20.53.78.106/32", + "20.193.27.215/32", + "20.193.25.197/32", + "20.193.12.126/32", + "20.193.24.251/32", + "20.204.242.101/32", + "20.207.72.113/32", + "20.204.242.19/32", + "20.219.45.67/32", + "20.207.72.11/32", + "20.219.45.190/32", + "20.204.243.55/32", + "20.204.241.148/32", + "20.207.72.110/32", + "20.204.240.172/32", + "20.207.72.21/32", + "20.204.246.81/32", + "20.207.107.181/32", + "20.204.246.254/32", + "20.219.43.246/32", + "52.149.25.43/32", + "52.149.61.51/32", + "52.149.58.139/32", + "52.149.60.38/32", + "52.148.165.38/32", + "52.143.95.162/32", + "52.149.56.151/32", + "52.149.30.45/32", + "52.149.58.173/32", + "52.143.95.204/32", + "52.149.28.83/32", + "52.149.58.69/32", + "52.148.161.87/32", + "52.149.58.27/32", + "52.149.28.18/32", + "20.79.226.26/32", + "20.79.239.66/32", + "20.79.238.198/32", + "20.113.14.159/32", + "20.75.144.152/32", + "20.43.172.120/32", + "20.53.134.160/32", + "20.201.15.208/32", + "20.93.28.24/32", + "20.61.34.40/32", + "52.242.224.168/32", + "20.80.129.80/32", + "20.195.108.47/32", + "4.195.133.120/32", + "4.228.76.163/32", + "4.182.131.108/32", + "4.209.224.56/32", + "108.141.83.74/32", + "4.213.46.14/32", + "172.169.17.165/32", + "51.8.71.117/32", + "20.3.1.178/32", + "52.149.56.151/32", + "52.149.30.45/32", + "52.149.58.173/32", + "52.143.95.204/32", + "52.149.28.83/32", + "52.149.58.69/32", + "52.148.161.87/32", + "52.149.58.27/32", + "52.149.28.18/32", + "20.79.226.26/32", + "20.79.239.66/32", + "20.79.238.198/32", + "20.113.14.159/32", + "20.75.144.152/32", + "20.43.172.120/32", + "20.53.134.160/32", + "20.201.15.208/32", + "20.93.28.24/32", + "20.61.34.40/32", + "52.242.224.168/32", + "20.80.129.80/32", + "20.195.108.47/32", + "4.195.133.120/32", + "4.228.76.163/32", + "4.182.131.108/32", + "4.209.224.56/32", + "108.141.83.74/32", + "4.213.46.14/32", + "172.169.17.165/32", + "51.8.71.117/32", + "20.3.1.178/32", + ] diff --git a/data/crawlers/googlebot.yaml b/data/crawlers/googlebot.yaml index f1735126..e304cf9c 100644 --- a/data/crawlers/googlebot.yaml +++ b/data/crawlers/googlebot.yaml @@ -2,262 +2,263 @@ user_agent_regex: \+http\://www\.google\.com/bot\.html action: ALLOW # https://developers.google.com/static/search/apis/ipranges/googlebot.json - remote_addresses: [ - "2001:4860:4801:10::/64", - "2001:4860:4801:11::/64", - "2001:4860:4801:12::/64", - "2001:4860:4801:13::/64", - "2001:4860:4801:14::/64", - "2001:4860:4801:15::/64", - "2001:4860:4801:16::/64", - "2001:4860:4801:17::/64", - "2001:4860:4801:18::/64", - "2001:4860:4801:19::/64", - "2001:4860:4801:1a::/64", - "2001:4860:4801:1b::/64", - "2001:4860:4801:1c::/64", - "2001:4860:4801:1d::/64", - "2001:4860:4801:1e::/64", - "2001:4860:4801:1f::/64", - "2001:4860:4801:20::/64", - "2001:4860:4801:21::/64", - "2001:4860:4801:22::/64", - "2001:4860:4801:23::/64", - "2001:4860:4801:24::/64", - "2001:4860:4801:25::/64", - "2001:4860:4801:26::/64", - "2001:4860:4801:27::/64", - "2001:4860:4801:28::/64", - "2001:4860:4801:29::/64", - "2001:4860:4801:2::/64", - "2001:4860:4801:2a::/64", - "2001:4860:4801:2b::/64", - "2001:4860:4801:2c::/64", - "2001:4860:4801:2d::/64", - "2001:4860:4801:2e::/64", - "2001:4860:4801:2f::/64", - "2001:4860:4801:31::/64", - "2001:4860:4801:32::/64", - "2001:4860:4801:33::/64", - "2001:4860:4801:34::/64", - "2001:4860:4801:35::/64", - "2001:4860:4801:36::/64", - "2001:4860:4801:37::/64", - "2001:4860:4801:38::/64", - "2001:4860:4801:39::/64", - "2001:4860:4801:3a::/64", - "2001:4860:4801:3b::/64", - "2001:4860:4801:3c::/64", - "2001:4860:4801:3d::/64", - "2001:4860:4801:3e::/64", - "2001:4860:4801:40::/64", - "2001:4860:4801:41::/64", - "2001:4860:4801:42::/64", - "2001:4860:4801:43::/64", - "2001:4860:4801:44::/64", - "2001:4860:4801:45::/64", - "2001:4860:4801:46::/64", - "2001:4860:4801:47::/64", - "2001:4860:4801:48::/64", - "2001:4860:4801:49::/64", - "2001:4860:4801:4a::/64", - "2001:4860:4801:4b::/64", - "2001:4860:4801:4c::/64", - "2001:4860:4801:50::/64", - "2001:4860:4801:51::/64", - "2001:4860:4801:52::/64", - "2001:4860:4801:53::/64", - "2001:4860:4801:54::/64", - "2001:4860:4801:55::/64", - "2001:4860:4801:56::/64", - "2001:4860:4801:60::/64", - "2001:4860:4801:61::/64", - "2001:4860:4801:62::/64", - "2001:4860:4801:63::/64", - "2001:4860:4801:64::/64", - "2001:4860:4801:65::/64", - "2001:4860:4801:66::/64", - "2001:4860:4801:67::/64", - "2001:4860:4801:68::/64", - "2001:4860:4801:69::/64", - "2001:4860:4801:6a::/64", - "2001:4860:4801:6b::/64", - "2001:4860:4801:6c::/64", - "2001:4860:4801:6d::/64", - "2001:4860:4801:6e::/64", - "2001:4860:4801:6f::/64", - "2001:4860:4801:70::/64", - "2001:4860:4801:71::/64", - "2001:4860:4801:72::/64", - "2001:4860:4801:73::/64", - "2001:4860:4801:74::/64", - "2001:4860:4801:75::/64", - "2001:4860:4801:76::/64", - "2001:4860:4801:77::/64", - "2001:4860:4801:78::/64", - "2001:4860:4801:79::/64", - "2001:4860:4801:80::/64", - "2001:4860:4801:81::/64", - "2001:4860:4801:82::/64", - "2001:4860:4801:83::/64", - "2001:4860:4801:84::/64", - "2001:4860:4801:85::/64", - "2001:4860:4801:86::/64", - "2001:4860:4801:87::/64", - "2001:4860:4801:88::/64", - "2001:4860:4801:90::/64", - "2001:4860:4801:91::/64", - "2001:4860:4801:92::/64", - "2001:4860:4801:93::/64", - "2001:4860:4801:94::/64", - "2001:4860:4801:95::/64", - "2001:4860:4801:96::/64", - "2001:4860:4801:a0::/64", - "2001:4860:4801:a1::/64", - "2001:4860:4801:a2::/64", - "2001:4860:4801:a3::/64", - "2001:4860:4801:a4::/64", - "2001:4860:4801:a5::/64", - "2001:4860:4801:c::/64", - "2001:4860:4801:f::/64", - "192.178.5.0/27", - "192.178.6.0/27", - "192.178.6.128/27", - "192.178.6.160/27", - "192.178.6.192/27", - "192.178.6.32/27", - "192.178.6.64/27", - "192.178.6.96/27", - "34.100.182.96/28", - "34.101.50.144/28", - "34.118.254.0/28", - "34.118.66.0/28", - "34.126.178.96/28", - "34.146.150.144/28", - "34.147.110.144/28", - "34.151.74.144/28", - "34.152.50.64/28", - "34.154.114.144/28", - "34.155.98.32/28", - "34.165.18.176/28", - "34.175.160.64/28", - "34.176.130.16/28", - "34.22.85.0/27", - "34.64.82.64/28", - "34.65.242.112/28", - "34.80.50.80/28", - "34.88.194.0/28", - "34.89.10.80/28", - "34.89.198.80/28", - "34.96.162.48/28", - "35.247.243.240/28", - "66.249.64.0/27", - "66.249.64.128/27", - "66.249.64.160/27", - "66.249.64.224/27", - "66.249.64.32/27", - "66.249.64.64/27", - "66.249.64.96/27", - "66.249.65.0/27", - "66.249.65.128/27", - "66.249.65.160/27", - "66.249.65.192/27", - "66.249.65.224/27", - "66.249.65.32/27", - "66.249.65.64/27", - "66.249.65.96/27", - "66.249.66.0/27", - "66.249.66.128/27", - "66.249.66.160/27", - "66.249.66.192/27", - "66.249.66.224/27", - "66.249.66.32/27", - "66.249.66.64/27", - "66.249.66.96/27", - "66.249.68.0/27", - "66.249.68.128/27", - "66.249.68.32/27", - "66.249.68.64/27", - "66.249.68.96/27", - "66.249.69.0/27", - "66.249.69.128/27", - "66.249.69.160/27", - "66.249.69.192/27", - "66.249.69.224/27", - "66.249.69.32/27", - "66.249.69.64/27", - "66.249.69.96/27", - "66.249.70.0/27", - "66.249.70.128/27", - "66.249.70.160/27", - "66.249.70.192/27", - "66.249.70.224/27", - "66.249.70.32/27", - "66.249.70.64/27", - "66.249.70.96/27", - "66.249.71.0/27", - "66.249.71.128/27", - "66.249.71.160/27", - "66.249.71.192/27", - "66.249.71.224/27", - "66.249.71.32/27", - "66.249.71.64/27", - "66.249.71.96/27", - "66.249.72.0/27", - "66.249.72.128/27", - "66.249.72.160/27", - "66.249.72.192/27", - "66.249.72.224/27", - "66.249.72.32/27", - "66.249.72.64/27", - "66.249.72.96/27", - "66.249.73.0/27", - "66.249.73.128/27", - "66.249.73.160/27", - "66.249.73.192/27", - "66.249.73.224/27", - "66.249.73.32/27", - "66.249.73.64/27", - "66.249.73.96/27", - "66.249.74.0/27", - "66.249.74.128/27", - "66.249.74.160/27", - "66.249.74.192/27", - "66.249.74.32/27", - "66.249.74.64/27", - "66.249.74.96/27", - "66.249.75.0/27", - "66.249.75.128/27", - "66.249.75.160/27", - "66.249.75.192/27", - "66.249.75.224/27", - "66.249.75.32/27", - "66.249.75.64/27", - "66.249.75.96/27", - "66.249.76.0/27", - "66.249.76.128/27", - "66.249.76.160/27", - "66.249.76.192/27", - "66.249.76.224/27", - "66.249.76.32/27", - "66.249.76.64/27", - "66.249.76.96/27", - "66.249.77.0/27", - "66.249.77.128/27", - "66.249.77.160/27", - "66.249.77.192/27", - "66.249.77.224/27", - "66.249.77.32/27", - "66.249.77.64/27", - "66.249.77.96/27", - "66.249.78.0/27", - "66.249.78.32/27", - "66.249.79.0/27", - "66.249.79.128/27", - "66.249.79.160/27", - "66.249.79.192/27", - "66.249.79.224/27", - "66.249.79.32/27", - "66.249.79.64/27", - "66.249.79.96/27" - ] + remote_addresses: + [ + "2001:4860:4801:10::/64", + "2001:4860:4801:11::/64", + "2001:4860:4801:12::/64", + "2001:4860:4801:13::/64", + "2001:4860:4801:14::/64", + "2001:4860:4801:15::/64", + "2001:4860:4801:16::/64", + "2001:4860:4801:17::/64", + "2001:4860:4801:18::/64", + "2001:4860:4801:19::/64", + "2001:4860:4801:1a::/64", + "2001:4860:4801:1b::/64", + "2001:4860:4801:1c::/64", + "2001:4860:4801:1d::/64", + "2001:4860:4801:1e::/64", + "2001:4860:4801:1f::/64", + "2001:4860:4801:20::/64", + "2001:4860:4801:21::/64", + "2001:4860:4801:22::/64", + "2001:4860:4801:23::/64", + "2001:4860:4801:24::/64", + "2001:4860:4801:25::/64", + "2001:4860:4801:26::/64", + "2001:4860:4801:27::/64", + "2001:4860:4801:28::/64", + "2001:4860:4801:29::/64", + "2001:4860:4801:2::/64", + "2001:4860:4801:2a::/64", + "2001:4860:4801:2b::/64", + "2001:4860:4801:2c::/64", + "2001:4860:4801:2d::/64", + "2001:4860:4801:2e::/64", + "2001:4860:4801:2f::/64", + "2001:4860:4801:31::/64", + "2001:4860:4801:32::/64", + "2001:4860:4801:33::/64", + "2001:4860:4801:34::/64", + "2001:4860:4801:35::/64", + "2001:4860:4801:36::/64", + "2001:4860:4801:37::/64", + "2001:4860:4801:38::/64", + "2001:4860:4801:39::/64", + "2001:4860:4801:3a::/64", + "2001:4860:4801:3b::/64", + "2001:4860:4801:3c::/64", + "2001:4860:4801:3d::/64", + "2001:4860:4801:3e::/64", + "2001:4860:4801:40::/64", + "2001:4860:4801:41::/64", + "2001:4860:4801:42::/64", + "2001:4860:4801:43::/64", + "2001:4860:4801:44::/64", + "2001:4860:4801:45::/64", + "2001:4860:4801:46::/64", + "2001:4860:4801:47::/64", + "2001:4860:4801:48::/64", + "2001:4860:4801:49::/64", + "2001:4860:4801:4a::/64", + "2001:4860:4801:4b::/64", + "2001:4860:4801:4c::/64", + "2001:4860:4801:50::/64", + "2001:4860:4801:51::/64", + "2001:4860:4801:52::/64", + "2001:4860:4801:53::/64", + "2001:4860:4801:54::/64", + "2001:4860:4801:55::/64", + "2001:4860:4801:56::/64", + "2001:4860:4801:60::/64", + "2001:4860:4801:61::/64", + "2001:4860:4801:62::/64", + "2001:4860:4801:63::/64", + "2001:4860:4801:64::/64", + "2001:4860:4801:65::/64", + "2001:4860:4801:66::/64", + "2001:4860:4801:67::/64", + "2001:4860:4801:68::/64", + "2001:4860:4801:69::/64", + "2001:4860:4801:6a::/64", + "2001:4860:4801:6b::/64", + "2001:4860:4801:6c::/64", + "2001:4860:4801:6d::/64", + "2001:4860:4801:6e::/64", + "2001:4860:4801:6f::/64", + "2001:4860:4801:70::/64", + "2001:4860:4801:71::/64", + "2001:4860:4801:72::/64", + "2001:4860:4801:73::/64", + "2001:4860:4801:74::/64", + "2001:4860:4801:75::/64", + "2001:4860:4801:76::/64", + "2001:4860:4801:77::/64", + "2001:4860:4801:78::/64", + "2001:4860:4801:79::/64", + "2001:4860:4801:80::/64", + "2001:4860:4801:81::/64", + "2001:4860:4801:82::/64", + "2001:4860:4801:83::/64", + "2001:4860:4801:84::/64", + "2001:4860:4801:85::/64", + "2001:4860:4801:86::/64", + "2001:4860:4801:87::/64", + "2001:4860:4801:88::/64", + "2001:4860:4801:90::/64", + "2001:4860:4801:91::/64", + "2001:4860:4801:92::/64", + "2001:4860:4801:93::/64", + "2001:4860:4801:94::/64", + "2001:4860:4801:95::/64", + "2001:4860:4801:96::/64", + "2001:4860:4801:a0::/64", + "2001:4860:4801:a1::/64", + "2001:4860:4801:a2::/64", + "2001:4860:4801:a3::/64", + "2001:4860:4801:a4::/64", + "2001:4860:4801:a5::/64", + "2001:4860:4801:c::/64", + "2001:4860:4801:f::/64", + "192.178.5.0/27", + "192.178.6.0/27", + "192.178.6.128/27", + "192.178.6.160/27", + "192.178.6.192/27", + "192.178.6.32/27", + "192.178.6.64/27", + "192.178.6.96/27", + "34.100.182.96/28", + "34.101.50.144/28", + "34.118.254.0/28", + "34.118.66.0/28", + "34.126.178.96/28", + "34.146.150.144/28", + "34.147.110.144/28", + "34.151.74.144/28", + "34.152.50.64/28", + "34.154.114.144/28", + "34.155.98.32/28", + "34.165.18.176/28", + "34.175.160.64/28", + "34.176.130.16/28", + "34.22.85.0/27", + "34.64.82.64/28", + "34.65.242.112/28", + "34.80.50.80/28", + "34.88.194.0/28", + "34.89.10.80/28", + "34.89.198.80/28", + "34.96.162.48/28", + "35.247.243.240/28", + "66.249.64.0/27", + "66.249.64.128/27", + "66.249.64.160/27", + "66.249.64.224/27", + "66.249.64.32/27", + "66.249.64.64/27", + "66.249.64.96/27", + "66.249.65.0/27", + "66.249.65.128/27", + "66.249.65.160/27", + "66.249.65.192/27", + "66.249.65.224/27", + "66.249.65.32/27", + "66.249.65.64/27", + "66.249.65.96/27", + "66.249.66.0/27", + "66.249.66.128/27", + "66.249.66.160/27", + "66.249.66.192/27", + "66.249.66.224/27", + "66.249.66.32/27", + "66.249.66.64/27", + "66.249.66.96/27", + "66.249.68.0/27", + "66.249.68.128/27", + "66.249.68.32/27", + "66.249.68.64/27", + "66.249.68.96/27", + "66.249.69.0/27", + "66.249.69.128/27", + "66.249.69.160/27", + "66.249.69.192/27", + "66.249.69.224/27", + "66.249.69.32/27", + "66.249.69.64/27", + "66.249.69.96/27", + "66.249.70.0/27", + "66.249.70.128/27", + "66.249.70.160/27", + "66.249.70.192/27", + "66.249.70.224/27", + "66.249.70.32/27", + "66.249.70.64/27", + "66.249.70.96/27", + "66.249.71.0/27", + "66.249.71.128/27", + "66.249.71.160/27", + "66.249.71.192/27", + "66.249.71.224/27", + "66.249.71.32/27", + "66.249.71.64/27", + "66.249.71.96/27", + "66.249.72.0/27", + "66.249.72.128/27", + "66.249.72.160/27", + "66.249.72.192/27", + "66.249.72.224/27", + "66.249.72.32/27", + "66.249.72.64/27", + "66.249.72.96/27", + "66.249.73.0/27", + "66.249.73.128/27", + "66.249.73.160/27", + "66.249.73.192/27", + "66.249.73.224/27", + "66.249.73.32/27", + "66.249.73.64/27", + "66.249.73.96/27", + "66.249.74.0/27", + "66.249.74.128/27", + "66.249.74.160/27", + "66.249.74.192/27", + "66.249.74.32/27", + "66.249.74.64/27", + "66.249.74.96/27", + "66.249.75.0/27", + "66.249.75.128/27", + "66.249.75.160/27", + "66.249.75.192/27", + "66.249.75.224/27", + "66.249.75.32/27", + "66.249.75.64/27", + "66.249.75.96/27", + "66.249.76.0/27", + "66.249.76.128/27", + "66.249.76.160/27", + "66.249.76.192/27", + "66.249.76.224/27", + "66.249.76.32/27", + "66.249.76.64/27", + "66.249.76.96/27", + "66.249.77.0/27", + "66.249.77.128/27", + "66.249.77.160/27", + "66.249.77.192/27", + "66.249.77.224/27", + "66.249.77.32/27", + "66.249.77.64/27", + "66.249.77.96/27", + "66.249.78.0/27", + "66.249.78.32/27", + "66.249.79.0/27", + "66.249.79.128/27", + "66.249.79.160/27", + "66.249.79.192/27", + "66.249.79.224/27", + "66.249.79.32/27", + "66.249.79.64/27", + "66.249.79.96/27", + ] diff --git a/data/crawlers/internet-archive.yaml b/data/crawlers/internet-archive.yaml index 5e209e85..99548409 100644 --- a/data/crawlers/internet-archive.yaml +++ b/data/crawlers/internet-archive.yaml @@ -1,8 +1,4 @@ - name: internet-archive action: ALLOW # https://ipinfo.io/AS7941 - remote_addresses: [ - "207.241.224.0/20", - "208.70.24.0/21", - "2620:0:9c0::/48" - ] \ No newline at end of file + remote_addresses: ["207.241.224.0/20", "208.70.24.0/21", "2620:0:9c0::/48"] diff --git a/data/crawlers/kagibot.yaml b/data/crawlers/kagibot.yaml index db62b579..2bbd5fc3 100644 --- a/data/crawlers/kagibot.yaml +++ b/data/crawlers/kagibot.yaml @@ -2,9 +2,10 @@ user_agent_regex: \+https\://kagi\.com/bot action: ALLOW # https://kagi.com/bot - remote_addresses: [ - "216.18.205.234/32", - "35.212.27.76/32", - "104.254.65.50/32", - "209.151.156.194/32" - ] + remote_addresses: + [ + "216.18.205.234/32", + "35.212.27.76/32", + "104.254.65.50/32", + "209.151.156.194/32", + ] diff --git a/data/crawlers/marginalia.yaml b/data/crawlers/marginalia.yaml index e12ebc45..ab6724b1 100644 --- a/data/crawlers/marginalia.yaml +++ b/data/crawlers/marginalia.yaml @@ -2,10 +2,11 @@ user_agent_regex: search\.marginalia\.nu action: ALLOW # Received directly over email - remote_addresses: [ - "193.183.0.162/31", - "193.183.0.164/30", - "193.183.0.168/30", - "193.183.0.172/31", - "193.183.0.174/32" - ] \ No newline at end of file + remote_addresses: + [ + "193.183.0.162/31", + "193.183.0.164/30", + "193.183.0.168/30", + "193.183.0.172/31", + "193.183.0.174/32", + ] diff --git a/data/crawlers/mojeekbot.yaml b/data/crawlers/mojeekbot.yaml index 40661203..79fd17b0 100644 --- a/data/crawlers/mojeekbot.yaml +++ b/data/crawlers/mojeekbot.yaml @@ -2,4 +2,4 @@ user_agent_regex: \+https\://www\.mojeek\.com/bot\.html action: ALLOW # https://www.mojeek.com/bot.html - remote_addresses: [ "5.102.173.71/32" ] \ No newline at end of file + remote_addresses: ["5.102.173.71/32"] diff --git a/data/crawlers/openai-gptbot.yaml b/data/crawlers/openai-gptbot.yaml index 42658e77..c414d42b 100644 --- a/data/crawlers/openai-gptbot.yaml +++ b/data/crawlers/openai-gptbot.yaml @@ -4,13 +4,14 @@ user_agent_regex: GPTBot/1\.1; \+https\://openai\.com/gptbot action: ALLOW # https://openai.com/gptbot.json - remote_addresses: [ - "52.230.152.0/24", - "20.171.206.0/24", - "20.171.207.0/24", - "4.227.36.0/25", - "20.125.66.80/28", - "172.182.204.0/24", - "172.182.214.0/24", - "172.182.215.0/24", - ] \ No newline at end of file + remote_addresses: + [ + "52.230.152.0/24", + "20.171.206.0/24", + "20.171.207.0/24", + "4.227.36.0/25", + "20.125.66.80/28", + "172.182.204.0/24", + "172.182.214.0/24", + "172.182.215.0/24", + ] diff --git a/data/crawlers/openai-searchbot.yaml b/data/crawlers/openai-searchbot.yaml index 05796be9..2a7a306e 100644 --- a/data/crawlers/openai-searchbot.yaml +++ b/data/crawlers/openai-searchbot.yaml @@ -4,10 +4,11 @@ user_agent_regex: OAI-SearchBot/1\.0; \+https\://openai\.com/searchbot action: ALLOW # https://openai.com/searchbot.json - remote_addresses: [ - "20.42.10.176/28", - "172.203.190.128/28", - "104.210.140.128/28", - "51.8.102.0/24", - "135.234.64.0/24" - ] \ No newline at end of file + remote_addresses: + [ + "20.42.10.176/28", + "172.203.190.128/28", + "104.210.140.128/28", + "51.8.102.0/24", + "135.234.64.0/24", + ] diff --git a/data/crawlers/perplexitybot.yaml b/data/crawlers/perplexitybot.yaml index d217162a..3da45b1c 100644 --- a/data/crawlers/perplexitybot.yaml +++ b/data/crawlers/perplexitybot.yaml @@ -4,13 +4,14 @@ user_agent_regex: PerplexityBot/.+; \+https\://perplexity\.ai/perplexitybot action: ALLOW # https://www.perplexity.com/perplexitybot.json - remote_addresses: [ - "107.20.236.150/32", - "3.224.62.45/32", - "18.210.92.235/32", - "3.222.232.239/32", - "3.211.124.183/32", - "3.231.139.107/32", - "18.97.1.228/30", - "18.97.9.96/29", - ] + remote_addresses: + [ + "107.20.236.150/32", + "3.224.62.45/32", + "18.210.92.235/32", + "3.222.232.239/32", + "3.211.124.183/32", + "3.231.139.107/32", + "18.97.1.228/30", + "18.97.9.96/29", + ] diff --git a/data/crawlers/qwantbot.yaml b/data/crawlers/qwantbot.yaml index a4021549..d43d06b6 100644 --- a/data/crawlers/qwantbot.yaml +++ b/data/crawlers/qwantbot.yaml @@ -2,4 +2,4 @@ user_agent_regex: \+https\://help\.qwant\.com/bot/ action: ALLOW # https://help.qwant.com/wp-content/uploads/sites/2/2025/01/qwantbot.json - remote_addresses: [ "91.242.162.0/24" ] + remote_addresses: ["91.242.162.0/24"] diff --git a/data/crawlers/yandexbot.yaml b/data/crawlers/yandexbot.yaml index f7f84376..94f8ed8e 100644 --- a/data/crawlers/yandexbot.yaml +++ b/data/crawlers/yandexbot.yaml @@ -1,6 +1,6 @@ -- name: yandexbot - action: ALLOW - expression: - all: - - userAgent.matches("\\+http\\://yandex\\.com/bots") - - verifyFCrDNS(remoteAddress, "^.*\\.yandex\\.(ru|com|net)$") \ No newline at end of file +- name: yandexbot + action: ALLOW + expression: + all: + - userAgent.matches("\\+http\\://yandex\\.com/bots") + - verifyFCrDNS(remoteAddress, "^.*\\.yandex\\.(ru|com|net)$") diff --git a/data/meta/README.md b/data/meta/README.md index bf758c79..ad737ed3 100644 --- a/data/meta/README.md +++ b/data/meta/README.md @@ -2,4 +2,4 @@ Contains policies that exclusively reference policies in _multiple_ other data folders. -Akin to "stances" that the administrator can take, with reference to various topics, such as AI/LLM systems. \ No newline at end of file +Akin to "stances" that the administrator can take, with reference to various topics, such as AI/LLM systems. diff --git a/data/meta/ai-block-aggressive.yaml b/data/meta/ai-block-aggressive.yaml index f76e15ef..8c7db5e0 100644 --- a/data/meta/ai-block-aggressive.yaml +++ b/data/meta/ai-block-aggressive.yaml @@ -3,4 +3,4 @@ - import: (data)/bots/ai-catchall.yaml - import: (data)/clients/ai.yaml - import: (data)/crawlers/ai-search.yaml -- import: (data)/crawlers/ai-training.yaml \ No newline at end of file +- import: (data)/crawlers/ai-training.yaml diff --git a/data/meta/messengers-preview.yaml b/data/meta/messengers-preview.yaml index 08f3a3eb..3696832c 100644 --- a/data/meta/messengers-preview.yaml +++ b/data/meta/messengers-preview.yaml @@ -1,2 +1,2 @@ -- import: (data)/clients/telegram-preview.yaml -- import: (data)/clients/vk-preview.yaml \ No newline at end of file +- import: (data)/clients/telegram-preview.yaml +- import: (data)/clients/vk-preview.yaml diff --git a/data/services/uptime-robot.yaml b/data/services/uptime-robot.yaml index b0d9e089..d4b8c6b1 100644 --- a/data/services/uptime-robot.yaml +++ b/data/services/uptime-robot.yaml @@ -2,222 +2,223 @@ user_agent_regex: UptimeRobot action: ALLOW # https://api.uptimerobot.com/meta/ips - remote_addresses: [ - "3.12.251.153/32", - "3.20.63.178/32", - "3.77.67.4/32", - "3.79.134.69/32", - "3.105.133.239/32", - "3.105.190.221/32", - "3.133.226.214/32", - "3.149.57.90/32", - "3.212.128.62/32", - "5.161.61.238/32", - "5.161.73.160/32", - "5.161.75.7/32", - "5.161.113.195/32", - "5.161.117.52/32", - "5.161.177.47/32", - "5.161.194.92/32", - "5.161.215.244/32", - "5.223.43.32/32", - "5.223.53.147/32", - "5.223.57.22/32", - "18.116.205.62/32", - "18.180.208.214/32", - "18.192.166.72/32", - "18.193.252.127/32", - "24.144.78.39/32", - "24.144.78.185/32", - "34.198.201.66/32", - "45.55.123.175/32", - "45.55.127.146/32", - "49.13.24.81/32", - "49.13.130.29/32", - "49.13.134.145/32", - "49.13.164.148/32", - "49.13.167.123/32", - "52.15.147.27/32", - "52.22.236.30/32", - "52.28.162.93/32", - "52.59.43.236/32", - "52.87.72.16/32", - "54.64.67.106/32", - "54.79.28.129/32", - "54.87.112.51/32", - "54.167.223.174/32", - "54.249.170.27/32", - "63.178.84.147/32", - "64.225.81.248/32", - "64.225.82.147/32", - "69.162.124.227/32", - "69.162.124.235/32", - "69.162.124.238/32", - "78.46.190.63/32", - "78.46.215.1/32", - "78.47.98.55/32", - "78.47.173.76/32", - "88.99.80.227/32", - "91.99.101.207/32", - "128.140.41.193/32", - "128.140.106.114/32", - "129.212.132.140/32", - "134.199.240.137/32", - "138.197.53.117/32", - "138.197.53.138/32", - "138.197.54.143/32", - "138.197.54.247/32", - "138.197.63.92/32", - "139.59.50.44/32", - "142.132.180.39/32", - "143.198.249.237/32", - "143.198.250.89/32", - "143.244.196.21/32", - "143.244.196.211/32", - "143.244.221.177/32", - "144.126.251.21/32", - "146.190.9.187/32", - "152.42.149.135/32", - "157.90.155.240/32", - "157.90.156.63/32", - "159.69.158.189/32", - "159.223.243.219/32", - "161.35.247.201/32", - "167.99.18.52/32", - "167.235.143.113/32", - "168.119.53.160/32", - "168.119.96.239/32", - "168.119.123.75/32", - "170.64.250.64/32", - "170.64.250.132/32", - "170.64.250.235/32", - "178.156.181.172/32", - "178.156.184.20/32", - "178.156.185.127/32", - "178.156.185.231/32", - "178.156.187.238/32", - "178.156.189.113/32", - "178.156.189.249/32", - "188.166.201.79/32", - "206.189.241.133/32", - "209.38.49.1/32", - "209.38.49.206/32", - "209.38.49.226/32", - "209.38.51.43/32", - "209.38.53.7/32", - "209.38.124.252/32", - "216.144.248.18/31", - "216.144.248.21/32", - "216.144.248.22/31", - "216.144.248.24/30", - "216.144.248.28/31", - "216.144.248.30/32", - "216.245.221.83/32", - "2400:6180:10:200::56a0:b000/128", - "2400:6180:10:200::56a0:c000/128", - "2400:6180:10:200::56a0:e000/128", - "2400:6180:100:d0::94b6:4001/128", - "2400:6180:100:d0::94b6:5001/128", - "2400:6180:100:d0::94b6:7001/128", - "2406:da14:94d:8601:9d0d:7754:bedf:e4f5/128", - "2406:da14:94d:8601:b325:ff58:2bba:7934/128", - "2406:da14:94d:8601:db4b:c5ac:2cbe:9a79/128", - "2406:da1c:9c8:dc02:7ae1:f2ea:ab91:2fde/128", - "2406:da1c:9c8:dc02:7db9:f38b:7b9f:402e/128", - "2406:da1c:9c8:dc02:82b2:f0fd:ee96:579/128", - "2600:1f16:775:3a00:ac3:c5eb:7081:942e/128", - "2600:1f16:775:3a00:37bf:6026:e54a:f03a/128", - "2600:1f16:775:3a00:3f24:5bb0:95d7:5a6b/128", - "2600:1f16:775:3a00:8c2c:2ba6:778f:5be5/128", - "2600:1f16:775:3a00:91ac:3120:ff38:92b5/128", - "2600:1f16:775:3a00:dbbe:36b0:3c45:da32/128", - "2600:1f18:179:f900:71:af9a:ade7:d772/128", - "2600:1f18:179:f900:2406:9399:4ae6:c5d3/128", - "2600:1f18:179:f900:4696:7729:7bb3:f52f/128", - "2600:1f18:179:f900:4b7d:d1cc:2d10:211/128", - "2600:1f18:179:f900:5c68:91b6:5d75:5d7/128", - "2600:1f18:179:f900:e8dd:eed1:a6c:183b/128", - "2604:a880:800:14:0:1:68ba:d000/128", - "2604:a880:800:14:0:1:68ba:e000/128", - "2604:a880:800:14:0:1:68bb:0/128", - "2604:a880:800:14:0:1:68bb:1000/128", - "2604:a880:800:14:0:1:68bb:3000/128", - "2604:a880:800:14:0:1:68bb:4000/128", - "2604:a880:800:14:0:1:68bb:5000/128", - "2604:a880:800:14:0:1:68bb:6000/128", - "2604:a880:800:14:0:1:68bb:7000/128", - "2604:a880:800:14:0:1:68bb:a000/128", - "2604:a880:800:14:0:1:68bb:b000/128", - "2604:a880:800:14:0:1:68bb:c000/128", - "2604:a880:800:14:0:1:68bb:d000/128", - "2604:a880:800:14:0:1:68bb:e000/128", - "2604:a880:800:14:0:1:68bb:f000/128", - "2607:ff68:107::4/128", - "2607:ff68:107::14/128", - "2607:ff68:107::33/128", - "2607:ff68:107::48/127", - "2607:ff68:107::50/125", - "2607:ff68:107::58/127", - "2607:ff68:107::60/128", - "2a01:4f8:c0c:83fa::1/128", - "2a01:4f8:c17:42e4::1/128", - "2a01:4f8:c2c:9fc6::1/128", - "2a01:4f8:c2c:beae::1/128", - "2a01:4f8:1c1a:3d53::1/128", - "2a01:4f8:1c1b:4ef4::1/128", - "2a01:4f8:1c1b:5b5a::1/128", - "2a01:4f8:1c1b:7ecc::1/128", - "2a01:4f8:1c1c:11aa::1/128", - "2a01:4f8:1c1c:5353::1/128", - "2a01:4f8:1c1c:7240::1/128", - "2a01:4f8:1c1c:a98a::1/128", - "2a01:4f8:c012:c60e::1/128", - "2a01:4f8:c013:c18::1/128", - "2a01:4f8:c013:34c0::1/128", - "2a01:4f8:c013:3b0f::1/128", - "2a01:4f8:c013:3c52::1/128", - "2a01:4f8:c013:3c53::1/128", - "2a01:4f8:c013:3c54::1/128", - "2a01:4f8:c013:3c55::1/128", - "2a01:4f8:c013:3c56::1/128", - "2a01:4ff:f0:bfd::1/128", - "2a01:4ff:f0:2219::1/128", - "2a01:4ff:f0:3e03::1/128", - "2a01:4ff:f0:5f80::1/128", - "2a01:4ff:f0:7fad::1/128", - "2a01:4ff:f0:9c5f::1/128", - "2a01:4ff:f0:b2f2::1/128", - "2a01:4ff:f0:b6f1::1/128", - "2a01:4ff:f0:d283::1/128", - "2a01:4ff:f0:d3cd::1/128", - "2a01:4ff:f0:e516::1/128", - "2a01:4ff:f0:e9cf::1/128", - "2a01:4ff:f0:eccb::1/128", - "2a01:4ff:f0:efd1::1/128", - "2a01:4ff:f0:fdc7::1/128", - "2a01:4ff:2f0:193c::1/128", - "2a01:4ff:2f0:27de::1/128", - "2a01:4ff:2f0:3b3a::1/128", - "2a03:b0c0:2:f0::bd91:f001/128", - "2a03:b0c0:2:f0::bd92:1/128", - "2a03:b0c0:2:f0::bd92:1001/128", - "2a03:b0c0:2:f0::bd92:2001/128", - "2a03:b0c0:2:f0::bd92:4001/128", - "2a03:b0c0:2:f0::bd92:5001/128", - "2a03:b0c0:2:f0::bd92:6001/128", - "2a03:b0c0:2:f0::bd92:7001/128", - "2a03:b0c0:2:f0::bd92:8001/128", - "2a03:b0c0:2:f0::bd92:9001/128", - "2a03:b0c0:2:f0::bd92:a001/128", - "2a03:b0c0:2:f0::bd92:b001/128", - "2a03:b0c0:2:f0::bd92:c001/128", - "2a03:b0c0:2:f0::bd92:e001/128", - "2a03:b0c0:2:f0::bd92:f001/128", - "2a05:d014:1815:3400:6d:9235:c1c0:96ad/128", - "2a05:d014:1815:3400:654f:bd37:724c:212b/128", - "2a05:d014:1815:3400:90b4:4ef9:5631:b170/128", - "2a05:d014:1815:3400:9779:d8e9:100a:9642/128", - "2a05:d014:1815:3400:af29:e95e:64ff:df81/128", - "2a05:d014:1815:3400:c7d6:f7f3:6cc1:30d1/128", - "2a05:d014:1815:3400:d784:e5dd:8e0:67cb/128", - ] + remote_addresses: + [ + "3.12.251.153/32", + "3.20.63.178/32", + "3.77.67.4/32", + "3.79.134.69/32", + "3.105.133.239/32", + "3.105.190.221/32", + "3.133.226.214/32", + "3.149.57.90/32", + "3.212.128.62/32", + "5.161.61.238/32", + "5.161.73.160/32", + "5.161.75.7/32", + "5.161.113.195/32", + "5.161.117.52/32", + "5.161.177.47/32", + "5.161.194.92/32", + "5.161.215.244/32", + "5.223.43.32/32", + "5.223.53.147/32", + "5.223.57.22/32", + "18.116.205.62/32", + "18.180.208.214/32", + "18.192.166.72/32", + "18.193.252.127/32", + "24.144.78.39/32", + "24.144.78.185/32", + "34.198.201.66/32", + "45.55.123.175/32", + "45.55.127.146/32", + "49.13.24.81/32", + "49.13.130.29/32", + "49.13.134.145/32", + "49.13.164.148/32", + "49.13.167.123/32", + "52.15.147.27/32", + "52.22.236.30/32", + "52.28.162.93/32", + "52.59.43.236/32", + "52.87.72.16/32", + "54.64.67.106/32", + "54.79.28.129/32", + "54.87.112.51/32", + "54.167.223.174/32", + "54.249.170.27/32", + "63.178.84.147/32", + "64.225.81.248/32", + "64.225.82.147/32", + "69.162.124.227/32", + "69.162.124.235/32", + "69.162.124.238/32", + "78.46.190.63/32", + "78.46.215.1/32", + "78.47.98.55/32", + "78.47.173.76/32", + "88.99.80.227/32", + "91.99.101.207/32", + "128.140.41.193/32", + "128.140.106.114/32", + "129.212.132.140/32", + "134.199.240.137/32", + "138.197.53.117/32", + "138.197.53.138/32", + "138.197.54.143/32", + "138.197.54.247/32", + "138.197.63.92/32", + "139.59.50.44/32", + "142.132.180.39/32", + "143.198.249.237/32", + "143.198.250.89/32", + "143.244.196.21/32", + "143.244.196.211/32", + "143.244.221.177/32", + "144.126.251.21/32", + "146.190.9.187/32", + "152.42.149.135/32", + "157.90.155.240/32", + "157.90.156.63/32", + "159.69.158.189/32", + "159.223.243.219/32", + "161.35.247.201/32", + "167.99.18.52/32", + "167.235.143.113/32", + "168.119.53.160/32", + "168.119.96.239/32", + "168.119.123.75/32", + "170.64.250.64/32", + "170.64.250.132/32", + "170.64.250.235/32", + "178.156.181.172/32", + "178.156.184.20/32", + "178.156.185.127/32", + "178.156.185.231/32", + "178.156.187.238/32", + "178.156.189.113/32", + "178.156.189.249/32", + "188.166.201.79/32", + "206.189.241.133/32", + "209.38.49.1/32", + "209.38.49.206/32", + "209.38.49.226/32", + "209.38.51.43/32", + "209.38.53.7/32", + "209.38.124.252/32", + "216.144.248.18/31", + "216.144.248.21/32", + "216.144.248.22/31", + "216.144.248.24/30", + "216.144.248.28/31", + "216.144.248.30/32", + "216.245.221.83/32", + "2400:6180:10:200::56a0:b000/128", + "2400:6180:10:200::56a0:c000/128", + "2400:6180:10:200::56a0:e000/128", + "2400:6180:100:d0::94b6:4001/128", + "2400:6180:100:d0::94b6:5001/128", + "2400:6180:100:d0::94b6:7001/128", + "2406:da14:94d:8601:9d0d:7754:bedf:e4f5/128", + "2406:da14:94d:8601:b325:ff58:2bba:7934/128", + "2406:da14:94d:8601:db4b:c5ac:2cbe:9a79/128", + "2406:da1c:9c8:dc02:7ae1:f2ea:ab91:2fde/128", + "2406:da1c:9c8:dc02:7db9:f38b:7b9f:402e/128", + "2406:da1c:9c8:dc02:82b2:f0fd:ee96:579/128", + "2600:1f16:775:3a00:ac3:c5eb:7081:942e/128", + "2600:1f16:775:3a00:37bf:6026:e54a:f03a/128", + "2600:1f16:775:3a00:3f24:5bb0:95d7:5a6b/128", + "2600:1f16:775:3a00:8c2c:2ba6:778f:5be5/128", + "2600:1f16:775:3a00:91ac:3120:ff38:92b5/128", + "2600:1f16:775:3a00:dbbe:36b0:3c45:da32/128", + "2600:1f18:179:f900:71:af9a:ade7:d772/128", + "2600:1f18:179:f900:2406:9399:4ae6:c5d3/128", + "2600:1f18:179:f900:4696:7729:7bb3:f52f/128", + "2600:1f18:179:f900:4b7d:d1cc:2d10:211/128", + "2600:1f18:179:f900:5c68:91b6:5d75:5d7/128", + "2600:1f18:179:f900:e8dd:eed1:a6c:183b/128", + "2604:a880:800:14:0:1:68ba:d000/128", + "2604:a880:800:14:0:1:68ba:e000/128", + "2604:a880:800:14:0:1:68bb:0/128", + "2604:a880:800:14:0:1:68bb:1000/128", + "2604:a880:800:14:0:1:68bb:3000/128", + "2604:a880:800:14:0:1:68bb:4000/128", + "2604:a880:800:14:0:1:68bb:5000/128", + "2604:a880:800:14:0:1:68bb:6000/128", + "2604:a880:800:14:0:1:68bb:7000/128", + "2604:a880:800:14:0:1:68bb:a000/128", + "2604:a880:800:14:0:1:68bb:b000/128", + "2604:a880:800:14:0:1:68bb:c000/128", + "2604:a880:800:14:0:1:68bb:d000/128", + "2604:a880:800:14:0:1:68bb:e000/128", + "2604:a880:800:14:0:1:68bb:f000/128", + "2607:ff68:107::4/128", + "2607:ff68:107::14/128", + "2607:ff68:107::33/128", + "2607:ff68:107::48/127", + "2607:ff68:107::50/125", + "2607:ff68:107::58/127", + "2607:ff68:107::60/128", + "2a01:4f8:c0c:83fa::1/128", + "2a01:4f8:c17:42e4::1/128", + "2a01:4f8:c2c:9fc6::1/128", + "2a01:4f8:c2c:beae::1/128", + "2a01:4f8:1c1a:3d53::1/128", + "2a01:4f8:1c1b:4ef4::1/128", + "2a01:4f8:1c1b:5b5a::1/128", + "2a01:4f8:1c1b:7ecc::1/128", + "2a01:4f8:1c1c:11aa::1/128", + "2a01:4f8:1c1c:5353::1/128", + "2a01:4f8:1c1c:7240::1/128", + "2a01:4f8:1c1c:a98a::1/128", + "2a01:4f8:c012:c60e::1/128", + "2a01:4f8:c013:c18::1/128", + "2a01:4f8:c013:34c0::1/128", + "2a01:4f8:c013:3b0f::1/128", + "2a01:4f8:c013:3c52::1/128", + "2a01:4f8:c013:3c53::1/128", + "2a01:4f8:c013:3c54::1/128", + "2a01:4f8:c013:3c55::1/128", + "2a01:4f8:c013:3c56::1/128", + "2a01:4ff:f0:bfd::1/128", + "2a01:4ff:f0:2219::1/128", + "2a01:4ff:f0:3e03::1/128", + "2a01:4ff:f0:5f80::1/128", + "2a01:4ff:f0:7fad::1/128", + "2a01:4ff:f0:9c5f::1/128", + "2a01:4ff:f0:b2f2::1/128", + "2a01:4ff:f0:b6f1::1/128", + "2a01:4ff:f0:d283::1/128", + "2a01:4ff:f0:d3cd::1/128", + "2a01:4ff:f0:e516::1/128", + "2a01:4ff:f0:e9cf::1/128", + "2a01:4ff:f0:eccb::1/128", + "2a01:4ff:f0:efd1::1/128", + "2a01:4ff:f0:fdc7::1/128", + "2a01:4ff:2f0:193c::1/128", + "2a01:4ff:2f0:27de::1/128", + "2a01:4ff:2f0:3b3a::1/128", + "2a03:b0c0:2:f0::bd91:f001/128", + "2a03:b0c0:2:f0::bd92:1/128", + "2a03:b0c0:2:f0::bd92:1001/128", + "2a03:b0c0:2:f0::bd92:2001/128", + "2a03:b0c0:2:f0::bd92:4001/128", + "2a03:b0c0:2:f0::bd92:5001/128", + "2a03:b0c0:2:f0::bd92:6001/128", + "2a03:b0c0:2:f0::bd92:7001/128", + "2a03:b0c0:2:f0::bd92:8001/128", + "2a03:b0c0:2:f0::bd92:9001/128", + "2a03:b0c0:2:f0::bd92:a001/128", + "2a03:b0c0:2:f0::bd92:b001/128", + "2a03:b0c0:2:f0::bd92:c001/128", + "2a03:b0c0:2:f0::bd92:e001/128", + "2a03:b0c0:2:f0::bd92:f001/128", + "2a05:d014:1815:3400:6d:9235:c1c0:96ad/128", + "2a05:d014:1815:3400:654f:bd37:724c:212b/128", + "2a05:d014:1815:3400:90b4:4ef9:5631:b170/128", + "2a05:d014:1815:3400:9779:d8e9:100a:9642/128", + "2a05:d014:1815:3400:af29:e95e:64ff:df81/128", + "2a05:d014:1815:3400:c7d6:f7f3:6cc1:30d1/128", + "2a05:d014:1815:3400:d784:e5dd:8e0:67cb/128", + ] diff --git a/docs/blog/2025-08-28-cpu-core-odd/ProofOfWorkDiagram/index.jsx b/docs/blog/2025-08-28-cpu-core-odd/ProofOfWorkDiagram/index.jsx index b4ac4776..020fff04 100644 --- a/docs/blog/2025-08-28-cpu-core-odd/ProofOfWorkDiagram/index.jsx +++ b/docs/blog/2025-08-28-cpu-core-odd/ProofOfWorkDiagram/index.jsx @@ -1,14 +1,16 @@ -import React, { useState, useEffect, useMemo } from 'react'; -import styles from './styles.module.css'; +import React, { useState, useEffect, useMemo } from "react"; +import styles from "./styles.module.css"; // A helper function to perform SHA-256 hashing. // It takes a string, encodes it, hashes it, and returns a hex string. async function sha256(message) { try { const msgBuffer = new TextEncoder().encode(message); - const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer); + const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer); const hashArray = Array.from(new Uint8Array(hashBuffer)); - const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); + const hashHex = hashArray + .map((b) => b.toString(16).padStart(2, "0")) + .join(""); return hashHex; } catch (error) { console.error("Hashing failed:", error); @@ -21,21 +23,42 @@ const generateRandomHex = (bytes = 16) => { const buffer = new Uint8Array(bytes); crypto.getRandomValues(buffer); return Array.from(buffer) - .map(byte => byte.toString(16).padStart(2, '0')) - .join(''); + .map((byte) => byte.toString(16).padStart(2, "0")) + .join(""); }; - // Icon components for better visual feedback const CheckIcon = () => ( - - + + ); const XCircleIcon = () => ( - - + + ); @@ -46,7 +69,7 @@ export default function App() { // State for the nonce, which is the variable we can change const [nonce, setNonce] = useState(0); // State to store the resulting hash - const [hash, setHash] = useState(''); + const [hash, setHash] = useState(""); // A flag to indicate if the current hash is the "winning" one const [isMining, setIsMining] = useState(false); const [isFound, setIsFound] = useState(false); @@ -55,7 +78,10 @@ export default function App() { const difficulty = "00"; // Memoize the combined data to avoid recalculating on every render - const combinedData = useMemo(() => `${challenge}${nonce}`, [challenge, nonce]); + const combinedData = useMemo( + () => `${challenge}${nonce}`, + [challenge, nonce], + ); // This effect hook recalculates the hash whenever the combinedData changes. useEffect(() => { @@ -68,7 +94,9 @@ export default function App() { } }; calculateHash(); - return () => { isMounted = false; }; + return () => { + isMounted = false; + }; }, [combinedData, difficulty]); // This effect handles the automatic mining process @@ -93,7 +121,7 @@ export default function App() { // Update the UI periodically to avoid freezing the browser if (miningNonce % 100 === 0) { setNonce(miningNonce); - await new Promise(resolve => setTimeout(resolve, 0)); // Yield to the browser + await new Promise((resolve) => setTimeout(resolve, 0)); // Yield to the browser } } }; @@ -102,28 +130,27 @@ export default function App() { return () => { continueMining = false; - } + }; }, [isMining, challenge, nonce, difficulty]); - const handleMineClick = () => { setIsMining(true); - } + }; const handleStopClick = () => { setIsMining(false); - } + }; const handleResetClick = () => { setIsMining(false); setNonce(0); - } + }; const handleNewChallengeClick = () => { setIsMining(false); setChallenge(generateRandomHex(16)); setNonce(0); - } + }; // Helper to render the hash with colored leading characters const renderHash = () => { @@ -153,12 +180,46 @@ export default function App() {

2. Nonce

- {nonce} -
@@ -172,13 +233,26 @@ export default function App() { {/* Arrow pointing down */}
- - + +
{/* Hash Output Block */} -
+

4. Resulting Hash (SHA-256)

@@ -193,18 +267,30 @@ export default function App() { {/* Mining Controls */}
{!isMining ? ( - ) : ( - )} - -
diff --git a/docs/blog/2025-08-28-cpu-core-odd/ProofOfWorkDiagram/styles.module.css b/docs/blog/2025-08-28-cpu-core-odd/ProofOfWorkDiagram/styles.module.css index 419b4048..157f8402 100644 --- a/docs/blog/2025-08-28-cpu-core-odd/ProofOfWorkDiagram/styles.module.css +++ b/docs/blog/2025-08-28-cpu-core-odd/ProofOfWorkDiagram/styles.module.css @@ -48,7 +48,9 @@ background-color: rgb(31 41 55); padding: 1.5rem; border-radius: 0.5rem; - box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + box-shadow: + 0 10px 15px -3px rgb(0 0 0 / 0.1), + 0 4px 6px -4px rgb(0 0 0 / 0.1); height: 100%; display: flex; flex-direction: column; @@ -158,7 +160,9 @@ .hashContainer { padding: 1.5rem; border-radius: 0.5rem; - box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + box-shadow: + 0 10px 15px -3px rgb(0 0 0 / 0.1), + 0 4px 6px -4px rgb(0 0 0 / 0.1); transition: all 300ms; border: 2px solid; } diff --git a/docs/docs/admin/_category_.json b/docs/docs/admin/_category_.json index 4b7ba50a..a5586551 100644 --- a/docs/docs/admin/_category_.json +++ b/docs/docs/admin/_category_.json @@ -5,4 +5,4 @@ "type": "generated-index", "description": "Tradeoffs and considerations you may want to keep in mind when using Anubis." } -} \ No newline at end of file +} diff --git a/docs/docs/admin/configuration/_category_.json b/docs/docs/admin/configuration/_category_.json index e22c7a2f..6b797b2b 100644 --- a/docs/docs/admin/configuration/_category_.json +++ b/docs/docs/admin/configuration/_category_.json @@ -5,4 +5,4 @@ "type": "generated-index", "description": "Detailed information about configuring parts of Anubis." } -} \ No newline at end of file +} diff --git a/docs/docs/admin/configuration/challenges/_category_.json b/docs/docs/admin/configuration/challenges/_category_.json index 96a70d2f..a01e84f1 100644 --- a/docs/docs/admin/configuration/challenges/_category_.json +++ b/docs/docs/admin/configuration/challenges/_category_.json @@ -2,4 +2,4 @@ "label": "Challenges", "position": 10, "link": null -} \ No newline at end of file +} diff --git a/docs/docs/admin/configuration/expressions.mdx b/docs/docs/admin/configuration/expressions.mdx index 762b848b..109b9c0a 100644 --- a/docs/docs/admin/configuration/expressions.mdx +++ b/docs/docs/admin/configuration/expressions.mdx @@ -243,16 +243,16 @@ function regexSafe(input: string): string; `regexSafe` takes a string and escapes it for safe use inside of a regular expression. This is useful when you are creating regular expressions from headers or variables such as `remoteAddress`. -| Input | Output | -| :------------------------ | :------------------------------ | -| `regexSafe("1.2.3.4")` | `1\\.2\\.3\\.4` | -| `regexSafe("techaro.lol")` | `techaro\\.lol` | -| `regexSafe("star*")` | `star\\*` | -| `regexSafe("plus+")` | `plus\\+` | -| `regexSafe("{braces}")` | `\\{braces\\}` | -| `regexSafe("start^")` | `start\\^` | -| `regexSafe("back\\slash")` | `back\\\\slash` | -| `regexSafe("dash-dash")` | `dash\\-dash` | +| Input | Output | +| :------------------------- | :-------------- | +| `regexSafe("1.2.3.4")` | `1\\.2\\.3\\.4` | +| `regexSafe("techaro.lol")` | `techaro\\.lol` | +| `regexSafe("star*")` | `star\\*` | +| `regexSafe("plus+")` | `plus\\+` | +| `regexSafe("{braces}")` | `\\{braces\\}` | +| `regexSafe("start^")` | `start\\^` | +| `regexSafe("back\\slash")` | `back\\\\slash` | +| `regexSafe("dash-dash")` | `dash\\-dash` | ### `segments` @@ -301,9 +301,9 @@ function arpaReverseIP(ip: string): string; `arpaReverseIP` takes an IP address and returns its value in [ARPA notation](https://www.ietf.org/rfc/rfc2317.html). This can be useful when matching PTR record patterns. -| Input | Output | -| :----------------------------- | :------------------------------------------------------------------- | -| `arpaReverseIP("1.2.3.4")` | `4.3.2.1` | +| Input | Output | +| :----------------------------- | :---------------------------------------------------------------- | +| `arpaReverseIP("1.2.3.4")` | `4.3.2.1` | | `arpaReverseIP("2001:db8::1")` | `1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2` | #### `lookupHost` diff --git a/docs/docs/admin/default-allow-behavior.mdx b/docs/docs/admin/default-allow-behavior.mdx index 6249e735..1b87183e 100644 --- a/docs/docs/admin/default-allow-behavior.mdx +++ b/docs/docs/admin/default-allow-behavior.mdx @@ -89,4 +89,4 @@ If you want to deny all traffic except what you explicitly allow, add a catch-al - The implicit allow rule is always last and cannot be removed. - Use your logs to monitor what traffic is being allowed by default. -See [Policy Definitions](./policies) for more details on writing rules. \ No newline at end of file +See [Policy Definitions](./policies) for more details on writing rules. diff --git a/docs/docs/admin/environments/_category_.json b/docs/docs/admin/environments/_category_.json index 31522719..a9150a73 100644 --- a/docs/docs/admin/environments/_category_.json +++ b/docs/docs/admin/environments/_category_.json @@ -5,4 +5,4 @@ "type": "generated-index", "description": "Detailed information about individual environments (such as HTTP servers, platforms, etc.) Anubis is known to work with." } -} \ No newline at end of file +} diff --git a/docs/docs/admin/environments/kubernetes.mdx b/docs/docs/admin/environments/kubernetes.mdx index e10f18e2..eac57292 100644 --- a/docs/docs/admin/environments/kubernetes.mdx +++ b/docs/docs/admin/environments/kubernetes.mdx @@ -94,10 +94,8 @@ containers: - ALL seccompProfile: type: RuntimeDefault - ``` - Then add a Service entry for Anubis: ```yaml diff --git a/docs/docs/admin/environments/nginx/conf-anubis.inc b/docs/docs/admin/environments/nginx/conf-anubis.inc index 6e5083ae..bc20e8f4 100644 --- a/docs/docs/admin/environments/nginx/conf-anubis.inc +++ b/docs/docs/admin/environments/nginx/conf-anubis.inc @@ -1,8 +1,2 @@ -# /etc/nginx/conf-anubis.inc - -# Forward to anubis -location / { - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_pass http://anubis; -} \ No newline at end of file +# /etc/nginx/conf-anubis.inc # Forward to anubis location / { proxy_set_header +Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://anubis; } diff --git a/docs/docs/admin/environments/traefik.mdx b/docs/docs/admin/environments/traefik.mdx index 197ddc19..04df792d 100644 --- a/docs/docs/admin/environments/traefik.mdx +++ b/docs/docs/admin/environments/traefik.mdx @@ -75,7 +75,7 @@ services: # Telling Anubis, where to listen for Traefik - BIND=:8080 # Telling Anubis to do redirect — ensure there is a space after '=' - - 'TARGET= ' + - "TARGET= " # Specifies which domains Anubis is allowed to redirect to. - REDIRECT_DOMAINS=example.com # Should be the full external URL for Anubis (including scheme) diff --git a/docs/docs/admin/frameworks/_category_.json b/docs/docs/admin/frameworks/_category_.json index 28eefe88..253bf449 100644 --- a/docs/docs/admin/frameworks/_category_.json +++ b/docs/docs/admin/frameworks/_category_.json @@ -5,4 +5,4 @@ "type": "generated-index", "description": "Information about getting specific frameworks or tools working with Anubis." } -} \ No newline at end of file +} diff --git a/docs/docs/admin/honeypot/_category_.json b/docs/docs/admin/honeypot/_category_.json index bc0581e9..90c63375 100644 --- a/docs/docs/admin/honeypot/_category_.json +++ b/docs/docs/admin/honeypot/_category_.json @@ -5,4 +5,4 @@ "type": "generated-index", "description": "Honeypot features in Anubis, allowing Anubis to passively detect malicious crawlers." } -} \ No newline at end of file +} diff --git a/docs/docs/admin/installation.mdx b/docs/docs/admin/installation.mdx index 7642526e..6ecaa5a1 100644 --- a/docs/docs/admin/installation.mdx +++ b/docs/docs/admin/installation.mdx @@ -67,7 +67,7 @@ Currently the following settings are configurable via the policy file: Anubis uses these environment variables for configuration: | Environment Variable | Default value | Explanation | -|:-------------------------------|:------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| :----------------------------- | :---------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `ASSET_LOOKUP_HEADER` | unset | If set, use the contents of this header in requests when looking up custom assets in `OVERLAY_FOLDER`. See [Header-based overlay dispatch](./botstopper.mdx#header-based-overlay-dispatch) for more details. | | `BASE_PREFIX` | unset | If set, adds a global prefix to all Anubis endpoints (everything starting with `/.within.website/x/anubis/`). For example, setting this to `/myapp` would make Anubis accessible at `/myapp/` instead of `/`. This is useful when running Anubis behind a reverse proxy that routes based on path prefixes. | | `BIND` | `:8923` | The network address that Anubis listens on. For `unix`, set this to a path: `/run/anubis/instance.sock` | @@ -123,7 +123,7 @@ If you don't know or understand what these settings mean, ignore them. These are | `TARGET_DISABLE_KEEPALIVE` | `false` | If `true`, disables HTTP keep-alive for connections to the target backend. Useful for backends that don't handle keep-alive properly. | | `TARGET_HOST` | unset | If set, overrides the Host header in requests forwarded to `TARGET`. | | `TARGET_INSECURE_SKIP_VERIFY` | `false` | If `true`, skip TLS certificate validation for targets that listen over `https`. If your backend does not listen over `https`, ignore this setting. | -| `TARGET_SNI` | unset | If set, TLS handshake hostname when forwarding requests to the `TARGET`. If set to auto, use Host header. | +| `TARGET_SNI` | unset | If set, TLS handshake hostname when forwarding requests to the `TARGET`. If set to auto, use Host header. | diff --git a/docs/docs/admin/roles/_category_.json b/docs/docs/admin/roles/_category_.json index 2d5af0b3..d087404d 100644 --- a/docs/docs/admin/roles/_category_.json +++ b/docs/docs/admin/roles/_category_.json @@ -5,4 +5,4 @@ "type": "generated-index", "description": "Various server roles you will need to keep in mind with Anubis." } -} \ No newline at end of file +} diff --git a/docs/docs/design/_category_.json b/docs/docs/design/_category_.json index 65764e85..87b1010e 100644 --- a/docs/docs/design/_category_.json +++ b/docs/docs/design/_category_.json @@ -5,4 +5,4 @@ "type": "generated-index", "description": "How Anubis is designed and the tradeoffs it makes." } -} \ No newline at end of file +} diff --git a/docs/docs/developer/_category_.json b/docs/docs/developer/_category_.json index cf3805e0..0b24e3b0 100644 --- a/docs/docs/developer/_category_.json +++ b/docs/docs/developer/_category_.json @@ -5,4 +5,4 @@ "type": "generated-index", "description": "Guides and suggestions to make Anubis development go smoothly for everyone." } -} \ No newline at end of file +} diff --git a/docs/docs/user/_category_.json b/docs/docs/user/_category_.json index ce1dbafe..2e646499 100644 --- a/docs/docs/user/_category_.json +++ b/docs/docs/user/_category_.json @@ -5,4 +5,4 @@ "type": "generated-index", "description": "Information for users on sites that use Anubis." } -} \ No newline at end of file +} diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index df12939b..e686522f 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -1,62 +1,62 @@ -import { themes as prismThemes } from 'prism-react-renderer'; -import type { Config } from '@docusaurus/types'; -import type * as Preset from '@docusaurus/preset-classic'; +import { themes as prismThemes } from "prism-react-renderer"; +import type { Config } from "@docusaurus/types"; +import type * as Preset from "@docusaurus/preset-classic"; // This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) const config: Config = { - title: 'Anubis', - tagline: 'Weigh the soul of incoming HTTP requests to protect your website!', - favicon: 'img/favicon.ico', + title: "Anubis", + tagline: "Weigh the soul of incoming HTTP requests to protect your website!", + favicon: "img/favicon.ico", // Set the production url of your site here - url: 'https://anubis.techaro.lol', + url: "https://anubis.techaro.lol", // Set the // pathname under which your site is served // For GitHub pages deployment, it is often '//' - baseUrl: '/', + baseUrl: "/", // GitHub pages deployment config. // If you aren't using GitHub pages, you don't need these. - organizationName: 'TecharoHQ', // Usually your GitHub org/user name. - projectName: 'anubis', // Usually your repo name. + organizationName: "TecharoHQ", // Usually your GitHub org/user name. + projectName: "anubis", // Usually your repo name. - onBrokenLinks: 'throw', - onBrokenMarkdownLinks: 'warn', + onBrokenLinks: "throw", + onBrokenMarkdownLinks: "warn", // Even if you don't use internationalization, you can use this field to set // useful metadata like html lang. For example, if your site is Chinese, you // may want to replace "en" with "zh-Hans". i18n: { - defaultLocale: 'en', - locales: ['en'], + defaultLocale: "en", + locales: ["en"], }, markdown: { mermaid: true, }, - themes: ['@docusaurus/theme-mermaid'], + themes: ["@docusaurus/theme-mermaid"], presets: [ [ - 'classic', + "classic", { blog: { showReadingTime: true, feedOptions: { - type: ['rss', 'atom', "json"], + type: ["rss", "atom", "json"], xslt: true, }, - editUrl: 'https://github.com/TecharoHQ/anubis/tree/main/docs/', - onInlineTags: 'warn', - onInlineAuthors: 'warn', - onUntruncatedBlogPosts: 'throw', + editUrl: "https://github.com/TecharoHQ/anubis/tree/main/docs/", + onInlineTags: "warn", + onInlineAuthors: "warn", + onUntruncatedBlogPosts: "throw", }, docs: { - sidebarPath: './sidebars.ts', - editUrl: 'https://github.com/TecharoHQ/anubis/tree/main/docs/', + sidebarPath: "./sidebars.ts", + editUrl: "https://github.com/TecharoHQ/anubis/tree/main/docs/", }, theme: { - customCss: './src/css/custom.css', + customCss: "./src/css/custom.css", }, } satisfies Preset.Options, ], @@ -67,47 +67,47 @@ const config: Config = { respectPrefersColorScheme: true, }, // Replace with your project's social card - image: 'img/social-card.jpg', + image: "img/social-card.jpg", navbar: { - title: 'Anubis', + title: "Anubis", logo: { - alt: 'A happy jackal woman with brown hair and red eyes', - src: 'img/favicon.webp', + alt: "A happy jackal woman with brown hair and red eyes", + src: "img/favicon.webp", }, items: [ - { to: '/blog', label: 'Blog', position: 'left' }, + { to: "/blog", label: "Blog", position: "left" }, { - type: 'docSidebar', - sidebarId: 'tutorialSidebar', - position: 'left', - label: 'Docs', + type: "docSidebar", + sidebarId: "tutorialSidebar", + position: "left", + label: "Docs", }, { - to: '/docs/admin/botstopper', + to: "/docs/admin/botstopper", label: "Unbranded Version", - position: "left" + position: "left", }, { - href: 'https://github.com/TecharoHQ/anubis', - label: 'GitHub', - position: 'right', + href: "https://github.com/TecharoHQ/anubis", + label: "GitHub", + position: "right", }, { - href: 'https://github.com/sponsors/Xe', + href: "https://github.com/sponsors/Xe", label: "Sponsor the Project", - position: 'right' + position: "right", }, ], }, footer: { - style: 'dark', + style: "dark", links: [ { - title: 'Docs', + title: "Docs", items: [ { - label: 'Intro', - to: '/docs/', + label: "Intro", + to: "/docs/", }, { label: "Installation", @@ -116,32 +116,32 @@ const config: Config = { ], }, { - title: 'Community', + title: "Community", items: [ { - label: 'GitHub Discussions', - href: 'https://github.com/TecharoHQ/anubis/discussions', + label: "GitHub Discussions", + href: "https://github.com/TecharoHQ/anubis/discussions", }, { - label: 'Bluesky', - href: 'https://bsky.app/profile/techaro.lol', + label: "Bluesky", + href: "https://bsky.app/profile/techaro.lol", }, ], }, { - title: 'More', + title: "More", items: [ { - label: 'Blog', - to: '/blog', + label: "Blog", + to: "/blog", }, { - label: 'GitHub', - href: 'https://github.com/TecharoHQ/anubis', + label: "GitHub", + href: "https://github.com/TecharoHQ/anubis", }, { - label: 'Status', - href: 'https://techarohq.github.io/status/' + label: "Status", + href: "https://techarohq.github.io/status/", }, ], }, @@ -153,13 +153,13 @@ const config: Config = { darkTheme: prismThemes.dracula, magicComments: [ { - className: 'code-block-diff-add-line', - line: 'diff-add' + className: "code-block-diff-add-line", + line: "diff-add", }, { - className: 'code-block-diff-remove-line', - line: 'diff-remove' - } + className: "code-block-diff-remove-line", + line: "diff-remove", + }, ], }, } satisfies Preset.ThemeConfig, diff --git a/docs/manifest/ingress.yaml b/docs/manifest/ingress.yaml index 52478361..8ce3b9fc 100644 --- a/docs/manifest/ingress.yaml +++ b/docs/manifest/ingress.yaml @@ -21,4 +21,4 @@ spec: service: name: anubis-docs port: - name: anubis \ No newline at end of file + name: anubis diff --git a/docs/manifest/onionservice.yaml b/docs/manifest/onionservice.yaml index 81ab9729..e0584468 100644 --- a/docs/manifest/onionservice.yaml +++ b/docs/manifest/onionservice.yaml @@ -5,10 +5,10 @@ metadata: spec: version: 3 rules: - - port: - number: 80 - backend: - service: - name: anubis-docs - port: - number: 80 \ No newline at end of file + - port: + number: 80 + backend: + service: + name: anubis-docs + port: + number: 80 diff --git a/docs/manifest/service.yaml b/docs/manifest/service.yaml index dadac058..1acdc45d 100644 --- a/docs/manifest/service.yaml +++ b/docs/manifest/service.yaml @@ -6,9 +6,9 @@ spec: selector: app: anubis-docs ports: - - port: 80 - targetPort: 80 - name: http - - port: 8081 - targetPort: 8081 - name: anubis + - port: 80 + targetPort: 80 + name: http + - port: 8081 + targetPort: 8081 + name: anubis diff --git a/docs/sidebars.ts b/docs/sidebars.ts index 28971397..574ed394 100644 --- a/docs/sidebars.ts +++ b/docs/sidebars.ts @@ -1,4 +1,4 @@ -import type {SidebarsConfig} from '@docusaurus/plugin-content-docs'; +import type { SidebarsConfig } from "@docusaurus/plugin-content-docs"; // This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) @@ -14,7 +14,7 @@ import type {SidebarsConfig} from '@docusaurus/plugin-content-docs'; */ const sidebars: SidebarsConfig = { // By default, Docusaurus generates a sidebar from the docs folder structure - tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], + tutorialSidebar: [{ type: "autogenerated", dirName: "." }], // But you can create a sidebar manually /* diff --git a/docs/src/components/EnterpriseOnly/index.jsx b/docs/src/components/EnterpriseOnly/index.jsx index bfd9486c..ac6bab1d 100644 --- a/docs/src/components/EnterpriseOnly/index.jsx +++ b/docs/src/components/EnterpriseOnly/index.jsx @@ -1,4 +1,4 @@ -import styles from './styles.module.css'; +import styles from "./styles.module.css"; export default function EnterpriseOnly({ link }) { return ( @@ -8,4 +8,4 @@ export default function EnterpriseOnly({ link }) {
); -} \ No newline at end of file +} diff --git a/docs/src/components/EnterpriseOnly/styles.module.css b/docs/src/components/EnterpriseOnly/styles.module.css index f3ac7a15..056cedc0 100644 --- a/docs/src/components/EnterpriseOnly/styles.module.css +++ b/docs/src/components/EnterpriseOnly/styles.module.css @@ -8,7 +8,9 @@ font-weight: 700; padding: 0.5rem 1rem; /* py-2 px-4 */ border-radius: 9999px; /* rounded-full */ - box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); /* shadow-lg approximation */ + box-shadow: + 0 10px 15px -3px rgba(0, 0, 0, 0.1), + 0 4px 6px -2px rgba(0, 0, 0, 0.05); /* shadow-lg approximation */ display: inline-flex; /* flex */ align-items: center; /* items-center */ } diff --git a/lib/challenge/preact/js/xeact.js b/lib/challenge/preact/js/xeact.js index cf4a102e..1488f8b8 100644 --- a/lib/challenge/preact/js/xeact.js +++ b/lib/challenge/preact/js/xeact.js @@ -5,7 +5,9 @@ */ const h = (name, data = {}, children = []) => { const result = - typeof name == "function" ? name(data) : Object.assign(document.createElement(name), data); + typeof name == "function" + ? name(data) + : Object.assign(document.createElement(name), data); if (!Array.isArray(children)) { children = [children]; } @@ -118,10 +120,10 @@ const d = (ms) => { /** * Parse the contents of a given HTML page element as JSON and * return the results. - * + * * This is useful when using templ to pass complicated data from * the server to the client via HTML[1]. - * + * * [1]: https://templ.guide/syntax-and-usage/script-templates/#pass-server-side-data-to-the-client-in-a-html-attribute */ const j = (id) => JSON.parse(g(id).textContent); diff --git a/lib/config/testdata/bad/badregexes.json b/lib/config/testdata/bad/badregexes.json index db371b0f..436f768d 100644 --- a/lib/config/testdata/bad/badregexes.json +++ b/lib/config/testdata/bad/badregexes.json @@ -18,4 +18,4 @@ "action": "DENY" } ] -} \ No newline at end of file +} diff --git a/lib/config/testdata/bad/badregexes.yaml b/lib/config/testdata/bad/badregexes.yaml index 3880e407..c6caedbd 100644 --- a/lib/config/testdata/bad/badregexes.yaml +++ b/lib/config/testdata/bad/badregexes.yaml @@ -1,7 +1,7 @@ bots: -- name: path-bad - path_regex: "a(b" - action: DENY -- name: user-agent-bad - user_agent_regex: "a(b" - action: DENY \ No newline at end of file + - name: path-bad + path_regex: "a(b" + action: DENY + - name: user-agent-bad + user_agent_regex: "a(b" + action: DENY diff --git a/lib/config/testdata/bad/import_and_bot.json b/lib/config/testdata/bad/import_and_bot.json index 3d0519bc..ef9778cd 100644 --- a/lib/config/testdata/bad/import_and_bot.json +++ b/lib/config/testdata/bad/import_and_bot.json @@ -7,4 +7,4 @@ "action": "CHALLENGE" } ] -} \ No newline at end of file +} diff --git a/lib/config/testdata/bad/import_and_bot.yaml b/lib/config/testdata/bad/import_and_bot.yaml index fdfaa43a..cc9142db 100644 --- a/lib/config/testdata/bad/import_and_bot.yaml +++ b/lib/config/testdata/bad/import_and_bot.yaml @@ -1,6 +1,6 @@ bots: -- import: (data)/bots/ai-catchall.yaml - name: generic-browser - user_agent_regex: > - Mozilla|Opera - action: CHALLENGE \ No newline at end of file + - import: (data)/bots/ai-catchall.yaml + name: generic-browser + user_agent_regex: > + Mozilla|Opera + action: CHALLENGE diff --git a/lib/config/testdata/bad/import_invalid_file.json b/lib/config/testdata/bad/import_invalid_file.json index c7546c09..26669635 100644 --- a/lib/config/testdata/bad/import_invalid_file.json +++ b/lib/config/testdata/bad/import_invalid_file.json @@ -4,4 +4,4 @@ "import": "(data)/does-not-exist-fake-file.yaml" } ] -} \ No newline at end of file +} diff --git a/lib/config/testdata/bad/import_invalid_file.yaml b/lib/config/testdata/bad/import_invalid_file.yaml index df78c067..c82b4533 100644 --- a/lib/config/testdata/bad/import_invalid_file.yaml +++ b/lib/config/testdata/bad/import_invalid_file.yaml @@ -1,2 +1,2 @@ bots: -- import: (data)/does-not-exist-fake-file.yaml \ No newline at end of file + - import: (data)/does-not-exist-fake-file.yaml diff --git a/lib/config/testdata/bad/invalid.json b/lib/config/testdata/bad/invalid.json index c5d1ff6c..334e5db7 100644 --- a/lib/config/testdata/bad/invalid.json +++ b/lib/config/testdata/bad/invalid.json @@ -1,5 +1,3 @@ { - "bots": [ - {} - ] -} \ No newline at end of file + "bots": [{}] +} diff --git a/lib/config/testdata/bad/invalid.yaml b/lib/config/testdata/bad/invalid.yaml index 18625b61..b78eb920 100644 --- a/lib/config/testdata/bad/invalid.yaml +++ b/lib/config/testdata/bad/invalid.yaml @@ -1 +1 @@ -bots: [] \ No newline at end of file +bots: [] diff --git a/lib/config/testdata/bad/multiple_expression_types.json b/lib/config/testdata/bad/multiple_expression_types.json index 8b852768..0bdf5bfc 100644 --- a/lib/config/testdata/bad/multiple_expression_types.json +++ b/lib/config/testdata/bad/multiple_expression_types.json @@ -8,10 +8,8 @@ "userAgent.startsWith(\"git/\") || userAgent.contains(\"libgit\")", "\"Git-Protocol\" in headers && headers[\"Git-Protocol\"] == \"version=2\"\n" ], - "any": [ - "userAgent.startsWith(\"evilbot/\")" - ] + "any": ["userAgent.startsWith(\"evilbot/\")"] } } ] -} \ No newline at end of file +} diff --git a/lib/config/testdata/bad/multiple_expression_types.yaml b/lib/config/testdata/bad/multiple_expression_types.yaml index f7aa5463..da97d454 100644 --- a/lib/config/testdata/bad/multiple_expression_types.yaml +++ b/lib/config/testdata/bad/multiple_expression_types.yaml @@ -1,10 +1,10 @@ bots: -- name: multiple-expression-types - action: ALLOW - expression: - all: - - userAgent.startsWith("git/") || userAgent.contains("libgit") - - > - "Git-Protocol" in headers && headers["Git-Protocol"] == "version=2" - any: - - userAgent.startsWith("evilbot/") + - name: multiple-expression-types + action: ALLOW + expression: + all: + - userAgent.startsWith("git/") || userAgent.contains("libgit") + - > + "Git-Protocol" in headers && headers["Git-Protocol"] == "version=2" + any: + - userAgent.startsWith("evilbot/") diff --git a/lib/config/testdata/bad/nobots.json b/lib/config/testdata/bad/nobots.json index 9e26dfee..0967ef42 100644 --- a/lib/config/testdata/bad/nobots.json +++ b/lib/config/testdata/bad/nobots.json @@ -1 +1 @@ -{} \ No newline at end of file +{} diff --git a/lib/config/testdata/bad/nobots.yaml b/lib/config/testdata/bad/nobots.yaml index 9e26dfee..0967ef42 100644 --- a/lib/config/testdata/bad/nobots.yaml +++ b/lib/config/testdata/bad/nobots.yaml @@ -1 +1 @@ -{} \ No newline at end of file +{} diff --git a/lib/config/testdata/bad/regex_ends_newline.yaml b/lib/config/testdata/bad/regex_ends_newline.yaml index 1f0ae85b..7400016b 100644 --- a/lib/config/testdata/bad/regex_ends_newline.yaml +++ b/lib/config/testdata/bad/regex_ends_newline.yaml @@ -1,17 +1,17 @@ bots: -- name: user-agent-ends-newline - # Subtle bug: this ends with a newline - user_agent_regex: > - Mozilla - action: CHALLENGE -- name: path-ends-newline - # Subtle bug: this ends with a newline - path_regex: > - ^/evil/.*$ - action: CHALLENGE -- name: headers-ends-newline - # Subtle bug: this ends with a newline - headers_regex: - CF-Worker: > - .* - action: CHALLENGE \ No newline at end of file + - name: user-agent-ends-newline + # Subtle bug: this ends with a newline + user_agent_regex: > + Mozilla + action: CHALLENGE + - name: path-ends-newline + # Subtle bug: this ends with a newline + path_regex: > + ^/evil/.*$ + action: CHALLENGE + - name: headers-ends-newline + # Subtle bug: this ends with a newline + headers_regex: + CF-Worker: > + .* + action: CHALLENGE diff --git a/lib/config/testdata/bad/status-codes-0.yaml b/lib/config/testdata/bad/status-codes-0.yaml index 0d08322e..96df3d1d 100644 --- a/lib/config/testdata/bad/status-codes-0.yaml +++ b/lib/config/testdata/bad/status-codes-0.yaml @@ -1,8 +1,8 @@ bots: -- name: everything - user_agent_regex: .* - action: DENY + - name: everything + user_agent_regex: .* + action: DENY status_codes: CHALLENGE: 0 - DENY: 0 \ No newline at end of file + DENY: 0 diff --git a/lib/config/testdata/good/allow_everyone.json b/lib/config/testdata/good/allow_everyone.json index a7e1af76..de298c6b 100644 --- a/lib/config/testdata/good/allow_everyone.json +++ b/lib/config/testdata/good/allow_everyone.json @@ -2,11 +2,8 @@ "bots": [ { "name": "everyones-invited", - "remote_addresses": [ - "0.0.0.0/0", - "::/0" - ], + "remote_addresses": ["0.0.0.0/0", "::/0"], "action": "ALLOW" } ] -} \ No newline at end of file +} diff --git a/lib/config/testdata/good/allow_everyone.yaml b/lib/config/testdata/good/allow_everyone.yaml index 5c495345..80dae8b2 100644 --- a/lib/config/testdata/good/allow_everyone.yaml +++ b/lib/config/testdata/good/allow_everyone.yaml @@ -1,6 +1,6 @@ bots: -- name: everyones-invited - remote_addresses: - - "0.0.0.0/0" - - "::/0" - action: ALLOW \ No newline at end of file + - name: everyones-invited + remote_addresses: + - "0.0.0.0/0" + - "::/0" + action: ALLOW diff --git a/lib/config/testdata/good/block_cf_workers.json b/lib/config/testdata/good/block_cf_workers.json index b84f1e0d..380fdf04 100644 --- a/lib/config/testdata/good/block_cf_workers.json +++ b/lib/config/testdata/good/block_cf_workers.json @@ -9,4 +9,4 @@ } ], "dnsbl": false -} \ No newline at end of file +} diff --git a/lib/config/testdata/good/block_cf_workers.yaml b/lib/config/testdata/good/block_cf_workers.yaml index c66badef..353c921a 100644 --- a/lib/config/testdata/good/block_cf_workers.yaml +++ b/lib/config/testdata/good/block_cf_workers.yaml @@ -2,4 +2,4 @@ bots: - name: cloudflare-workers headers_regex: CF-Worker: .* - action: DENY \ No newline at end of file + action: DENY diff --git a/lib/config/testdata/good/challengemozilla.json b/lib/config/testdata/good/challengemozilla.json index e9d34eeb..eaee8490 100644 --- a/lib/config/testdata/good/challengemozilla.json +++ b/lib/config/testdata/good/challengemozilla.json @@ -6,4 +6,4 @@ "action": "CHALLENGE" } ] -} \ No newline at end of file +} diff --git a/lib/config/testdata/good/challengemozilla.yaml b/lib/config/testdata/good/challengemozilla.yaml index 15922b0a..f6d8e9ac 100644 --- a/lib/config/testdata/good/challengemozilla.yaml +++ b/lib/config/testdata/good/challengemozilla.yaml @@ -1,4 +1,4 @@ bots: -- name: generic-browser - user_agent_regex: Mozilla - action: CHALLENGE \ No newline at end of file + - name: generic-browser + user_agent_regex: Mozilla + action: CHALLENGE diff --git a/lib/config/testdata/good/everything_blocked.json b/lib/config/testdata/good/everything_blocked.json index e1763e45..ab694f25 100644 --- a/lib/config/testdata/good/everything_blocked.json +++ b/lib/config/testdata/good/everything_blocked.json @@ -7,4 +7,4 @@ } ], "dnsbl": false -} \ No newline at end of file +} diff --git a/lib/config/testdata/good/everything_blocked.yaml b/lib/config/testdata/good/everything_blocked.yaml index 323c5969..1c805581 100644 --- a/lib/config/testdata/good/everything_blocked.yaml +++ b/lib/config/testdata/good/everything_blocked.yaml @@ -1,4 +1,4 @@ bots: -- name: everything - user_agent_regex: .* - action: DENY + - name: everything + user_agent_regex: .* + action: DENY diff --git a/lib/config/testdata/good/git_client.json b/lib/config/testdata/good/git_client.json index 68a2b3e8..52c5e11f 100644 --- a/lib/config/testdata/good/git_client.json +++ b/lib/config/testdata/good/git_client.json @@ -11,4 +11,4 @@ } } ] -} \ No newline at end of file +} diff --git a/lib/config/testdata/good/git_client.yaml b/lib/config/testdata/good/git_client.yaml index 44aa2da3..1c496789 100644 --- a/lib/config/testdata/good/git_client.yaml +++ b/lib/config/testdata/good/git_client.yaml @@ -1,8 +1,8 @@ bots: -- name: allow-git-clients - action: ALLOW - expression: - all: - - userAgent.startsWith("git/") || userAgent.contains("libgit") - - > - "Git-Protocol" in headers && headers["Git-Protocol"] == "version=2" + - name: allow-git-clients + action: ALLOW + expression: + all: + - userAgent.startsWith("git/") || userAgent.contains("libgit") + - > + "Git-Protocol" in headers && headers["Git-Protocol"] == "version=2" diff --git a/lib/config/testdata/good/import_filesystem.json b/lib/config/testdata/good/import_filesystem.json index 23480c90..ba0228a7 100644 --- a/lib/config/testdata/good/import_filesystem.json +++ b/lib/config/testdata/good/import_filesystem.json @@ -4,4 +4,4 @@ "import": "./testdata/hack-test.json" } ] -} \ No newline at end of file +} diff --git a/lib/config/testdata/good/import_filesystem.yaml b/lib/config/testdata/good/import_filesystem.yaml index 422ccc4e..2ea0d54e 100644 --- a/lib/config/testdata/good/import_filesystem.yaml +++ b/lib/config/testdata/good/import_filesystem.yaml @@ -1,2 +1,2 @@ bots: -- import: ./testdata/hack-test.yaml \ No newline at end of file + - import: ./testdata/hack-test.yaml diff --git a/lib/config/testdata/good/import_keep_internet_working.json b/lib/config/testdata/good/import_keep_internet_working.json index 68ff2dbc..06b08fe1 100644 --- a/lib/config/testdata/good/import_keep_internet_working.json +++ b/lib/config/testdata/good/import_keep_internet_working.json @@ -4,4 +4,4 @@ "import": "(data)/common/keep-internet-working.yaml" } ] -} \ No newline at end of file +} diff --git a/lib/config/testdata/good/import_keep_internet_working.yaml b/lib/config/testdata/good/import_keep_internet_working.yaml index 923ffe32..19ff33eb 100644 --- a/lib/config/testdata/good/import_keep_internet_working.yaml +++ b/lib/config/testdata/good/import_keep_internet_working.yaml @@ -1,2 +1,2 @@ bots: -- import: (data)/common/keep-internet-working.yaml \ No newline at end of file + - import: (data)/common/keep-internet-working.yaml diff --git a/lib/config/testdata/good/old_xesite.json b/lib/config/testdata/good/old_xesite.json index 21816bdd..763d6785 100644 --- a/lib/config/testdata/good/old_xesite.json +++ b/lib/config/testdata/good/old_xesite.json @@ -76,4 +76,4 @@ "action": "CHALLENGE" } ] -} \ No newline at end of file +} diff --git a/lib/config/testdata/good/status-codes-paranoid.yaml b/lib/config/testdata/good/status-codes-paranoid.yaml index 89655a3d..0310388b 100644 --- a/lib/config/testdata/good/status-codes-paranoid.yaml +++ b/lib/config/testdata/good/status-codes-paranoid.yaml @@ -1,8 +1,8 @@ bots: -- name: everything - user_agent_regex: .* - action: DENY + - name: everything + user_agent_regex: .* + action: DENY status_codes: CHALLENGE: 200 - DENY: 200 \ No newline at end of file + DENY: 200 diff --git a/lib/config/testdata/good/status-codes-rfc.yaml b/lib/config/testdata/good/status-codes-rfc.yaml index 4e4e6d8d..c70ea126 100644 --- a/lib/config/testdata/good/status-codes-rfc.yaml +++ b/lib/config/testdata/good/status-codes-rfc.yaml @@ -1,8 +1,8 @@ bots: -- name: everything - user_agent_regex: .* - action: DENY + - name: everything + user_agent_regex: .* + action: DENY status_codes: CHALLENGE: 403 - DENY: 403 \ No newline at end of file + DENY: 403 diff --git a/lib/config/testdata/hack-test.json b/lib/config/testdata/hack-test.json index 652dcd87..a173bb18 100644 --- a/lib/config/testdata/hack-test.json +++ b/lib/config/testdata/hack-test.json @@ -2,8 +2,6 @@ { "name": "ipv6-ula", "action": "ALLOW", - "remote_addresses": [ - "fc00::/7" - ] + "remote_addresses": ["fc00::/7"] } -] \ No newline at end of file +] diff --git a/lib/config/testdata/hack-test.yaml b/lib/config/testdata/hack-test.yaml index cd4d7d05..29263e96 100644 --- a/lib/config/testdata/hack-test.yaml +++ b/lib/config/testdata/hack-test.yaml @@ -1,3 +1,3 @@ - name: well-known path_regex: ^/.well-known/.*$ - action: ALLOW \ No newline at end of file + action: ALLOW diff --git a/lib/localization/locales/cs.json b/lib/localization/locales/cs.json index db4eded3..967da646 100644 --- a/lib/localization/locales/cs.json +++ b/lib/localization/locales/cs.json @@ -63,4 +63,4 @@ "js_calculation_error": "Chyba výpočtu!", "js_calculation_error_msg": "Nepodařilo se vypočítat výzvu:", "missing_required_forwarded_headers": "Chybějící požadované hlavičky X-Forwarded-*" -} \ No newline at end of file +} diff --git a/lib/localization/locales/en.json b/lib/localization/locales/en.json index 0280b975..4dffb969 100644 --- a/lib/localization/locales/en.json +++ b/lib/localization/locales/en.json @@ -63,4 +63,4 @@ "js_finished_reading": "I've finished reading, continue →", "js_calculation_error": "Calculation error!", "js_calculation_error_msg": "Failed to calculate challenge:" -} \ No newline at end of file +} diff --git a/lib/localization/locales/es.json b/lib/localization/locales/es.json index 8beb3bf8..d4e91418 100644 --- a/lib/localization/locales/es.json +++ b/lib/localization/locales/es.json @@ -63,4 +63,4 @@ "js_calculation_error_msg": "Falló al calcular el desafío:", "missing_required_forwarded_headers": "Faltan los encabezados X-Forwarded-* requeridos", "simplified_explanation": "Esta es una medida contra bots y solicitudes maliciosas similar a un CAPTCHA. Sin embargo, en lugar de tener que hacer el trabajo usted mismo, a su navegador se le asigna una tarea de cálculo que debe resolver para garantizar que es un cliente válido. Este concepto se llama Prueba de trabajo. La tarea se calcula en unos segundos y se le concede acceso al sitio web. Gracias por su comprensión y paciencia." -} \ No newline at end of file +} diff --git a/lib/localization/locales/et.json b/lib/localization/locales/et.json index 09125b9c..6ecfd2fa 100644 --- a/lib/localization/locales/et.json +++ b/lib/localization/locales/et.json @@ -63,4 +63,4 @@ "js_calculation_error_msg": "Ei suutnud kontrolli arvutada:", "missing_required_forwarded_headers": "Puuduvad nõutud X-Forwarded-* päised", "simplified_explanation": "See on meede robotite ja pahatahtlike päringute vastu, mis sarnaneb CAPTCHA-le. Kuid selle asemel, et peaksite ise tööd tegema, antakse teie brauserile arvutusülesanne, mille see peab lahendama, et tagada selle kehtivus kliendina. Seda kontseptsiooni nimetatakse Töötõendiks. Ülesanne arvutatakse mõne sekundiga ja teile antakse juurdepääs veebisaidile. Täname teid mõistva suhtumise ja kannatlikkuse eest." -} \ No newline at end of file +} diff --git a/lib/localization/locales/fi.json b/lib/localization/locales/fi.json index bd06d3a7..fb313c25 100644 --- a/lib/localization/locales/fi.json +++ b/lib/localization/locales/fi.json @@ -63,4 +63,4 @@ "js_calculation_error_msg": "Haasteen laskenta ei onnistunut:", "missing_required_forwarded_headers": "Puuttuvat vaaditut X-Forwarded-* otsikot", "simplified_explanation": "Tämä on toimenpide botteja ja haitallisia pyyntöjä vastaan, joka on samanlainen kuin CAPTCHA. Sen sijaan, että joutuisit tekemään työtä itse, selaimesi saa laskentatehtävän, joka sen on ratkaistava varmistaakseen, että se on kelvollinen asiakas. Tätä käsitettä kutsutaan nimellä Työtodistus. Tehtävä lasketaan muutamassa sekunnissa ja saat pääsyn verkkosivustolle. Kiitos ymmärryksestäsi ja kärsivällisyydestäsi." -} \ No newline at end of file +} diff --git a/lib/localization/locales/fr.json b/lib/localization/locales/fr.json index b696e04c..a113c457 100644 --- a/lib/localization/locales/fr.json +++ b/lib/localization/locales/fr.json @@ -63,4 +63,4 @@ "js_calculation_error_msg": "Échec du calcul du défi :", "missing_required_forwarded_headers": "En-têtes X-Forwarded-* requis manquants", "simplified_explanation": "Il s'agit d'une mesure contre les robots et les requêtes malveillantes similaire à un CAPTCHA. Cependant, au lieu d'avoir à faire le travail vous-même, votre navigateur se voit confier une tâche de calcul qu'il doit résoudre pour s'assurer qu'il est un client valide. Ce concept s'appelle Preuve de travail. La tâche est calculée en quelques secondes et vous avez accès au site Web. Merci de votre compréhension et de votre patience." -} \ No newline at end of file +} diff --git a/lib/localization/locales/it.json b/lib/localization/locales/it.json index e2ecc11b..4b44c523 100644 --- a/lib/localization/locales/it.json +++ b/lib/localization/locales/it.json @@ -63,4 +63,4 @@ "js_calculation_error_msg": "Impossibile superare il test:", "missing_required_forwarded_headers": "Mancano gli header X-Forwarded-* richiesti", "simplified_explanation": "Questa è una misura contro bot e richieste dannose simile a un CAPTCHA. Tuttavia, invece di dover lavorare tu stesso, al tuo browser viene assegnato un compito di calcolo che deve risolvere per garantire che sia un client valido. Questo concetto è chiamato Proof of Work. Il compito viene calcolato in pochi secondi e ti viene concesso l'accesso al sito web. Grazie per la tua comprensione e pazienza." -} \ No newline at end of file +} diff --git a/lib/localization/locales/ja.json b/lib/localization/locales/ja.json index 3042173d..369438ed 100644 --- a/lib/localization/locales/ja.json +++ b/lib/localization/locales/ja.json @@ -63,4 +63,4 @@ "js_calculation_error_msg": "チャレンジの計算に失敗しました:", "missing_required_forwarded_headers": "必要な X-Forwarded-* ヘッダーがありません", "simplified_explanation": "これは、CAPTCHAと同様の、ボットや悪意のあるリクエストに対する対策です。ただし、自分で作業する代わりに、ブラウザに計算タスクが与えられ、それを解決して有効なクライアントであることを確認する必要があります。この概念はProof of Workと呼ばれます。タスクは数秒で計算され、ウェブサイトへのアクセスが許可されます。ご理解とご協力をお願いいたします。" -} \ No newline at end of file +} diff --git a/lib/localization/locales/nb.json b/lib/localization/locales/nb.json index 0b8b6fcc..ada36f20 100644 --- a/lib/localization/locales/nb.json +++ b/lib/localization/locales/nb.json @@ -63,4 +63,4 @@ "js_calculation_error_msg": "Mislyktes i å beregne utfordring:", "missing_required_forwarded_headers": "Mangler nødvendige X-Forwarded-* header", "simplified_explanation": "Dette er et tiltak mot roboter og ondsinnede forespørsler som ligner på en CAPTCHA. Men i stedet for å måtte gjøre arbeidet selv, får nettleseren din en beregningsoppgave som den må løse for å sikre at den er en gyldig klient. Dette konseptet kalles Proof of Work. Oppgaven beregnes på noen få sekunder, og du får tilgang til nettstedet. Takk for din forståelse og tålmodighet." -} \ No newline at end of file +} diff --git a/lib/localization/locales/pl.json b/lib/localization/locales/pl.json index 47e84c31..b7e7f6e8 100644 --- a/lib/localization/locales/pl.json +++ b/lib/localization/locales/pl.json @@ -1,66 +1,66 @@ { - "loading": "Ładowanie...", - "why_am_i_seeing": "Dlaczego to widzę?", - "protected_by": "Chronione przez", - "protected_from": "Przed", - "made_with": "Stworzone z ❤️ w 🇨🇦", - "mascot_design": "Projekt maskotki:", - "ai_companies_explanation": "Widzisz to, ponieważ administrator tej strony skonfigurował Anubisa, aby chronić serwer przed masowym skanowaniem treści przez firmy tworzące AI. Powoduje to obciążenie i przestoje, przez co zasoby strony stają się niedostępne dla wszystkich.", - "anubis_compromise": "Anubis jest kompromisem. Używa mechanizmu Proof-of-Work w stylu Hashcash — proponowanego systemu ograniczania spamu e-mail. Pomysł polega na tym, że dla indywidualnych użytkowników dodatkowe obciążenie jest niezauważalne, ale w skali masowego skanowania koszt szybko rośnie.", - "hack_purpose": "Docelowo jest to rozwiązanie tymczasowe, aby zyskać czas na ulepszenie metod identyfikacji przeglądarek bez interfejsu graficznego (np. poprzez analizę renderowania czcionek), by w przyszłości nie musieć wyświetlać strony z zadaniem Proof-of-Work użytkownikom, którzy najprawdopodobniej są prawidłowi.", - "simplified_explanation": "To zabezpieczenie przed botami i złośliwymi żądaniami, podobne do CAPTCHA. Jednak zamiast wykonywać zadanie samodzielnie, przeglądarka otrzymuje obliczenie do wykonania, aby potwierdzić, że jest prawidłowym klientem. Ten mechanizm to Proof of Work. Zadanie trwa kilka sekund i uzyskujesz dostęp do strony. Dziękujemy za cierpliwość.", - "jshelter_note": "Uwaga: Anubis wymaga nowoczesnych funkcji JavaScript, które wtyczki typu JShelter mogą blokować. Wyłącz JShelter lub podobne dodatki dla tej domeny.", - "version_info": "Ta strona działa na Anubis w wersji", - "try_again": "Spróbuj ponownie", - "go_home": "Wróć na stronę główną", - "contact_webmaster": "lub jeśli uważasz, że nie powinieneś być blokowany, skontaktuj się z administratorem pod adresem", - "connection_security": "Poczekaj chwilę, sprawdzamy bezpieczeństwo Twojego połączenia.", - "javascript_required": "Niestety, aby przejść tę próbę, musisz włączyć obsługę JavaScript. Jest to konieczne, ponieważ firmy zajmujące się sztuczną inteligencją zmieniły umowę społeczną dotyczącą funkcjonowania hostingu stron internetowych. Rozwiązanie bez obsługi JavaScript jest w trakcie opracowywania.", - "benchmark_requires_js": "Uruchomienie narzędzia testowego wymaga włączonego JavaScript.", - "difficulty": "Trudność:", - "algorithm": "Algorytm:", - "compare": "Porównaj:", - "time": "Czas", - "iters": "Iteracje", - "time_a": "Czas A", - "iters_a": "Iteracje A", - "time_b": "Czas B", - "iters_b": "Iteracje B", - "static_check_endpoint": "To jedynie punkt kontrolny do użytku przez Twój reverse proxy.", - "authorization_required": "Wymagane uwierzytelnienie", - "cookies_disabled": "Twoja przeglądarka blokuje ciasteczka. Anubis wymaga ich, aby potwierdzić, że jesteś prawidłowym klientem. Włącz ciasteczka dla tej domeny.", - "access_denied": "Brak dostępu: kod błędu", - "dronebl_entry": "DroneBL zgłosił wpis", - "see_dronebl_lookup": "zobacz", - "internal_server_error": "Błąd wewnętrzny serwera: administrator błędnie skonfigurował Anubis. Skontaktuj się z administratorem i poproś o sprawdzenie logów", - "invalid_redirect": "Nieprawidłowe przekierowanie", - "redirect_not_parseable": "Nie można odczytać adresu przekierowania", - "redirect_domain_not_allowed": "Domena przekierowania niedozwolona", - "missing_required_forwarded_headers": "Brak wymaganych nagłówków X-Forwarded-*", - "failed_to_sign_jwt": "Nie udało się podpisać JWT", - "invalid_invocation": "Nieprawidłowe wywołanie MakeChallenge", - "client_error_browser": "Błąd klienta: upewnij się, że Twoja przeglądarka jest aktualna i spróbuj ponownie później.", - "oh_noes": "O nie!", - "benchmarking_anubis": "Testowanie wydajności Anubis!", - "you_are_not_a_bot": "Nie jesteś botem!", - "making_sure_not_bot": "Sprawdzamy, czy nie jesteś botem!", - "celphase": "CELPHASE", - "js_web_crypto_error": "Twoja przeglądarka nie obsługuje web.crypto. Czy korzystasz z bezpiecznego połączenia?", - "js_web_workers_error": "Twoja przeglądarka nie obsługuje web workers (Anubis ich używa, by nie zawieszać przeglądarki). Czy masz zainstalowaną wtyczkę typu JShelter?", - "js_cookies_error": "Twoja przeglądarka nie zapisuje ciasteczek. Anubis używa ich do przechowywania podpisanego tokenu potwierdzającego przejście zabezpieczenia. Włącz zapis ciasteczek dla tej domeny. Nazwy ciasteczek mogą zmieniać się bez zapowiedzi. Nazwy oraz zawartość ciasteczek nie są cześcią publicznego API.", - "js_context_not_secure": "Kontekst nie jest bezpieczny!", - "js_context_not_secure_msg": "Spróbuj połączyć się przez HTTPS lub poinformuj administratora, by skonfigurował HTTPS. Więcej informacji na MDN.", - "js_calculating": "Obliczanie...", - "js_missing_feature": "Brakująca funkcja", - "js_challenge_error": "Błąd wyzwania!", - "js_challenge_error_msg": "Nie udało się ustalić algorytmu sprawdzającego. Możesz spróbować odświeżyć stronę.", - "js_calculating_difficulty": "Obliczanie...
Trudność:", - "js_speed": "Prędkość:", - "js_verification_longer": "Weryfikacja trwa dłużej niż zwykle. Proszę nie odświeżać strony.", - "js_success": "Sukces!", - "js_done_took": "Gotowe! Zajęło to", - "js_iterations": "iteracji", - "js_finished_reading": "Skończyłem czytać, kontynuuj →", - "js_calculation_error": "Błąd obliczeń!", - "js_calculation_error_msg": "Nie udało się obliczyć zadania:" -} \ No newline at end of file + "loading": "Ładowanie...", + "why_am_i_seeing": "Dlaczego to widzę?", + "protected_by": "Chronione przez", + "protected_from": "Przed", + "made_with": "Stworzone z ❤️ w 🇨🇦", + "mascot_design": "Projekt maskotki:", + "ai_companies_explanation": "Widzisz to, ponieważ administrator tej strony skonfigurował Anubisa, aby chronić serwer przed masowym skanowaniem treści przez firmy tworzące AI. Powoduje to obciążenie i przestoje, przez co zasoby strony stają się niedostępne dla wszystkich.", + "anubis_compromise": "Anubis jest kompromisem. Używa mechanizmu Proof-of-Work w stylu Hashcash — proponowanego systemu ograniczania spamu e-mail. Pomysł polega na tym, że dla indywidualnych użytkowników dodatkowe obciążenie jest niezauważalne, ale w skali masowego skanowania koszt szybko rośnie.", + "hack_purpose": "Docelowo jest to rozwiązanie tymczasowe, aby zyskać czas na ulepszenie metod identyfikacji przeglądarek bez interfejsu graficznego (np. poprzez analizę renderowania czcionek), by w przyszłości nie musieć wyświetlać strony z zadaniem Proof-of-Work użytkownikom, którzy najprawdopodobniej są prawidłowi.", + "simplified_explanation": "To zabezpieczenie przed botami i złośliwymi żądaniami, podobne do CAPTCHA. Jednak zamiast wykonywać zadanie samodzielnie, przeglądarka otrzymuje obliczenie do wykonania, aby potwierdzić, że jest prawidłowym klientem. Ten mechanizm to Proof of Work. Zadanie trwa kilka sekund i uzyskujesz dostęp do strony. Dziękujemy za cierpliwość.", + "jshelter_note": "Uwaga: Anubis wymaga nowoczesnych funkcji JavaScript, które wtyczki typu JShelter mogą blokować. Wyłącz JShelter lub podobne dodatki dla tej domeny.", + "version_info": "Ta strona działa na Anubis w wersji", + "try_again": "Spróbuj ponownie", + "go_home": "Wróć na stronę główną", + "contact_webmaster": "lub jeśli uważasz, że nie powinieneś być blokowany, skontaktuj się z administratorem pod adresem", + "connection_security": "Poczekaj chwilę, sprawdzamy bezpieczeństwo Twojego połączenia.", + "javascript_required": "Niestety, aby przejść tę próbę, musisz włączyć obsługę JavaScript. Jest to konieczne, ponieważ firmy zajmujące się sztuczną inteligencją zmieniły umowę społeczną dotyczącą funkcjonowania hostingu stron internetowych. Rozwiązanie bez obsługi JavaScript jest w trakcie opracowywania.", + "benchmark_requires_js": "Uruchomienie narzędzia testowego wymaga włączonego JavaScript.", + "difficulty": "Trudność:", + "algorithm": "Algorytm:", + "compare": "Porównaj:", + "time": "Czas", + "iters": "Iteracje", + "time_a": "Czas A", + "iters_a": "Iteracje A", + "time_b": "Czas B", + "iters_b": "Iteracje B", + "static_check_endpoint": "To jedynie punkt kontrolny do użytku przez Twój reverse proxy.", + "authorization_required": "Wymagane uwierzytelnienie", + "cookies_disabled": "Twoja przeglądarka blokuje ciasteczka. Anubis wymaga ich, aby potwierdzić, że jesteś prawidłowym klientem. Włącz ciasteczka dla tej domeny.", + "access_denied": "Brak dostępu: kod błędu", + "dronebl_entry": "DroneBL zgłosił wpis", + "see_dronebl_lookup": "zobacz", + "internal_server_error": "Błąd wewnętrzny serwera: administrator błędnie skonfigurował Anubis. Skontaktuj się z administratorem i poproś o sprawdzenie logów", + "invalid_redirect": "Nieprawidłowe przekierowanie", + "redirect_not_parseable": "Nie można odczytać adresu przekierowania", + "redirect_domain_not_allowed": "Domena przekierowania niedozwolona", + "missing_required_forwarded_headers": "Brak wymaganych nagłówków X-Forwarded-*", + "failed_to_sign_jwt": "Nie udało się podpisać JWT", + "invalid_invocation": "Nieprawidłowe wywołanie MakeChallenge", + "client_error_browser": "Błąd klienta: upewnij się, że Twoja przeglądarka jest aktualna i spróbuj ponownie później.", + "oh_noes": "O nie!", + "benchmarking_anubis": "Testowanie wydajności Anubis!", + "you_are_not_a_bot": "Nie jesteś botem!", + "making_sure_not_bot": "Sprawdzamy, czy nie jesteś botem!", + "celphase": "CELPHASE", + "js_web_crypto_error": "Twoja przeglądarka nie obsługuje web.crypto. Czy korzystasz z bezpiecznego połączenia?", + "js_web_workers_error": "Twoja przeglądarka nie obsługuje web workers (Anubis ich używa, by nie zawieszać przeglądarki). Czy masz zainstalowaną wtyczkę typu JShelter?", + "js_cookies_error": "Twoja przeglądarka nie zapisuje ciasteczek. Anubis używa ich do przechowywania podpisanego tokenu potwierdzającego przejście zabezpieczenia. Włącz zapis ciasteczek dla tej domeny. Nazwy ciasteczek mogą zmieniać się bez zapowiedzi. Nazwy oraz zawartość ciasteczek nie są cześcią publicznego API.", + "js_context_not_secure": "Kontekst nie jest bezpieczny!", + "js_context_not_secure_msg": "Spróbuj połączyć się przez HTTPS lub poinformuj administratora, by skonfigurował HTTPS. Więcej informacji na MDN.", + "js_calculating": "Obliczanie...", + "js_missing_feature": "Brakująca funkcja", + "js_challenge_error": "Błąd wyzwania!", + "js_challenge_error_msg": "Nie udało się ustalić algorytmu sprawdzającego. Możesz spróbować odświeżyć stronę.", + "js_calculating_difficulty": "Obliczanie...
Trudność:", + "js_speed": "Prędkość:", + "js_verification_longer": "Weryfikacja trwa dłużej niż zwykle. Proszę nie odświeżać strony.", + "js_success": "Sukces!", + "js_done_took": "Gotowe! Zajęło to", + "js_iterations": "iteracji", + "js_finished_reading": "Skończyłem czytać, kontynuuj →", + "js_calculation_error": "Błąd obliczeń!", + "js_calculation_error_msg": "Nie udało się obliczyć zadania:" +} diff --git a/lib/localization/locales/ru.json b/lib/localization/locales/ru.json index 632efd3d..f98e8e14 100644 --- a/lib/localization/locales/ru.json +++ b/lib/localization/locales/ru.json @@ -63,4 +63,4 @@ "js_calculation_error_msg": "Не удалось рассчитать задачу:", "missing_required_forwarded_headers": "Отсутствуют требуемые заголовки X-Forwarded-*", "simplified_explanation": "Это мера против ботов и вредоносных запросов, аналогичная CAPTCHA. Однако вместо того, чтобы вам приходилось работать самостоятельно, вашему браузеру дается задача вычисления, которую он должен решить, чтобы убедиться, что он является действительным клиентом. Эта концепция называется Доказательство выполнения работы. Задача рассчитывается за несколько секунд, и вам предоставляется доступ к веб-сайту. Спасибо за понимание и терпение." -} \ No newline at end of file +} diff --git a/lib/localization/locales/sv.json b/lib/localization/locales/sv.json index dbb18cca..96bff72a 100644 --- a/lib/localization/locales/sv.json +++ b/lib/localization/locales/sv.json @@ -63,4 +63,4 @@ "js_calculation_error_msg": "Misslyckades att kalkylera utmaning:", "missing_required_forwarded_headers": "Saknar nödvändiga X-Forwarded-* headers", "simplified_explanation": "Detta är en åtgärd mot botar och skadliga förfrågningar som liknar en CAPTCHA. Men i stället för att du själv måste göra jobbet får din webbläsare en beräkningsuppgift som den måste lösa för att säkerställa att den är en giltig klient. Detta koncept kallas Arbetsbevis. Uppgiften beräknas på några sekunder och du beviljas tillgång till webbplatsen. Tack för din förståelse och ditt tålamod." -} \ No newline at end of file +} diff --git a/lib/localization/locales/vi.json b/lib/localization/locales/vi.json index edaf20fa..533212b2 100644 --- a/lib/localization/locales/vi.json +++ b/lib/localization/locales/vi.json @@ -63,4 +63,4 @@ "js_finished_reading": "Tôi đã đọc xong, tiếp tục →", "js_calculation_error": "Lỗi tính toán!", "js_calculation_error_msg": "Không thể tính toán thử thách:" -} \ No newline at end of file +} diff --git a/lib/localization/locales/zh-TW.json b/lib/localization/locales/zh-TW.json index 4e7da25c..9f6403b6 100644 --- a/lib/localization/locales/zh-TW.json +++ b/lib/localization/locales/zh-TW.json @@ -63,4 +63,4 @@ "js_calculation_error_msg": "計算挑戰失敗:", "missing_required_forwarded_headers": "缺少必要的 X-Forwarded-* 標頭", "simplified_explanation": "這是一種類似於驗證碼的措施,用於防止機器人和惡意請求。但是,您無需自己動手,您的瀏覽器會收到一個計算任務,必須解決該任務以確保它是有效的客戶端。這個概念稱為工作量證明。該任務在幾秒鐘內計算完畢,您將被授予訪問網站的權限。感謝您的理解和耐心。" -} \ No newline at end of file +} diff --git a/lib/policy/testdata/hack-test.json b/lib/policy/testdata/hack-test.json index 652dcd87..a173bb18 100644 --- a/lib/policy/testdata/hack-test.json +++ b/lib/policy/testdata/hack-test.json @@ -2,8 +2,6 @@ { "name": "ipv6-ula", "action": "ALLOW", - "remote_addresses": [ - "fc00::/7" - ] + "remote_addresses": ["fc00::/7"] } -] \ No newline at end of file +] diff --git a/lib/policy/testdata/hack-test.yaml b/lib/policy/testdata/hack-test.yaml index cd4d7d05..29263e96 100644 --- a/lib/policy/testdata/hack-test.yaml +++ b/lib/policy/testdata/hack-test.yaml @@ -1,3 +1,3 @@ - name: well-known path_regex: ^/.well-known/.*$ - action: ALLOW \ No newline at end of file + action: ALLOW diff --git a/lib/testdata/cloudflare-workers-cel.yaml b/lib/testdata/cloudflare-workers-cel.yaml index b2d6de5a..b165d503 100644 --- a/lib/testdata/cloudflare-workers-cel.yaml +++ b/lib/testdata/cloudflare-workers-cel.yaml @@ -1,8 +1,8 @@ bots: -- name: cloudflare-workers - expression: '"Cf-Worker" in headers' - action: DENY + - name: cloudflare-workers + expression: '"Cf-Worker" in headers' + action: DENY status_codes: CHALLENGE: 401 - DENY: 403 \ No newline at end of file + DENY: 403 diff --git a/lib/testdata/cloudflare-workers-header.yaml b/lib/testdata/cloudflare-workers-header.yaml index 4fa9671b..20306445 100644 --- a/lib/testdata/cloudflare-workers-header.yaml +++ b/lib/testdata/cloudflare-workers-header.yaml @@ -1,9 +1,9 @@ bots: -- name: cloudflare-workers - headers_regex: - CF-Worker: .* - action: DENY + - name: cloudflare-workers + headers_regex: + CF-Worker: .* + action: DENY status_codes: CHALLENGE: 401 - DENY: 403 \ No newline at end of file + DENY: 403 diff --git a/lib/testdata/hack-test.json b/lib/testdata/hack-test.json index 652dcd87..a173bb18 100644 --- a/lib/testdata/hack-test.json +++ b/lib/testdata/hack-test.json @@ -2,8 +2,6 @@ { "name": "ipv6-ula", "action": "ALLOW", - "remote_addresses": [ - "fc00::/7" - ] + "remote_addresses": ["fc00::/7"] } -] \ No newline at end of file +] diff --git a/lib/testdata/hack-test.yaml b/lib/testdata/hack-test.yaml index cd4d7d05..29263e96 100644 --- a/lib/testdata/hack-test.yaml +++ b/lib/testdata/hack-test.yaml @@ -1,3 +1,3 @@ - name: well-known path_regex: ^/.well-known/.*$ - action: ALLOW \ No newline at end of file + action: ALLOW diff --git a/lib/testdata/rule_change.yaml b/lib/testdata/rule_change.yaml index c4fe462d..737500e7 100644 --- a/lib/testdata/rule_change.yaml +++ b/lib/testdata/rule_change.yaml @@ -1,12 +1,12 @@ bots: -- name: old-rule - path_regex: ^/old$ - action: CHALLENGE + - name: old-rule + path_regex: ^/old$ + action: CHALLENGE -- name: new-rule - path_regex: ^/new$ - action: CHALLENGE + - name: new-rule + path_regex: ^/new$ + action: CHALLENGE status_codes: CHALLENGE: 401 - DENY: 403 \ No newline at end of file + DENY: 403 diff --git a/package-lock.json b/package-lock.json index bbcae50c..8a31b1ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,14 +13,19 @@ "preact": "^10.28.2" }, "devDependencies": { + "@commitlint/cli": "^20.4.1", + "@commitlint/config-conventional": "^20.4.1", + "baseline-browser-mapping": "^2.9.19", "cssnano": "^7.1.2", "cssnano-preset-advanced": "^7.0.10", "esbuild": "^0.27.2", + "husky": "^9.1.7", "playwright": "^1.52.0", "postcss-cli": "^11.0.1", "postcss-import": "^16.1.1", "postcss-import-url": "^7.2.0", - "postcss-url": "^10.1.3" + "postcss-url": "^10.1.3", + "prettier": "^3.8.1" } }, "node_modules/@aws-crypto/sha256-js": { @@ -61,6 +66,300 @@ "node": ">=18.0.0" } }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@commitlint/cli": { + "version": "20.4.1", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-20.4.1.tgz", + "integrity": "sha512-uuFKKpc7OtQM+6SRqT+a4kV818o1pS+uvv/gsRhyX7g4x495jg+Q7P0+O9VNGyLXBYP0syksS7gMRDJKcekr6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/format": "^20.4.0", + "@commitlint/lint": "^20.4.1", + "@commitlint/load": "^20.4.0", + "@commitlint/read": "^20.4.0", + "@commitlint/types": "^20.4.0", + "tinyexec": "^1.0.0", + "yargs": "^17.0.0" + }, + "bin": { + "commitlint": "cli.js" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/config-conventional": { + "version": "20.4.1", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-20.4.1.tgz", + "integrity": "sha512-0YUvIeBtpi86XriqrR+TCULVFiyYTIOEPjK7tTRMxjcBm1qlzb+kz7IF2WxL6Fq5DaundG8VO37BNgMkMTBwqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^20.4.0", + "conventional-changelog-conventionalcommits": "^9.1.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/config-validator": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-20.4.0.tgz", + "integrity": "sha512-zShmKTF+sqyNOfAE0vKcqnpvVpG0YX8F9G/ZIQHI2CoKyK+PSdladXMSns400aZ5/QZs+0fN75B//3Q5CHw++w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^20.4.0", + "ajv": "^8.11.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/ensure": { + "version": "20.4.1", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-20.4.1.tgz", + "integrity": "sha512-WLQqaFx1pBooiVvBrA1YfJNFqZF8wS/YGOtr5RzApDbV9tQ52qT5VkTsY65hFTnXhW8PcDfZLaknfJTmPejmlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^20.4.0", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.snakecase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "lodash.upperfirst": "^4.3.1" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/execute-rule": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-20.0.0.tgz", + "integrity": "sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/format": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-20.4.0.tgz", + "integrity": "sha512-i3ki3WR0rgolFVX6r64poBHXM1t8qlFel1G1eCBvVgntE3fCJitmzSvH5JD/KVJN/snz6TfaX2CLdON7+s4WVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^20.4.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/is-ignored": { + "version": "20.4.1", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-20.4.1.tgz", + "integrity": "sha512-In5EO4JR1lNsAv1oOBBO24V9ND1IqdAJDKZiEpdfjDl2HMasAcT7oA+5BKONv1pRoLG380DGPE2W2RIcUwdgLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^20.4.0", + "semver": "^7.6.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/is-ignored/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@commitlint/lint": { + "version": "20.4.1", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-20.4.1.tgz", + "integrity": "sha512-g94LrGl/c6UhuhDQqNqU232aslLEN2vzc7MPfQTHzwzM4GHNnEAwVWWnh0zX8S5YXecuLXDwbCsoGwmpAgPWKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/is-ignored": "^20.4.1", + "@commitlint/parse": "^20.4.1", + "@commitlint/rules": "^20.4.1", + "@commitlint/types": "^20.4.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/load": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-20.4.0.tgz", + "integrity": "sha512-Dauup/GfjwffBXRJUdlX/YRKfSVXsXZLnINXKz0VZkXdKDcaEILAi9oflHGbfydonJnJAbXEbF3nXPm9rm3G6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/config-validator": "^20.4.0", + "@commitlint/execute-rule": "^20.0.0", + "@commitlint/resolve-extends": "^20.4.0", + "@commitlint/types": "^20.4.0", + "cosmiconfig": "^9.0.0", + "cosmiconfig-typescript-loader": "^6.1.0", + "is-plain-obj": "^4.1.0", + "lodash.mergewith": "^4.6.2", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/message": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-20.4.0.tgz", + "integrity": "sha512-B5lGtvHgiLAIsK5nLINzVW0bN5hXv+EW35sKhYHE8F7V9Uz1fR4tx3wt7mobA5UNhZKUNgB/+ldVMQE6IHZRyA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/parse": { + "version": "20.4.1", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-20.4.1.tgz", + "integrity": "sha512-XNtZjeRcFuAfUnhYrCY02+mpxwY4OmnvD3ETbVPs25xJFFz1nRo/25nHj+5eM+zTeRFvWFwD4GXWU2JEtoK1/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^20.4.0", + "conventional-changelog-angular": "^8.1.0", + "conventional-commits-parser": "^6.2.1" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/read": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-20.4.0.tgz", + "integrity": "sha512-QfpFn6/I240ySEGv7YWqho4vxqtPpx40FS7kZZDjUJ+eHxu3azfhy7fFb5XzfTqVNp1hNoI3tEmiEPbDB44+cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/top-level": "^20.4.0", + "@commitlint/types": "^20.4.0", + "git-raw-commits": "^4.0.0", + "minimist": "^1.2.8", + "tinyexec": "^1.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/resolve-extends": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-20.4.0.tgz", + "integrity": "sha512-ay1KM8q0t+/OnlpqXJ+7gEFQNlUtSU5Gxr8GEwnVf2TPN3+ywc5DzL3JCxmpucqxfHBTFwfRMXxPRRnR5Ki20g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/config-validator": "^20.4.0", + "@commitlint/types": "^20.4.0", + "global-directory": "^4.0.1", + "import-meta-resolve": "^4.0.0", + "lodash.mergewith": "^4.6.2", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/rules": { + "version": "20.4.1", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-20.4.1.tgz", + "integrity": "sha512-WtqypKEPbQEuJwJS4aKs0OoJRBKz1HXPBC9wRtzVNH68FLhPWzxXlF09hpUXM9zdYTpm4vAdoTGkWiBgQ/vL0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/ensure": "^20.4.1", + "@commitlint/message": "^20.4.0", + "@commitlint/to-lines": "^20.0.0", + "@commitlint/types": "^20.4.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/to-lines": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-20.0.0.tgz", + "integrity": "sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/top-level": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-20.4.0.tgz", + "integrity": "sha512-NDzq8Q6jmFaIIBC/GG6n1OQEaHdmaAAYdrZRlMgW6glYWGZ+IeuXmiymDvQNXPc82mVxq2KiE3RVpcs+1OeDeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/types": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-20.4.0.tgz", + "integrity": "sha512-aO5l99BQJ0X34ft8b0h7QFkQlqxC6e7ZPVmBKz13xM9O8obDaM1Cld4sQlJDXXU/VFuUzQ30mVtHjVz74TuStw==", + "dev": true, + "license": "MIT", + "dependencies": { + "conventional-commits-parser": "^6.2.1", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=v18" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", @@ -553,6 +852,34 @@ "node": ">=14.0.0" } }, + "node_modules/@types/node": { + "version": "25.2.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.3.tgz", + "integrity": "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -593,6 +920,20 @@ "node": ">= 8" } }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true, + "license": "MIT" + }, "node_modules/autoprefixer": { "version": "10.4.21", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", @@ -639,9 +980,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.8.23", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.23.tgz", - "integrity": "sha512-616V5YX4bepJFzNyOfce5Fa8fDJMfoxzOIzDCZwaGL8MKVpFrXqfNUoIpRn9YMI5pXf/VKgzjB4htFMsFKKdiQ==", + "version": "2.9.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", + "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -726,6 +1067,16 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -837,6 +1188,17 @@ "node": ">=16" } }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -844,6 +1206,93 @@ "dev": true, "license": "MIT" }, + "node_modules/conventional-changelog-angular": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.1.0.tgz", + "integrity": "sha512-GGf2Nipn1RUCAktxuVauVr1e3r8QrLP/B0lEUsFktmGqc3ddbQkhoJZHJctVU829U1c6mTSWftrVOCHaL85Q3w==", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/conventional-changelog-conventionalcommits": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-9.1.0.tgz", + "integrity": "sha512-MnbEysR8wWa8dAEvbj5xcBgJKQlX/m0lhS8DsyAAWDHdfs2faDJxTgzRYlRYpXSe7UiKrIIlB4TrBKU9q9DgkA==", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/conventional-commits-parser": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.2.1.tgz", + "integrity": "sha512-20pyHgnO40rvfI0NGF/xiEoFMkXDtkF8FwHvk5BokoFoCuTQRI8vrNCNFWUOfuolKJMm1tPCHc8GgYEtr1XRNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "meow": "^13.0.0" + }, + "bin": { + "conventional-commits-parser": "dist/cli/index.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cosmiconfig-typescript-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.2.0.tgz", + "integrity": "sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "jiti": "^2.6.1" + }, + "engines": { + "node": ">=v18" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=9", + "typescript": ">=5" + } + }, "node_modules/css-declaration-sorter": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", @@ -1058,6 +1507,19 @@ "dev": true, "license": "MIT" }, + "node_modules/dargs": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz", + "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/dependency-graph": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-1.0.0.tgz", @@ -1127,6 +1589,19 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.244", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.244.tgz", @@ -1154,6 +1629,26 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/esbuild": { "version": "0.27.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", @@ -1206,6 +1701,30 @@ "node": ">=6" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -1283,6 +1802,37 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/git-raw-commits": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz", + "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dargs": "^8.0.0", + "meow": "^12.0.1", + "split2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.mjs" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/git-raw-commits/node_modules/meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -1296,6 +1846,22 @@ "node": ">= 6" } }, + "node_modules/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "4.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -1323,6 +1889,77 @@ "dev": true, "license": "ISC" }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -1395,6 +2032,29 @@ "node": ">=0.12.0" } }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-url": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", @@ -1402,6 +2062,50 @@ "dev": true, "license": "MIT" }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "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==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT" + }, "node_modules/jsonfile": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", @@ -1428,6 +2132,13 @@ "url": "https://github.com/sponsors/antonk52" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.assign": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", @@ -1435,6 +2146,20 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -1442,6 +2167,27 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.trim": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/lodash.trim/-/lodash.trim-4.5.1.tgz", @@ -1456,6 +2202,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "dev": true, + "license": "MIT" + }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -1479,6 +2232,19 @@ "dev": true, "license": "CC0-1.0" }, + "node_modules/meow": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mime": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", @@ -1505,6 +2271,16 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -1565,6 +2341,38 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -2348,6 +3156,22 @@ "url": "https://opencollective.com/preact" } }, + "node_modules/prettier": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", @@ -2408,6 +3232,16 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -2429,6 +3263,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/resolve-relative-url": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-relative-url/-/resolve-relative-url-1.0.0.tgz", @@ -2479,6 +3323,16 @@ "node": ">=0.10.0" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -2570,6 +3424,16 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", @@ -2637,6 +3501,29 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", diff --git a/package.json b/package.json index 08c4d14f..01292e4a 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "", "main": "index.js", "scripts": { - "test": "npm run assets && go test ./...", + "test": "npm run assets && SKIP_INTEGRATION=1 go test ./...", "test:integration": "npm run assets && go test -v ./internal/test", "test:integration:podman": "npm run assets && go test -v ./internal/test --playwright-runner=podman", "test:integration:docker": "npm run assets && go test -v ./internal/test --playwright-runner=docker", @@ -12,23 +12,58 @@ "build": "npm run assets && go build -o ./var/anubis ./cmd/anubis", "dev": "npm run assets && go run ./cmd/anubis --use-remote-address --target http://localhost:3000", "container": "npm run assets && go run ./cmd/containerbuild", - "package": "yeet", - "lint": "make lint" + "package": "go tool yeet", + "lint": "make lint", + "prepare": "husky && go mod download", + "format": "prettier -w . 2>&1 >/dev/null && go run goimports -w ." }, "author": "", "license": "ISC", "devDependencies": { + "@commitlint/cli": "^20.4.1", + "@commitlint/config-conventional": "^20.4.1", + "baseline-browser-mapping": "^2.9.19", "cssnano": "^7.1.2", "cssnano-preset-advanced": "^7.0.10", "esbuild": "^0.27.2", + "husky": "^9.1.7", "playwright": "^1.52.0", "postcss-cli": "^11.0.1", "postcss-import": "^16.1.1", "postcss-import-url": "^7.2.0", - "postcss-url": "^10.1.3" + "postcss-url": "^10.1.3", + "prettier": "^3.8.1" }, "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", "preact": "^10.28.2" + }, + "commitlint": { + "extends": [ + "@commitlint/config-conventional" + ], + "rules": { + "body-max-line-length": [ + 2, + "always", + 99999 + ], + "footer-max-line-length": [ + 2, + "always", + 99999 + ], + "signed-off-by": [ + 2, + "always" + ] + } + }, + "prettier": { + "singleQuote": false, + "tabWidth": 2, + "semi": true, + "trailingComma": "all", + "printWidth": 80 } -} \ No newline at end of file +} diff --git a/test/anubis_configs/aggressive_403.yaml b/test/anubis_configs/aggressive_403.yaml index facafd6f..ff966517 100644 --- a/test/anubis_configs/aggressive_403.yaml +++ b/test/anubis_configs/aggressive_403.yaml @@ -1,12 +1,12 @@ bots: -- name: deny - user_agent_regex: DENY - action: DENY + - name: deny + user_agent_regex: DENY + action: DENY -- name: challenge - user_agent_regex: CHALLENGE - action: CHALLENGE + - name: challenge + user_agent_regex: CHALLENGE + action: CHALLENGE status_codes: CHALLENGE: 401 - DENY: 403 \ No newline at end of file + DENY: 403 diff --git a/test/double_slash/test.mjs b/test/double_slash/test.mjs index 7ae9c5a8..15a54eb9 100644 --- a/test/double_slash/test.mjs +++ b/test/double_slash/test.mjs @@ -3,13 +3,13 @@ import { createInterface } from "readline"; async function getPage(path) { return fetch(`http://localhost:8923${path}`) - .then(resp => { + .then((resp) => { if (resp.status !== 200) { throw new Error(`wanted status 200, got status: ${resp.status}`); } return resp; }) - .then(resp => resp.text()); + .then((resp) => resp.text()); } (async () => { @@ -42,4 +42,4 @@ async function getPage(path) { } process.exit(failed ? 1 : 0); -})(); \ No newline at end of file +})(); diff --git a/test/forced-language/test.mjs b/test/forced-language/test.mjs index e64237ef..7fab657e 100644 --- a/test/forced-language/test.mjs +++ b/test/forced-language/test.mjs @@ -3,25 +3,25 @@ async function getChallengePage() { headers: { "Accept-Language": "en", "User-Agent": "CHALLENGE", - } + }, }) - .then(resp => { + .then((resp) => { if (resp.status !== 200) { throw new Error(`wanted status 200, got status: ${resp.status}`); } return resp; }) - .then(resp => resp.text()); + .then((resp) => resp.text()); } (async () => { const page = await getChallengePage(); if (!page.includes(``)) { - console.log(page) + console.log(page); throw new Error("force language smoke test failed"); } console.log("FORCED_LANGUAGE=de caused a page to be rendered in german"); process.exit(0); -})(); \ No newline at end of file +})(); diff --git a/test/i18n/test.mjs b/test/i18n/test.mjs index 64b32703..ba48ea28 100644 --- a/test/i18n/test.mjs +++ b/test/i18n/test.mjs @@ -1,12 +1,14 @@ async function fetchLanguages() { - return fetch("http://localhost:8923/.within.website/x/cmd/anubis/static/locales/manifest.json") - .then(resp => { + return fetch( + "http://localhost:8923/.within.website/x/cmd/anubis/static/locales/manifest.json", + ) + .then((resp) => { if (resp.status !== 200) { throw new Error(`wanted status 200, got status: ${resp.status}`); } return resp; }) - .then(resp => resp.json()); + .then((resp) => resp.json()); } async function getChallengePage(lang) { @@ -14,15 +16,15 @@ async function getChallengePage(lang) { headers: { "Accept-Language": lang, "User-Agent": "CHALLENGE", - } + }, }) - .then(resp => { + .then((resp) => { if (resp.status !== 200) { throw new Error(`wanted status 200, got status: ${resp.status}`); } return resp; }) - .then(resp => resp.text()); + .then((resp) => resp.text()); } (async () => { @@ -42,7 +44,7 @@ async function getChallengePage(lang) { console.log(`getting for ${lang}`); const page = await getChallengePage(lang); - resultSheet[lang] = page.includes(``) + resultSheet[lang] = page.includes(``); } for (const [lang, result] of Object.entries(resultSheet)) { @@ -59,4 +61,4 @@ async function getChallengePage(lang) { } process.exit(0); -})(); \ No newline at end of file +})(); diff --git a/test/k8s/cert-manager/selfsigned-issuer.yaml b/test/k8s/cert-manager/selfsigned-issuer.yaml index 07d2b7bc..8120e82a 100644 --- a/test/k8s/cert-manager/selfsigned-issuer.yaml +++ b/test/k8s/cert-manager/selfsigned-issuer.yaml @@ -3,4 +3,4 @@ kind: ClusterIssuer metadata: name: selfsigned spec: - selfSigned: {} \ No newline at end of file + selfSigned: {} diff --git a/test/k8s/deps/cert-manager.yaml b/test/k8s/deps/cert-manager.yaml index f3e17fae..1d3fda13 100644 --- a/test/k8s/deps/cert-manager.yaml +++ b/test/k8s/deps/cert-manager.yaml @@ -10,4 +10,4 @@ spec: createNamespace: true set: installCRDs: "true" - "prometheus.enabled": "false" \ No newline at end of file + "prometheus.enabled": "false" diff --git a/test/log-file/test.mjs b/test/log-file/test.mjs index 8b036cd3..f9db6454 100644 --- a/test/log-file/test.mjs +++ b/test/log-file/test.mjs @@ -3,16 +3,16 @@ import { statSync } from "fs"; async function getPage(path) { return fetch(`http://localhost:8923${path}`, { headers: { - 'User-Agent': 'CHALLENGE' - } + "User-Agent": "CHALLENGE", + }, }) - .then(resp => { + .then((resp) => { if (resp.status !== 200) { throw new Error(`wanted status 200, got status: ${resp.status}`); } return resp; }) - .then(resp => resp.text()); + .then((resp) => resp.text()); } async function getFileSize(filePath) { @@ -63,7 +63,9 @@ async function getFileSize(filePath) { // Verify that log file size increased if (finalSize <= initialSize) { - console.error("ERROR: Log file size did not increase after making requests!"); + console.error( + "ERROR: Log file size did not increase after making requests!", + ); failed = true; } @@ -79,10 +81,14 @@ async function getFileSize(filePath) { console.log(`Successful requests: ${successCount}/${requests.length}`); if (failed) { - console.error("Test failed: Some requests failed or log file size did not increase"); + console.error( + "Test failed: Some requests failed or log file size did not increase", + ); process.exit(1); } else { - console.log("Test passed: All requests succeeded and log file size increased"); + console.log( + "Test passed: All requests succeeded and log file size increased", + ); process.exit(0); } -})(); \ No newline at end of file +})(); diff --git a/test/nginx/conf/nginx/conf-anubis.inc b/test/nginx/conf/nginx/conf-anubis.inc index 6e5083ae..1535ec91 100644 --- a/test/nginx/conf/nginx/conf-anubis.inc +++ b/test/nginx/conf/nginx/conf-anubis.inc @@ -1,8 +1,7 @@ # /etc/nginx/conf-anubis.inc - # Forward to anubis location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://anubis; -} \ No newline at end of file +} diff --git a/test/robots_txt/test.mjs b/test/robots_txt/test.mjs index ce62b9f7..faa6d89d 100644 --- a/test/robots_txt/test.mjs +++ b/test/robots_txt/test.mjs @@ -3,25 +3,25 @@ async function getRobotsTxt() { headers: { "Accept-Language": "en", "User-Agent": "Mozilla/5.0", - } + }, }) - .then(resp => { + .then((resp) => { if (resp.status !== 200) { throw new Error(`wanted status 200, got status: ${resp.status}`); } return resp; }) - .then(resp => resp.text()); + .then((resp) => resp.text()); } (async () => { const page = await getRobotsTxt(); if (page.includes(``)) { - console.log(page) + console.log(page); throw new Error("serve robots.txt smoke test failed"); } console.log("serve-robots-txt serves robots.txt"); process.exit(0); -})(); \ No newline at end of file +})(); diff --git a/test/shared/www/index.html b/test/shared/www/index.html index 8c55c8cb..f259424f 100644 --- a/test/shared/www/index.html +++ b/test/shared/www/index.html @@ -1,9 +1,9 @@ - + Anubis works! - - + +
@@ -11,7 +11,10 @@

If you see this, everything has gone according to keikaku.

- +
- \ No newline at end of file + diff --git a/test/unix-socket-xff/test.mjs b/test/unix-socket-xff/test.mjs index 8b8479c0..5c85dba4 100644 --- a/test/unix-socket-xff/test.mjs +++ b/test/unix-socket-xff/test.mjs @@ -1,19 +1,20 @@ async function testWithUserAgent(userAgent) { - const statusCode = - await fetch("https://relayd.local.cetacean.club:3004/reqmeta", { + const statusCode = await fetch( + "https://relayd.local.cetacean.club:3004/reqmeta", + { headers: { "User-Agent": userAgent, - } - }) - .then(resp => resp.status); + }, + }, + ).then((resp) => resp.status); return statusCode; } const codes = { allow: await testWithUserAgent("ALLOW"), challenge: await testWithUserAgent("CHALLENGE"), - deny: await testWithUserAgent("DENY") -} + deny: await testWithUserAgent("DENY"), +}; const expected = { allow: 200, @@ -26,5 +27,7 @@ console.log("CHALLENGE:", codes.challenge); console.log("DENY: ", codes.deny); if (JSON.stringify(codes) !== JSON.stringify(expected)) { - throw new Error(`wanted ${JSON.stringify(expected)}, got: ${JSON.stringify(codes)}`); -} \ No newline at end of file + throw new Error( + `wanted ${JSON.stringify(expected)}, got: ${JSON.stringify(codes)}`, + ); +} diff --git a/web/js/algorithms/fast.ts b/web/js/algorithms/fast.ts index 6330da56..82a9a778 100644 --- a/web/js/algorithms/fast.ts +++ b/web/js/algorithms/fast.ts @@ -6,7 +6,9 @@ interface ProcessOptions { } const getHardwareConcurrency = () => - navigator.hardwareConcurrency !== undefined ? navigator.hardwareConcurrency : 1; + navigator.hardwareConcurrency !== undefined + ? navigator.hardwareConcurrency + : 1; export default function process( options: ProcessOptions, @@ -25,7 +27,10 @@ export default function process( workerMethod = "webcrypto"; } - if (navigator.userAgent.includes("Firefox") || navigator.userAgent.includes("Goanna")) { + if ( + navigator.userAgent.includes("Firefox") || + navigator.userAgent.includes("Goanna") + ) { console.log("Firefox detected, using pure-JS fallback"); workerMethod = "purejs"; } diff --git a/web/js/algorithms/index.ts b/web/js/algorithms/index.ts index 5b571837..2781aef0 100644 --- a/web/js/algorithms/index.ts +++ b/web/js/algorithms/index.ts @@ -3,4 +3,4 @@ import fast from "./fast"; export default { fast: fast, slow: fast, // XXX(Xe): slow is deprecated, but keep this around in case anything goes bad -} \ No newline at end of file +}; diff --git a/web/js/bench.ts b/web/js/bench.ts index 719b1675..1dd7805c 100644 --- a/web/js/bench.ts +++ b/web/js/bench.ts @@ -2,13 +2,27 @@ import algorithms from "./algorithms"; const defaultDifficulty = 4; -const status: HTMLParagraphElement = document.getElementById("status") as HTMLParagraphElement; -const difficultyInput: HTMLInputElement = document.getElementById("difficulty-input") as HTMLInputElement; -const algorithmSelect: HTMLSelectElement = document.getElementById("algorithm-select") as HTMLSelectElement; -const compareSelect: HTMLSelectElement = document.getElementById("compare-select") as HTMLSelectElement; -const header: HTMLTableRowElement = document.getElementById("table-header") as HTMLTableRowElement; -const headerCompare: HTMLTableSectionElement = document.getElementById("table-header-compare") as HTMLTableSectionElement; -const results: HTMLTableRowElement = document.getElementById("results") as HTMLTableRowElement; +const status: HTMLParagraphElement = document.getElementById( + "status", +) as HTMLParagraphElement; +const difficultyInput: HTMLInputElement = document.getElementById( + "difficulty-input", +) as HTMLInputElement; +const algorithmSelect: HTMLSelectElement = document.getElementById( + "algorithm-select", +) as HTMLSelectElement; +const compareSelect: HTMLSelectElement = document.getElementById( + "compare-select", +) as HTMLSelectElement; +const header: HTMLTableRowElement = document.getElementById( + "table-header", +) as HTMLTableRowElement; +const headerCompare: HTMLTableSectionElement = document.getElementById( + "table-header-compare", +) as HTMLTableSectionElement; +const results: HTMLTableRowElement = document.getElementById( + "results", +) as HTMLTableRowElement; const setupControls = () => { if (defaultDifficulty == null) { @@ -41,7 +55,12 @@ const benchmarkTrial = async (stats, difficulty, algorithm, signal) => { .join(""); const t0 = performance.now(); - const { hash, nonce } = await process({ basePrefix: "/", version: "devel" }, challenge, Number(difficulty), signal); + const { hash, nonce } = await process( + { basePrefix: "/", version: "devel" }, + challenge, + Number(difficulty), + signal, + ); const t1 = performance.now(); console.log({ hash, nonce }); diff --git a/web/js/main.ts b/web/js/main.ts index fbedb3a6..b07d52d9 100644 --- a/web/js/main.ts +++ b/web/js/main.ts @@ -29,22 +29,25 @@ const getAvailableLanguages = async () => { } try { - const response = await fetch(`${basePrefix}/.within.website/x/cmd/anubis/static/locales/manifest.json`); + const response = await fetch( + `${basePrefix}/.within.website/x/cmd/anubis/static/locales/manifest.json`, + ); if (response.ok) { const manifest = await response.json(); - return manifest.supportedLanguages || ['en']; + return manifest.supportedLanguages || ["en"]; } } catch (error) { - console.warn('Failed to load language manifest, falling back to default languages'); + console.warn( + "Failed to load language manifest, falling back to default languages", + ); } // Fallback to default languages if manifest loading fails - return ['en']; + return ["en"]; }; // Use the browser language from the HTML lang attribute which is set by the server settings or request headers -const getBrowserLanguage = async () => - document.documentElement.lang; +const getBrowserLanguage = async () => document.documentElement.lang; // Load translations from JSON files const loadTranslations = async (lang) => { @@ -54,12 +57,16 @@ const loadTranslations = async (lang) => { } try { - const response = await fetch(`${basePrefix}/.within.website/x/cmd/anubis/static/locales/${lang}.json`); + const response = await fetch( + `${basePrefix}/.within.website/x/cmd/anubis/static/locales/${lang}.json`, + ); return await response.json(); } catch (error) { - console.warn(`Failed to load translations for ${lang}, falling back to English`); - if (lang !== 'en') { - return await loadTranslations('en'); + console.warn( + `Failed to load translations for ${lang}, falling back to English`, + ); + if (lang !== "en") { + return await loadTranslations("en"); } throw error; } @@ -72,10 +79,10 @@ const getRedirectUrl = () => { } if (publicUrl && window.location.href.startsWith(publicUrl)) { const urlParams = new URLSearchParams(window.location.search); - return urlParams.get('redir'); + return urlParams.get("redir"); } return window.location.href; -} +}; let translations = {}; let currentLang; @@ -95,20 +102,28 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key; const dependencies = [ { name: "Web Workers", - msg: t('web_workers_error'), + msg: t("web_workers_error"), value: window.Worker, }, { name: "Cookies", - msg: t('cookies_error'), + msg: t("cookies_error"), value: navigator.cookieEnabled, }, ]; - const status: HTMLParagraphElement = document.getElementById("status") as HTMLParagraphElement; - const image: HTMLImageElement = document.getElementById("image") as HTMLImageElement; - const title: HTMLHeadingElement = document.getElementById("title") as HTMLHeadingElement; - const progress: HTMLDivElement = document.getElementById("progress") as HTMLDivElement; + const status: HTMLParagraphElement = document.getElementById( + "status", + ) as HTMLParagraphElement; + const image: HTMLImageElement = document.getElementById( + "image", + ) as HTMLImageElement; + const title: HTMLHeadingElement = document.getElementById( + "title", + ) as HTMLHeadingElement; + const progress: HTMLDivElement = document.getElementById( + "progress", + ) as HTMLDivElement; const anubisVersion = j("anubis_version"); const basePrefix = j("anubis_base_prefix"); @@ -130,12 +145,12 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key; progress.style.display = "none"; }; - status.innerHTML = t('calculating'); + status.innerHTML = t("calculating"); for (const { value, name, msg } of dependencies) { if (!value) { ohNoes({ - titleMsg: `${t('missing_feature')} ${name}`, + titleMsg: `${t("missing_feature")} ${name}`, statusMsg: msg, imageSrc: imageURL("reject", anubisVersion, basePrefix), }); @@ -148,20 +163,20 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key; const process = algorithms[rules.algorithm]; if (!process) { ohNoes({ - titleMsg: t('challenge_error'), - statusMsg: t('challenge_error_msg'), + titleMsg: t("challenge_error"), + statusMsg: t("challenge_error_msg"), imageSrc: imageURL("reject", anubisVersion, basePrefix), }); return; } - status.innerHTML = `${t('calculating_difficulty')} ${rules.difficulty}, `; + status.innerHTML = `${t("calculating_difficulty")} ${rules.difficulty}, `; progress.style.display = "inline-block"; // the whole text, including "Speed:", as a single node, because some browsers // (Firefox mobile) present screen readers with each node as a separate piece // of text. - const rateText = document.createTextNode(`${t('speed')} 0kH/s`); + const rateText = document.createTextNode(`${t("speed")} 0kH/s`); status.appendChild(rateText); let lastSpeedUpdate = 0; @@ -180,7 +195,7 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key; // only update the speed every second so it's less visually distracting if (delta - lastSpeedUpdate > 1000) { lastSpeedUpdate = delta; - rateText.data = `${t('speed')} ${(iters / delta).toFixed(3)}kH/s`; + rateText.data = `${t("speed")} ${(iters / delta).toFixed(3)}kH/s`; } // the probability of still being on the page is (1 - likelihood) ^ iters. // by definition, half of the time the progress bar only gets to half, so @@ -192,13 +207,14 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key; const distance = (1 - Math.pow(probability, 2)) * 100; progress["aria-valuenow"] = distance; if (progress.firstElementChild !== null) { - (progress.firstElementChild as HTMLElement).style.width = `${distance}%`; + (progress.firstElementChild as HTMLElement).style.width = + `${distance}%`; } if (probability < 0.1 && !showingApology) { status.append( document.createElement("br"), - document.createTextNode(t('verification_longer')), + document.createTextNode(t("verification_longer")), ); showingApology = true; } @@ -208,7 +224,9 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key; console.log({ hash, nonce }); if (userReadDetails) { - const container: HTMLDivElement = document.getElementById("progress") as HTMLDivElement; + const container: HTMLDivElement = document.getElementById( + "progress", + ) as HTMLDivElement; // Style progress bar as a continue button container.style.display = "flex"; @@ -224,7 +242,7 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key; container.style.outlineOffset = "2px"; container.style.width = "min(20rem, 90%)"; container.style.margin = "1rem auto 2rem"; - container.innerHTML = t('finished_reading'); + container.innerHTML = t("finished_reading"); function onDetailsExpand() { const redir = getRedirectUrl(); @@ -255,8 +273,8 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key; } } catch (err) { ohNoes({ - titleMsg: t('calculation_error'), - statusMsg: `${t('calculation_error_msg')} ${err.message}`, + titleMsg: t("calculation_error"), + statusMsg: `${t("calculation_error_msg")} ${err.message}`, imageSrc: imageURL("reject", anubisVersion, basePrefix), }); } diff --git a/web/js/worker/sha256-purejs.ts b/web/js/worker/sha256-purejs.ts index 69060615..52ee1cda 100644 --- a/web/js/worker/sha256-purejs.ts +++ b/web/js/worker/sha256-purejs.ts @@ -1,4 +1,4 @@ -import { Sha256 } from '@aws-crypto/sha256-js'; +import { Sha256 } from "@aws-crypto/sha256-js"; const calculateSHA256 = (text) => { const hash = new Sha256(); @@ -12,7 +12,7 @@ function toHexString(arr: Uint8Array): string { .join(""); } -addEventListener('message', async ({ data: eventData }) => { +addEventListener("message", async ({ data: eventData }) => { const { data, difficulty, threads } = eventData; let nonce = eventData.nonce; const isMainThread = nonce === 0; @@ -21,7 +21,7 @@ addEventListener('message', async ({ data: eventData }) => { const requiredZeroBytes = Math.floor(difficulty / 2); const isDifficultyOdd = difficulty % 2 !== 0; - for (; ;) { + for (;;) { const hashBuffer = await calculateSHA256(data + nonce); const hashArray = new Uint8Array(hashBuffer); @@ -34,7 +34,7 @@ addEventListener('message', async ({ data: eventData }) => { } if (isValid && isDifficultyOdd) { - if ((hashArray[requiredZeroBytes] >> 4) !== 0) { + if (hashArray[requiredZeroBytes] >> 4 !== 0) { isValid = false; } } @@ -55,7 +55,7 @@ addEventListener('message', async ({ data: eventData }) => { /* Truncate the decimal portion of the nonce. This is a bit of an evil bit * hack, but it works reliably enough. The core of why this works is: - * + * * > 13.4 % 1 !== 0 * true * > 13 % 1 !== 0 @@ -70,4 +70,4 @@ addEventListener('message', async ({ data: eventData }) => { postMessage(nonce); } } -}); \ No newline at end of file +}); diff --git a/web/js/worker/sha256-webcrypto.ts b/web/js/worker/sha256-webcrypto.ts index c83f4665..d3cdeca2 100644 --- a/web/js/worker/sha256-webcrypto.ts +++ b/web/js/worker/sha256-webcrypto.ts @@ -6,7 +6,10 @@ const calculateSHA256 = async (input: string) => { }; const toHexString = (byteArray: Uint8Array) => { - return byteArray.reduce((str, byte) => str + byte.toString(16).padStart(2, "0"), ""); + return byteArray.reduce( + (str, byte) => str + byte.toString(16).padStart(2, "0"), + "", + ); }; addEventListener("message", async ({ data: eventData }) => { @@ -18,7 +21,7 @@ addEventListener("message", async ({ data: eventData }) => { const requiredZeroBytes = Math.floor(difficulty / 2); const isDifficultyOdd = difficulty % 2 !== 0; - for (; ;) { + for (;;) { const hashBuffer = await calculateSHA256(data + nonce); const hashArray = new Uint8Array(hashBuffer); @@ -31,7 +34,7 @@ addEventListener("message", async ({ data: eventData }) => { } if (isValid && isDifficultyOdd) { - if ((hashArray[requiredZeroBytes] >> 4) !== 0) { + if (hashArray[requiredZeroBytes] >> 4 !== 0) { isValid = false; } } @@ -52,7 +55,7 @@ addEventListener("message", async ({ data: eventData }) => { /* Truncate the decimal portion of the nonce. This is a bit of an evil bit * hack, but it works reliably enough. The core of why this works is: - * + * * > 13.4 % 1 !== 0 * true * > 13 % 1 !== 0 @@ -67,4 +70,4 @@ addEventListener("message", async ({ data: eventData }) => { postMessage(nonce); } } -}); \ No newline at end of file +}); diff --git a/xess/postcss.config.js b/xess/postcss.config.js index 7084661d..13c708c6 100644 --- a/xess/postcss.config.js +++ b/xess/postcss.config.js @@ -5,4 +5,4 @@ module.exports = { }), require("postcss-url")({ url: "inline" }), ], -}; \ No newline at end of file +}; diff --git a/yeetfile.js b/yeetfile.js index 47749aff..caab0a5e 100644 --- a/yeetfile.js +++ b/yeetfile.js @@ -1,43 +1,41 @@ $`npm run assets`; -[ - "amd64", - "arm64", - "ppc64le", - "riscv64", -].forEach(goarch => { - [deb, rpm, tarball].forEach(method => method.build({ - name: "anubis", - description: "Anubis weighs the souls of incoming HTTP requests and uses a sha256 proof-of-work challenge in order to protect upstream resources from scraper bots.", - homepage: "https://anubis.techaro.lol", - license: "MIT", - goarch, +["amd64", "arm64", "ppc64le", "riscv64"].forEach((goarch) => { + [deb, rpm, tarball].forEach((method) => + method.build({ + name: "anubis", + description: + "Anubis weighs the souls of incoming HTTP requests and uses a sha256 proof-of-work challenge in order to protect upstream resources from scraper bots.", + homepage: "https://anubis.techaro.lol", + license: "MIT", + goarch, - documentation: { - "./README.md": "README.md", - "./LICENSE": "LICENSE", - "./data/botPolicies.yaml": "botPolicies.yaml", - }, + documentation: { + "./README.md": "README.md", + "./LICENSE": "LICENSE", + "./data/botPolicies.yaml": "botPolicies.yaml", + }, - build: ({ bin, etc, systemd, doc }) => { - $`go build -o ${bin}/anubis -ldflags '-s -w -extldflags "-static" -X "github.com/TecharoHQ/anubis.Version=${git.tag()}"' ./cmd/anubis`; - $`go build -o ${bin}/anubis-robots2policy -ldflags '-s -w -extldflags "-static" -X "github.com/TecharoHQ/anubis.Version=${git.tag()}"' ./cmd/robots2policy`; + build: ({ bin, etc, systemd, doc }) => { + $`go build -o ${bin}/anubis -ldflags '-s -w -extldflags "-static" -X "github.com/TecharoHQ/anubis.Version=${git.tag()}"' ./cmd/anubis`; + $`go build -o ${bin}/anubis-robots2policy -ldflags '-s -w -extldflags "-static" -X "github.com/TecharoHQ/anubis.Version=${git.tag()}"' ./cmd/robots2policy`; - file.install("./run/anubis@.service", `${systemd}/anubis@.service`); - file.install("./run/default.env", `${etc}/default.env`); + file.install("./run/anubis@.service", `${systemd}/anubis@.service`); + file.install("./run/default.env", `${etc}/default.env`); - $`mkdir -p ${doc}/docs` - $`cp -a docs/docs ${doc}`; - $`find ${doc} -name _category_.json -delete`; - $`mkdir -p ${doc}/data`; - $`cp -a data/apps ${doc}/data/apps`; - $`cp -a data/bots ${doc}/data/bots`; - $`cp -a data/clients ${doc}/data/clients`; - $`cp -a data/common ${doc}/data/common`; - $`cp -a data/crawlers ${doc}/data/crawlers`; - $`cp -a data/meta ${doc}/data/meta`; - }, - })); + $`mkdir -p ${doc}/docs`; + $`cp -a docs/docs ${doc}`; + $`find ${doc} -name _category_.json -delete`; + $`mkdir -p ${doc}/data`; + $`cp -a data/apps ${doc}/data/apps`; + $`cp -a data/bots ${doc}/data/bots`; + $`cp -a data/clients ${doc}/data/clients`; + $`cp -a data/common ${doc}/data/common`; + $`cp -a data/crawlers ${doc}/data/crawlers`; + $`cp -a data/meta ${doc}/data/meta`; + }, + }), + ); }); // NOTE(Xe): Fixes #217. This is a "half baked" tarball that includes the harder @@ -46,41 +44,41 @@ $`npm run assets`; // model into the bazaar of round holes that various modern languages use. Needless // to say, this makes adoption easier. tarball.build({ - name: "anubis-src-vendor", - license: "MIT", - // XXX(Xe): This is needed otherwise go will be very sad. - platform: yeet.goos, - goarch: yeet.goarch, + name: "anubis-src-vendor", + license: "MIT", + // XXX(Xe): This is needed otherwise go will be very sad. + platform: yeet.goos, + goarch: yeet.goarch, - build: ({ out }) => { - // prepare clean checkout in $out - $`git archive --format=tar HEAD | tar xC ${out}`; - // vendor Go dependencies - $`cd ${out} && go mod vendor`; - // write VERSION file - $`echo ${git.tag()} > ${out}/VERSION`; - }, + build: ({ out }) => { + // prepare clean checkout in $out + $`git archive --format=tar HEAD | tar xC ${out}`; + // vendor Go dependencies + $`cd ${out} && go mod vendor`; + // write VERSION file + $`echo ${git.tag()} > ${out}/VERSION`; + }, - mkFilename: ({ name, version }) => `${name}-${version}`, + mkFilename: ({ name, version }) => `${name}-${version}`, }); tarball.build({ - name: "anubis-src-vendor-npm", - license: "MIT", - // XXX(Xe): This is needed otherwise go will be very sad. - platform: yeet.goos, - goarch: yeet.goarch, + name: "anubis-src-vendor-npm", + license: "MIT", + // XXX(Xe): This is needed otherwise go will be very sad. + platform: yeet.goos, + goarch: yeet.goarch, - build: ({ out }) => { - // prepare clean checkout in $out - $`git archive --format=tar HEAD | tar xC ${out}`; - // vendor Go dependencies - $`cd ${out} && go mod vendor`; - // build NPM-bound dependencies - $`cd ${out} && npm ci && npm run assets && rm -rf node_modules` - // write VERSION file - $`echo ${git.tag()} > ${out}/VERSION`; - }, + build: ({ out }) => { + // prepare clean checkout in $out + $`git archive --format=tar HEAD | tar xC ${out}`; + // vendor Go dependencies + $`cd ${out} && go mod vendor`; + // build NPM-bound dependencies + $`cd ${out} && npm ci && npm run assets && rm -rf node_modules`; + // write VERSION file + $`echo ${git.tag()} > ${out}/VERSION`; + }, - mkFilename: ({ name, version }) => `${name}-${version}`, -}); \ No newline at end of file + mkFilename: ({ name, version }) => `${name}-${version}`, +});